Changes in / [b368dd8:cf5e5b1]
- Files:
-
- 5 edited
-
src/Parser/TypedefTable.cc (modified) (5 diffs)
-
src/Parser/TypedefTable.h (modified) (2 diffs)
-
src/Parser/parser.yy (modified) (32 diffs)
-
src/main.cc (modified) (2 diffs)
-
tools/prettyprinter/lex.ll (modified) (2 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Parser/TypedefTable.cc
rb368dd8 rcf5e5b1 10 10 // Created On : Sat May 16 15:20:13 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 30 18:04:38201813 // Update Count : 1 4812 // Last Modified On : Tue May 22 08:40:01 2018 13 // Update Count : 121 14 14 // 15 15 … … 20 20 #if 0 21 21 #include <iostream> 22 #define debugPrint( code ) code22 #define debugPrint( x ) cerr << x 23 23 #else 24 #define debugPrint( code)24 #define debugPrint( x ) 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 /*, "MTD"*/);56 typedefTable.addToEnclosingScope( name, TYPEDEFname ); 57 57 } // if 58 58 } // TypedefTable::makeTypedef 59 59 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*/ ) { 60 void TypedefTable::addToEnclosingScope( const std::string & identifier, int kind ) { 68 61 assert( kindTable.currentScope() >= 1 ); 69 62 auto scope = kindTable.currentScope() - 1; 70 debugPrint( cerr << "Adding2 at " /* << locn */ << "" << identifier << " as kind " << kind << " scope " << scope << endl );63 debugPrint( "Adding " << identifier << " as kind " << kind << " scope " << scope << endl ); 71 64 auto ret = kindTable.insertAt( scope, identifier, kind ); 72 65 if ( ! ret.second ) ret.first->second = kind; // exists => update … … 75 68 void TypedefTable::enterScope() { 76 69 kindTable.beginScope(); 77 debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl ); 78 debugPrint( print() ); 70 debugPrint( "Entering scope " << kindTable.currentScope() << endl ); 79 71 } // TypedefTable::enterScope 80 72 81 73 void TypedefTable::leaveScope() { 82 debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl ); 83 debugPrint( print() ); 74 debugPrint( "Leaving scope " << kindTable.currentScope() << endl ); 84 75 kindTable.endScope(); 85 76 } // TypedefTable::leaveScope 86 77 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 } 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 // } 103 88 104 89 // Local Variables: // -
src/Parser/TypedefTable.h
rb368dd8 rcf5e5b1 10 10 // Created On : Sat May 16 15:24:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 30 17:02:49 201813 // Update Count : 8212 // Last Modified On : Tue May 22 08:39:29 2018 13 // Update Count : 77 14 14 // 15 15 … … 32 32 void changeKind( const std::string & identifier, int kind ); 33 33 void makeTypedef( const std::string & name ); 34 void addToScope( const std::string & identifier, int kind /*, const char **/ ); 35 void addToEnclosingScope( const std::string & identifier, int kind /*, const char */ ); 34 void addToEnclosingScope( const std::string & identifier, int kind ); 36 35 37 36 void enterScope(); 38 37 void leaveScope(); 39 40 void print( void ) const;41 38 }; // TypedefTable 42 39 -
src/Parser/parser.yy
rb368dd8 rcf5e5b1 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Thu May 31 15:11:40201813 // Update Count : 3 44412 // Last Modified On : Mon May 28 17:01:36 2018 13 // Update Count : 3383 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 if_statement267 %type<sn> selection_statement 268 268 %type<sn> switch_clause_list_opt switch_clause_list 269 269 %type<en> case_value … … 332 332 %type<decl> c_declaration static_assert 333 333 %type<decl> KR_function_declarator KR_function_no_ptr KR_function_ptr KR_function_array 334 %type<decl> KR_ parameter_list KR_parameter_list_opt334 %type<decl> KR_declaration_list KR_declaration_list_opt 335 335 336 336 %type<decl> parameter_declaration parameter_list parameter_type_list_opt … … 404 404 //************************* Namespace Management ******************************** 405 405 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 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. 432 428 433 429 push: … … 858 854 // | '[' push assignment_expression pop ']' 859 855 // { $$ = new ExpressionNode( build_tuple( $3 ) ); } 860 '[' ',' tuple_expression_list']'861 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $ 3) ) ); }862 | '[' push assignment_expression pop ',' tuple_expression_list']'863 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $ 6) ) ); }856 '[' push ',' tuple_expression_list pop ']' 857 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)(new ExpressionNode( nullptr ) )->set_last( $4 ) ) ); } 858 | '[' push assignment_expression ',' tuple_expression_list pop ']' 859 { $$ = new ExpressionNode( build_tuple( (ExpressionNode *)$3->set_last( $5 ) ) ); } 864 860 ; 865 861 … … 913 909 '{' '}' 914 910 { $$ = new StatementNode( build_compound( (StatementNode *)0 ) ); } 915 | '{' push 911 | '{' 912 // Two scopes are necessary because the block itself has a scope, but every declaration within the block also 913 // requires its own scope. 914 push push 916 915 local_label_declaration_opt // GCC, local labels 917 916 statement_decl_list // C99, intermix declarations and statements 918 917 pop '}' 919 { $$ = new StatementNode( build_compound( $ 4) ); }918 { $$ = new StatementNode( build_compound( $5 ) ); } 920 919 ; 921 920 922 921 statement_decl_list: // C99 923 922 statement_decl 924 | statement_decl_list statement_decl925 { if ( $1 != 0 ) { $1->set_last( $ 2); $$ = $1; } }923 | statement_decl_list push statement_decl 924 { if ( $1 != 0 ) { $1->set_last( $3 ); $$ = $1; } } 926 925 ; 927 926 … … 941 940 $$ = new StatementNode( $2 ); 942 941 } 943 | statement 942 | statement pop 944 943 ; 945 944 … … 956 955 957 956 selection_statement: 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; } 957 IF '(' push if_control_expression ')' statement %prec THEN 958 // explicitly deal with the shift/reduce conflict on if/else 959 { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); } 960 | IF '(' push if_control_expression ')' statement ELSE statement 961 { $$ = new StatementNode( build_if( $4, $6, $8 ) ); } 962 962 | SWITCH '(' comma_expression ')' case_clause 963 963 { $$ = new StatementNode( build_switch( true, $3, $5 ) ); } 964 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop'}' // CFA964 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA 965 965 { 966 966 StatementNode *sw = new StatementNode( build_switch( true, $3, $8 ) ); … … 974 974 | CHOOSE '(' comma_expression ')' case_clause // CFA 975 975 { $$ = new StatementNode( build_switch( false, $3, $5 ) ); } 976 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt pop'}' // CFA976 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA 977 977 { 978 978 StatementNode *sw = new StatementNode( build_switch( false, $3, $8 ) ); … … 981 981 ; 982 982 983 if_statement:984 IF '(' if_control_expression ')' statement %prec THEN985 // explicitly deal with the shift/reduce conflict on if/else986 { $$ = new StatementNode( build_if( $3, $5, nullptr ) ); }987 | IF '(' if_control_expression ')' statement ELSE statement988 { $$ = new StatementNode( build_if( $3, $5, $7 ) ); }989 ;990 991 992 983 if_control_expression: 993 comma_expression 984 comma_expression pop 994 985 { $$ = new IfCtl( nullptr, $1 ); } 995 | c_declaration // no semi-colon986 | c_declaration pop // no semi-colon 996 987 { $$ = new IfCtl( $1, nullptr ); } 997 | cfa_declaration // no semi-colon988 | cfa_declaration pop // no semi-colon 998 989 { $$ = new IfCtl( $1, nullptr ); } 999 990 | declaration comma_expression // semi-colon separated … … 1056 1047 | DO statement WHILE '(' comma_expression ')' ';' 1057 1048 { $$ = new StatementNode( build_while( $5, $2, true ) ); } 1058 | FOR '(' push for_control_expression ')' statement pop1049 | FOR '(' push for_control_expression ')' statement 1059 1050 { $$ = new StatementNode( build_for( $4, $6 ) ); } 1060 1051 ; 1061 1052 1062 1053 for_control_expression: 1063 comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt1064 { $$ = new ForCtl( $1, $ 3, $5); }1054 comma_expression_opt pop ';' comma_expression_opt ';' comma_expression_opt 1055 { $$ = new ForCtl( $1, $4, $6 ); } 1065 1056 | declaration comma_expression_opt ';' comma_expression_opt // C99 1066 1057 { $$ = new ForCtl( $1, $2, $4 ); } … … 1184 1175 1185 1176 handler_clause: 1186 handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop1187 { $$ = new StatementNode( build_catch( $1, $ 4, $6, $8) ); }1188 | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop1189 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $ 5, $7, $9) ) ); }1177 handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop 1178 { $$ = new StatementNode( build_catch( $1, $5, $7, $9 ) ); } 1179 | handler_clause handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop 1180 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $6, $8, $10 ) ) ); } 1190 1181 ; 1191 1182 … … 1291 1282 1292 1283 declaration_list_opt: // used at beginning of switch statement 1284 pop // empty 1285 { $$ = nullptr; } 1286 | declaration_list 1287 ; 1288 1289 declaration_list: 1290 declaration 1291 | declaration_list push declaration 1292 { $$ = $1->appendList( $3 ); } 1293 ; 1294 1295 KR_declaration_list_opt: // used to declare parameter types in K&R style functions 1293 1296 // empty 1294 1297 { $$ = nullptr; } 1295 | declaration_list 1296 ; 1297 1298 declaration_list: 1299 declaration 1300 | declaration_list declaration 1301 { $$ = $1->appendList( $2 ); } 1302 ; 1303 1304 KR_parameter_list_opt: // used to declare parameter types in K&R style functions 1305 // empty 1306 { $$ = nullptr; } 1307 | KR_parameter_list 1308 ; 1309 1310 KR_parameter_list: 1298 | KR_declaration_list 1299 ; 1300 1301 KR_declaration_list: 1311 1302 push c_declaration pop ';' 1312 1303 { $$ = $2; } 1313 | KR_ parameter_list push c_declaration pop ';'1304 | KR_declaration_list push c_declaration pop ';' 1314 1305 { $$ = $1->appendList( $3 ); } 1315 1306 ; … … 1331 1322 1332 1323 declaration: // old & new style declarations 1333 c_declaration ';'1334 | cfa_declaration ';'// CFA1324 c_declaration pop ';' 1325 | cfa_declaration pop ';' // CFA 1335 1326 | static_assert 1336 1327 ; … … 1440 1431 TYPEDEF cfa_variable_specifier 1441 1432 { 1442 typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname /*, "1"*/);1433 typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname ); 1443 1434 $$ = $2->addTypedef(); 1444 1435 } 1445 1436 | TYPEDEF cfa_function_specifier 1446 1437 { 1447 typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname /*, "2"*/);1438 typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname ); 1448 1439 $$ = $2->addTypedef(); 1449 1440 } 1450 1441 | cfa_typedef_declaration pop ',' push no_attr_identifier 1451 1442 { 1452 typedefTable.addToEnclosingScope( *$5, TYPEDEFname /*, "3"*/);1443 typedefTable.addToEnclosingScope( *$5, TYPEDEFname ); 1453 1444 $$ = $1->appendList( $1->cloneType( $5 ) ); 1454 1445 } … … 1461 1452 TYPEDEF type_specifier declarator 1462 1453 { 1463 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname /*, "4"*/);1454 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname ); 1464 1455 $$ = $3->addType( $2 )->addTypedef(); 1465 1456 } 1466 1457 | typedef_declaration pop ',' push declarator 1467 1458 { 1468 typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname /*, "5"*/);1459 typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname ); 1469 1460 $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() ); 1470 1461 } 1471 1462 | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 ) 1472 1463 { 1473 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname /*, "6"*/);1464 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname ); 1474 1465 $$ = $4->addType( $3 )->addQualifiers( $1 )->addTypedef(); 1475 1466 } 1476 1467 | type_specifier TYPEDEF declarator 1477 1468 { 1478 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname /*, "7"*/);1469 typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname ); 1479 1470 $$ = $3->addType( $1 )->addTypedef(); 1480 1471 } 1481 1472 | type_specifier TYPEDEF type_qualifier_list declarator 1482 1473 { 1483 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname /*, "8"*/);1474 typedefTable.addToEnclosingScope( *$4->name, TYPEDEFname ); 1484 1475 $$ = $4->addQualifiers( $1 )->addTypedef()->addType( $1 ); 1485 1476 } … … 1608 1599 1609 1600 forall: 1610 FORALL '(' type_parameter_list')' // CFA1611 { $$ = DeclarationNode::newForall( $ 3); }1601 FORALL '(' push type_parameter_list pop ')' // CFA 1602 { $$ = DeclarationNode::newForall( $4 ); } 1612 1603 ; 1613 1604 … … 2201 2192 type_parameter: // CFA 2202 2193 type_class no_attr_identifier_or_type_name 2203 { typedefTable.addTo Scope( *$2, TYPEDEFname /*, "9"*/); }2194 { typedefTable.addToEnclosingScope( *$2, TYPEDEFname ); } 2204 2195 type_initializer_opt assertion_list_opt 2205 2196 { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); } … … 2237 2228 | '|' '{' push trait_declaration_list pop '}' 2238 2229 { $$ = $4; } 2239 //| '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}' '(' type_list ')'2240 //{ SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; }2230 | '|' '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}' '(' type_list ')' 2231 { SemanticError( yylloc, "Generic data-type assertion is currently unimplemented." ); $$ = nullptr; } 2241 2232 ; 2242 2233 … … 2270 2261 no_attr_identifier_or_type_name 2271 2262 { 2272 typedefTable.addToEnclosingScope( *$1, TYPEDEFname /*, "10"*/);2263 typedefTable.addToEnclosingScope( *$1, TYPEDEFname ); 2273 2264 $$ = DeclarationNode::newTypeDecl( $1, 0 ); 2274 2265 } 2275 | no_attr_identifier_or_type_name '(' type_parameter_list')'2276 { 2277 typedefTable.addToEnclosingScope( *$1, TYPEGENname /*, "11"*/);2278 $$ = DeclarationNode::newTypeDecl( $1, $ 3);2266 | no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' 2267 { 2268 typedefTable.addToEnclosingScope( *$1, TYPEGENname ); 2269 $$ = DeclarationNode::newTypeDecl( $1, $4 ); 2279 2270 } 2280 2271 ; 2281 2272 2282 2273 trait_specifier: // CFA 2283 TRAIT no_attr_identifier_or_type_name '(' type_parameter_list')' '{' '}'2284 { $$ = DeclarationNode::newTrait( $2, $ 4, 0 ); }2285 | TRAIT no_attr_identifier_or_type_name '(' type_parameter_list')' '{' push trait_declaration_list pop '}'2286 { $$ = DeclarationNode::newTrait( $2, $ 4, $8); }2274 TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' '}' 2275 { $$ = DeclarationNode::newTrait( $2, $5, 0 ); } 2276 | TRAIT no_attr_identifier_or_type_name '(' push type_parameter_list pop ')' '{' push trait_declaration_list pop '}' 2277 { $$ = DeclarationNode::newTrait( $2, $5, $10 ); } 2287 2278 ; 2288 2279 … … 2322 2313 2323 2314 external_definition_list: 2324 push external_definition pop 2325 { $$ = $2; } 2315 external_definition 2326 2316 | external_definition_list 2327 2317 { forall = xxx; } 2328 push external_definition pop2318 push external_definition 2329 2319 { $$ = $1 ? $1->appendList( $4 ) : $4; } 2330 2320 ; … … 2348 2338 linkage = LinkageSpec::linkageUpdate( yylloc, linkage, $2 ); 2349 2339 } 2350 // SKULLDUGGERY: Declarations in extern "X" need to be added to the current lexical scope. However, 2351 // external_definition_list_opt creates a new scope that loses the types at the end of the extern block. The 2352 // correction is a pop/push (reverse order) to undo the push/pop from external_definition_list_opt. This 2353 // trick works for nested extern "X"s, as each one undoes itself in the nesting. 2354 '{' pop external_definition_list_opt push '}' 2340 '{' external_definition_list_opt '}' 2355 2341 { 2356 2342 linkage = linkageStack.top(); 2357 2343 linkageStack.pop(); 2358 $$ = $ 6;2344 $$ = $5; 2359 2345 } 2360 2346 | EXTENSION external_definition // GCC, multiple __extension__ allowed, meaning unknown … … 2365 2351 | type_qualifier_list 2366 2352 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type 2367 '{' external_definition_list push '}'// CFA, namespace2368 { 2369 for ( DeclarationNode * iter = $ 4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {2353 push '{' external_definition_list '}' // CFA, namespace 2354 { 2355 for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 2370 2356 if ( isMangled( iter->linkage ) ) { // ignore extern "C" 2371 2357 iter->addQualifiers( $1->clone() ); … … 2374 2360 xxx = false; 2375 2361 delete $1; 2376 $$ = $ 4;2362 $$ = $5; 2377 2363 } 2378 2364 | declaration_qualifier_list 2379 2365 { if ( $1->type->forall ) xxx = forall = true; } // remember generic type 2380 '{' external_definition_list '}'// CFA, namespace2381 { 2382 for ( DeclarationNode * iter = $ 4; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {2366 push '{' external_definition_list '}' // CFA, namespace 2367 { 2368 for ( DeclarationNode * iter = $5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 2383 2369 if ( isMangled( iter->linkage ) ) { // ignore extern "C" 2384 2370 iter->addQualifiers( $1->clone() ); … … 2387 2373 xxx = false; 2388 2374 delete $1; 2389 $$ = $ 4;2375 $$ = $5; 2390 2376 } 2391 2377 | declaration_qualifier_list type_qualifier_list … … 2394 2380 if ( $2->type->forall ) xxx = forall = true; // remember generic type 2395 2381 } 2396 '{' external_definition_list '}'// CFA, namespace2397 { 2398 for ( DeclarationNode * iter = $ 5; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) {2382 push '{' external_definition_list '}' // CFA, namespace 2383 { 2384 for ( DeclarationNode * iter = $6; iter != nullptr; iter = (DeclarationNode *)iter->get_next() ) { 2399 2385 if ( isMangled( iter->linkage ) && isMangled( $2->linkage ) ) { // ignore extern "C" 2400 2386 iter->addQualifiers( $1->clone() ); … … 2405 2391 delete $1; 2406 2392 delete $2; 2407 $$ = $ 5;2393 $$ = $6; 2408 2394 } 2409 2395 ; … … 2418 2404 | function_declarator compound_statement 2419 2405 { $$ = $1->addFunctionBody( $2 ); } 2420 | KR_function_declarator KR_ parameter_list_opt compound_statement2406 | KR_function_declarator KR_declaration_list_opt compound_statement 2421 2407 { $$ = $1->addOldDeclList( $2 )->addFunctionBody( $3 ); } 2422 2408 ; … … 2458 2444 2459 2445 // Old-style K&R function definition, OBSOLESCENT (see 4) 2460 | declaration_specifier KR_function_declarator KR_ parameter_list_opt with_clause_opt compound_statement2446 | declaration_specifier KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement 2461 2447 { 2462 2448 rebindForall( $1, $2 ); … … 2464 2450 } 2465 2451 // handles default int return type, OBSOLESCENT (see 1) 2466 | type_qualifier_list KR_function_declarator KR_ parameter_list_opt with_clause_opt compound_statement2452 | type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement 2467 2453 { $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); } 2468 2454 // handles default int return type, OBSOLESCENT (see 1) 2469 | declaration_qualifier_list KR_function_declarator KR_ parameter_list_opt with_clause_opt compound_statement2455 | declaration_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement 2470 2456 { $$ = $2->addOldDeclList( $3 )->addFunctionBody( $5, $4 )->addQualifiers( $1 ); } 2471 2457 // handles default int return type, OBSOLESCENT (see 1) 2472 | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_ parameter_list_opt with_clause_opt compound_statement2458 | declaration_qualifier_list type_qualifier_list KR_function_declarator KR_declaration_list_opt with_clause_opt compound_statement 2473 2459 { $$ = $3->addOldDeclList( $4 )->addFunctionBody( $6, $5 )->addQualifiers( $2 )->addQualifiers( $1 ); } 2474 2460 ; … … 2715 2701 typedef 2716 2702 // hide type name in enclosing scope by variable name 2717 { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER /*, "ID"*/); }2703 { typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER ); } 2718 2704 | '(' paren_type ')' 2719 2705 { $$ = $2; } … … 3205 3191 '[' push cfa_abstract_parameter_list pop ']' 3206 3192 { $$ = DeclarationNode::newTuple( $3 ); } 3207 | '[' push type_specifier_nobody ELLIPSIS pop']'3193 | '[' push type_specifier_nobody ELLIPSIS ']' 3208 3194 { SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; } 3209 | '[' push type_specifier_nobody ELLIPSIS constant_expression pop']'3195 | '[' push type_specifier_nobody ELLIPSIS constant_expression ']' 3210 3196 { SemanticError( yylloc, "Tuple array currently unimplemented." ); $$ = nullptr; } 3211 3197 ; -
src/main.cc
rb368dd8 rcf5e5b1 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed May 30 17:53:14201813 // Update Count : 49 612 // Last Modified On : Mon May 7 14:35:57 2018 13 // Update Count : 492 14 14 // 15 15 … … 573 573 yyin = input; 574 574 yylineno = 1; 575 typedefTable.enterScope(); 575 576 int parseStatus = yyparse(); 576 577 -
tools/prettyprinter/lex.ll
rb368dd8 rcf5e5b1 10 10 * Created On : Sat Dec 15 11:45:59 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Thu May 31 08:49:58201813 * Update Count : 27 412 * Last Modified On : Sun Apr 15 21:28:33 2018 13 * Update Count : 271 14 14 */ 15 15 … … 77 77 } 78 78 79 <INITIAL,C_CODE>"//"[^\n]* {// C++ style comments79 <INITIAL,C_CODE>"//"[^\n]*"\n" { // C++ style comments 80 80 #if defined(DEBUG_ALL) | defined(DEBUG_COMMENT) 81 81 cerr << "\"//\"[^\\n]*\"\n\" : " << yytext << endl;
Note:
See TracChangeset
for help on using the changeset viewer.