Changeset 3d26610
- Timestamp:
- May 31, 2018, 4:05:01 PM (5 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
- Location:
- src
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/TypedefTable.cc
rbd946e4 r3d26610 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 22 08:40:01201813 // Update Count : 1 2112 // Last Modified On : Wed May 30 18:04:38 2018 13 // Update Count : 148 14 14 // 15 15 … … 20 20 #if 0 21 21 #include <iostream> 22 #define debugPrint( x ) cerr << x22 #define debugPrint( code ) code 23 23 #else 24 #define debugPrint( x)24 #define debugPrint( code ) 25 25 #endif 26 26 … … 29 29 TypedefTable::~TypedefTable() { 30 30 if ( ! SemanticErrorThrow && kindTable.currentScope() != 0 ) { 31 //std::cerr << "scope failure " << kindTable.currentScope() << endl;31 std::cerr << "scope failure " << kindTable.currentScope() << endl; 32 32 } // if 33 33 } // TypedefTable::~TypedefTable … … 54 54 void TypedefTable::makeTypedef( const string & name ) { 55 55 if ( ! typedefTable.exists( name ) ) { 56 typedefTable.addToEnclosingScope( name, TYPEDEFname );56 typedefTable.addToEnclosingScope( name, TYPEDEFname /*, "MTD"*/ ); 57 57 } // if 58 58 } // TypedefTable::makeTypedef 59 59 60 void TypedefTable::addToEnclosingScope( const std::string & identifier, int kind ) { 60 void TypedefTable::addToScope( const std::string & identifier, int kind /*, const char * locn*/ ) { 61 auto scope = kindTable.currentScope(); 62 debugPrint( cerr << "Adding at " /* << locn */ << " " << identifier << " as kind " << kind << " scope " << scope << endl ); 63 auto ret = kindTable.insertAt( scope, identifier, kind ); 64 if ( ! ret.second ) ret.first->second = kind; // exists => update 65 } // TypedefTable::addToScope 66 67 void TypedefTable::addToEnclosingScope( const std::string & identifier, int kind /*, const char * locn*/ ) { 61 68 assert( kindTable.currentScope() >= 1 ); 62 69 auto scope = kindTable.currentScope() - 1; 63 debugPrint( "Adding" << identifier << " as kind " << kind << " scope " << scope << endl );70 debugPrint( cerr << "Adding2 at " /* << locn */ << " " << identifier << " as kind " << kind << " scope " << scope << endl ); 64 71 auto ret = kindTable.insertAt( scope, identifier, kind ); 65 72 if ( ! ret.second ) ret.first->second = kind; // exists => update … … 68 75 void TypedefTable::enterScope() { 69 76 kindTable.beginScope(); 70 debugPrint( "Entering scope " << kindTable.currentScope() << endl ); 77 debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl ); 78 debugPrint( print() ); 71 79 } // TypedefTable::enterScope 72 80 73 81 void TypedefTable::leaveScope() { 74 debugPrint( "Leaving scope " << kindTable.currentScope() << endl ); 82 debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl ); 83 debugPrint( print() ); 75 84 kindTable.endScope(); 76 85 } // TypedefTable::leaveScope 77 86 78 // void TypedefTable::print( void ) const { 79 // for ( KindTable::const_iterator i = table.begin(); i != table.end(); i++) { 80 // debugPrint( (*i ).first << ": " ); 81 // list< Entry > declList = (*i).second; 82 // for ( list< Entry >::const_iterator j = declList.begin(); j != declList.end(); j++ ) { 83 // debugPrint( "(" << (*j).scope << " " << (*j).kind << ") " ); 84 // } 85 // debugPrint( endl ); 86 // } // for 87 // } 87 void TypedefTable::print( void ) const { 88 KindTable::size_type scope = kindTable.currentScope(); 89 debugPrint( cerr << "[" << scope << "]" ); 90 for ( KindTable::const_iterator i = kindTable.begin(); i != kindTable.end(); i++ ) { 91 while ( i.get_level() != scope ) { 92 --scope; 93 debugPrint( cerr << endl << "[" << scope << "]" ); 94 } // while 95 debugPrint( cerr << " " << (*i).first << ":" << (*i).second ); 96 } // for 97 while ( scope > 0 ) { 98 --scope; 99 debugPrint( cerr << endl << "[" << scope << "]" ); 100 } 101 debugPrint( cerr << endl ); 102 } 88 103 89 104 // Local Variables: // -
src/Parser/TypedefTable.h
rbd946e4 r3d26610 10 10 // Created On : Sat May 16 15:24:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Tue May 22 08:39:29 201813 // Update Count : 7712 // Last Modified On : Wed May 30 17:02:49 2018 13 // Update Count : 82 14 14 // 15 15 … … 32 32 void changeKind( const std::string & identifier, int kind ); 33 33 void makeTypedef( const std::string & name ); 34 void addToEnclosingScope( const std::string & identifier, int kind ); 34 void addToScope( const std::string & identifier, int kind /*, const char **/ ); 35 void addToEnclosingScope( const std::string & identifier, int kind /*, const char */ ); 35 36 36 37 void enterScope(); 37 38 void leaveScope(); 39 40 void print( void ) const; 38 41 }; // TypedefTable 39 42 -
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 -
src/main.cc
rbd946e4 r3d26610 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Mon May 7 14:35:57201813 // Update Count : 49 212 // Last Modified On : Wed May 30 17:53:14 2018 13 // Update Count : 496 14 14 // 15 15 … … 573 573 yyin = input; 574 574 yylineno = 1; 575 typedefTable.enterScope();576 575 int parseStatus = yyparse(); 577 576
Note: See TracChangeset
for help on using the changeset viewer.