Changeset 3d26610 for src/Parser/parser.yy
- Timestamp:
- May 31, 2018, 4:05:01 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, with_gc
- Children:
- b368dd8
- Parents:
- bd946e4
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/parser.yy
rbd946e4 r3d26610 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 30 20:29:03201813 // Update Count : 34 3212 // Last Modified On : Thu May 31 15:11:40 2018 13 // Update Count : 3444 14 14 // 15 15 … … 265 265 %type<sn> statement labeled_statement compound_statement 266 266 %type<sn> statement_decl statement_decl_list statement_list_nodecl 267 %type<sn> selection_statement 267 %type<sn> selection_statement if_statement 268 268 %type<sn> switch_clause_list_opt switch_clause_list 269 269 %type<en> case_value … … 404 404 //************************* Namespace Management ******************************** 405 405 406 // The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal symbols 407 // "identifier", "TYPEDEFname", and "TYPEGENname" that are lexically identical. While it is possible to write a purely 408 // context-free grammar, such a grammar would obscure the relationship between syntactic and semantic constructs. 409 // Hence, this grammar uses the ANSI style. 410 // 411 // Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, those 412 // introduced through "forall" qualifiers), and by introducing "type generators" -- parameterized types. This latter 413 // type name creates a third class of identifiers that must be distinguished by the scanner. 414 // 415 // Since the scanner cannot distinguish among the different classes of identifiers without some context information, it 416 // accesses a data structure (TypedefTable) to allow classification of an identifier that it has just read. Semantic 417 // actions during the parser update this data structure when the class of identifiers change. 418 // 419 // Because the Cforall language is block-scoped, an identifier can change its class in a local scope; it must revert to 420 // its original class at the end of the block. Since type names can be local to a particular declaration, each 421 // declaration is itself a scope. This requires distinguishing between type names that are local to the current 422 // declaration scope and those that persist past the end of the declaration (i.e., names defined in "typedef" or "otype" 423 // declarations). 424 // 425 // The non-terminals "push" and "pop" denote the opening and closing of scopes. Every push must have a matching pop, 426 // although it is regrettable the matching pairs do not always occur within the same rule. These non-terminals may 427 // appear in more contexts than strictly necessary from a semantic point of view. 406 // The C grammar is not context free because it relies on the distinct terminal symbols "identifier" and "TYPEDEFname", 407 // which are lexically identical. 408 // 409 // typedef int foo; // identifier foo must now be scanned as TYPEDEFname 410 // foo f; // to allow it to appear in this context 411 // 412 // While it may be possible to write a purely context-free grammar, such a grammar would obscure the relationship 413 // between syntactic and semantic constructs. Cforall compounds this problem by introducing type names local to the 414 // scope of a declaration (for instance, those introduced through "forall" qualifiers), and by introducing "type 415 // generators" -- parameterized types. This latter type name creates a third class of identifiers, "TYPEGENname", which 416 // must be distinguished by the lexical scanner. 417 // 418 // Since the scanner cannot distinguish among the different classes of identifiers without some context information, 419 // there is a type table (typedefTable), which holds type names and identifiers that override type names, for each named 420 // scope. During parsing, semantic actions update the type table by adding new identifiers in the current scope. For 421 // each context that introduces a name scope, a new level is created in the type table and that level is popped on 422 // exiting the scope. Since type names can be local to a particular declaration, each declaration is itself a scope. 423 // This requires distinguishing between type names that are local to the current declaration scope and those that 424 // persist past the end of the declaration (i.e., names defined in "typedef" or "otype" declarations). 425 // 426 // The non-terminals "push" and "pop" denote the opening and closing of named scopes. Every push has a matching pop in 427 // the production rule. There are multiple lists of declarations, where each declaration is a named scope, so pop/push 428 // around the list separator. 429 // 430 // int f( forall(T) T (*f1) T , forall( S ) S (*f2)( S ) ); 431 // push pop push pop 428 432 429 433 push: … … 952 956 953 957 selection_statement: 954 IF '(' push if_control_expression ')' statement pop %prec THEN 955 // explicitly deal with the shift/reduce conflict on if/else 956 { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); } 957 | IF '(' push if_control_expression ')' statement ELSE statement pop 958 { $$ = new StatementNode( build_if( $4, $6, $8 ) ); } 958 // pop causes a S/R conflict without separating the IF statement into a non-terminal even after resolving 959 // the inherent S/R conflict with THEN/ELSE. 960 push if_statement pop 961 { $$ = $2; } 959 962 | SWITCH '(' comma_expression ')' case_clause 960 963 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); } … … 977 980 } 978 981 ; 982 983 if_statement: 984 IF '(' if_control_expression ')' statement %prec THEN 985 // explicitly deal with the shift/reduce conflict on if/else 986 { $$ = new StatementNode( build_if( $3, $5, nullptr ) ); } 987 | IF '(' if_control_expression ')' statement ELSE statement 988 { $$ = new StatementNode( build_if( $3, $5, $7 ) ); } 989 ; 990 979 991 980 992 if_control_expression: … … 1172 1184 1173 1185 handler_clause: 1174 handler_key '(' push pushexception_declaration pop handler_predicate_opt ')' compound_statement pop1175 { $$ = new StatementNode( build_catch( $1, $ 5, $7, $9) ); }1176 | handler_clause handler_key '(' push pushexception_declaration pop handler_predicate_opt ')' compound_statement pop1177 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $ 6, $8, $10) ) ); }1186 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop 1187 { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); } 1188 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop 1189 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); } 1178 1190 ; 1179 1191
Note: See TracChangeset
for help on using the changeset viewer.