Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/parser.yy

    rdbedd71 r7991c7d  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Fri Aug 12 07:59:58 2022
    13 // Update Count     : 5649
     12// Last Modified On : Fri Jul  1 15:35:08 2022
     13// Update Count     : 5405
    1414//
    1515
     
    5858
    5959// lex uses __null in a boolean context, it's fine.
    60 //#pragma GCC diagnostic ignored "-Wparentheses-equality"
     60#pragma GCC diagnostic ignored "-Wparentheses-equality"
    6161
    6262extern DeclarationNode * parseTree;
     
    197197} // fieldDecl
    198198
    199 #define NEW_ZERO new ExpressionNode( build_constantInteger( *new string( "0" ) ) )
    200 #define NEW_ONE  new ExpressionNode( build_constantInteger( *new string( "1" ) ) )
    201 #define UPDOWN( compop, left, right ) (compop == OperKinds::LThan || compop == OperKinds::LEThan ? left : right)
    202 
    203 ForCtrl * forCtrl( DeclarationNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    204         if ( index->initializer ) {
    205                 SemanticError( yylloc, "Direct initialization disallowed. Use instead: type var; initialization ~ comparison ~ increment." );
    206         } // if
    207         if ( index->next ) {
    208                 SemanticError( yylloc, "Multiple loop indexes disallowed in for-loop declaration." );
    209         } // if
    210         return new ForCtrl( index->addInitializer( new InitializerNode( start ) ),
    211                 // NULL comp/inc => leave blank
    212                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index->name ) ) ), comp ) ) : nullptr,
    213                 inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    214                                                         OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index->name ) ) ), inc ) ) : nullptr );
    215 } // forCtrl
    216 
    217199ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) {
    218200        ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->expr.get());
     
    224206                distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),
    225207                // NULL comp/inc => leave blank
    226                 comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : nullptr,
     208                comp ? new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ) : 0,
    227209                inc ? new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto
    228                                                         OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : nullptr );
     210                                                        OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) : 0 );
    229211} // forCtrl
    230212
     
    364346%type<ifctl> conditional_declaration
    365347%type<fctl> for_control_expression              for_control_expression_list
    366 %type<compop> updown updowneq downupdowneq
     348%type<compop> inclexcl
    367349%type<en> subrange
    368350%type<decl> asm_name_opt
     
    12571239iteration_statement:
    12581240        WHILE '(' ')' statement                                                         %prec THEN // CFA => while ( 1 )
    1259                 { $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) ); }
     1241                { $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) ); }
    12601242        | WHILE '(' ')' statement ELSE statement                        // CFA
    12611243                {
    1262                         $$ = new StatementNode( build_while( new CondCtl( nullptr, NEW_ONE ), maybe_build_compound( $4 ) ) );
     1244                        $$ = new StatementNode( build_while( new CondCtl( nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ), maybe_build_compound( $4 ) ) );
    12631245                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12641246                }
     
    12681250                { $$ = new StatementNode( build_while( $3, maybe_build_compound( $5 ), $7 ) ); }
    12691251        | DO statement WHILE '(' ')' ';'                                        // CFA => do while( 1 )
    1270                 { $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) ); }
     1252                { $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) ); }
    12711253        | DO statement WHILE '(' ')' ELSE statement                     // CFA
    12721254                {
    1273                         $$ = new StatementNode( build_do_while( NEW_ONE, maybe_build_compound( $2 ) ) );
     1255                        $$ = new StatementNode( build_do_while( new ExpressionNode( build_constantInteger( *new string( "1" ) ) ), maybe_build_compound( $2 ) ) );
    12741256                        SemanticWarning( yylloc, Warning::SuperfluousElse, "" );
    12751257                }
     
    13231305
    13241306        | comma_expression                                                                      // CFA
    1325                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), NEW_ZERO, OperKinds::LThan, $1->clone(), NEW_ONE ); }
    1326         | downupdowneq comma_expression                                         // CFA
    1327                 { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $1, NEW_ZERO, $2->clone() ), $1, UPDOWN( $1, $2->clone(), NEW_ZERO ), NEW_ONE ); }
    1328 
    1329         | comma_expression updowneq comma_expression            // CFA
    1330                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), NEW_ONE ); }
    1331         | '@' updowneq comma_expression                                         // CFA
    1332                 {
    1333                         if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1334                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, NEW_ONE );
    1335                 }
    1336         | comma_expression updowneq '@'                                         // CFA
    1337                 {
    1338                         if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing comparison ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
    1339                         else { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1340                 }
    1341         | comma_expression updowneq comma_expression '~' comma_expression // CFA
    1342                 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), UPDOWN( $2, $1->clone(), $3 ), $2, UPDOWN( $2, $3->clone(), $1->clone() ), $5 ); }
    1343         | '@' updowneq comma_expression '~' comma_expression // CFA
    1344                 {
    1345                         if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1346                         else $$ = forCtrl( $3, new string( DeclarationNode::anonymous.newName() ), $3->clone(), $2, nullptr, $5 );
    1347                 }
    1348         | comma_expression updowneq '@' '~' comma_expression // CFA
    1349                 {
    1350                         if ( $2 == OperKinds::LThan || $2 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing comparison ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
    1351                         else { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1352                 }
    1353         | comma_expression updowneq comma_expression '~' '@' // CFA, error
    1354                 { SemanticError( yylloc, "Missing increment ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
    1355         | '@' updowneq comma_expression '~' '@'                         // CFA, error
    1356                 { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
    1357         | comma_expression updowneq '@' '~' '@'                         // CFA, error
    1358                 { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
    1359         | '@' updowneq '@' '~' '@'                                                      // CFA, error
    1360                 { SemanticError( yylloc, "Missing loop fields ('@') with an anonymous loop index is meaningless." ); $$ = nullptr; }
    1361 
     1307                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1308                                                OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1309        | '=' comma_expression                                                          // CFA
     1310                { $$ = forCtrl( $2, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1311                                                OperKinds::LEThan, $2->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1312        | comma_expression inclexcl comma_expression            // CFA
     1313                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1314        | comma_expression inclexcl comma_expression '~' comma_expression // CFA
     1315                { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); }
     1316        | comma_expression ';'                                                          // CFA
     1317                { $$ = forCtrl( new ExpressionNode( build_constantInteger( *new string( "0u" ) ) ), $1, nullptr, OperKinds::LThan, nullptr, nullptr ); }
    13621318        | comma_expression ';' comma_expression                         // CFA
    1363                 { $$ = forCtrl( $3, $1, NEW_ZERO, OperKinds::LThan, $3->clone(), NEW_ONE ); }
    1364         | comma_expression ';' downupdowneq comma_expression // CFA
    1365                 { $$ = forCtrl( $4, $1, UPDOWN( $3, NEW_ZERO, $4->clone() ), $3, UPDOWN( $3, $4->clone(), NEW_ZERO ), NEW_ONE ); }
    1366 
    1367         | comma_expression ';' comma_expression updowneq comma_expression // CFA
    1368                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), NEW_ONE ); }
    1369         | comma_expression ';' '@' updowneq comma_expression // CFA
    1370                 {
    1371                         if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1372                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, NEW_ONE );
    1373                 }
    1374         | comma_expression ';' comma_expression updowneq '@' // CFA
    1375                 {
    1376                         if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1377                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
    1378                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    1379                 }
    1380         | comma_expression ';' '@' updowneq '@'                         // CFA, error
    1381                 { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1382 
    1383         | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    1384                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    1385         | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, error
    1386                 {
    1387                         if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1388                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, $7 );
    1389                 }
    1390         | comma_expression ';' comma_expression updowneq '@' '~' comma_expression // CFA
    1391                 {
    1392                         if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1393                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
    1394                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, $7 );
    1395                 }
    1396         | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    1397                 { $$ = forCtrl( $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    1398         | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, error
    1399                 {
    1400                         if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1401                         else $$ = forCtrl( $5, $1, $5->clone(), $4, nullptr, nullptr );
    1402                 }
    1403         | comma_expression ';' comma_expression updowneq '@' '~' '@' // CFA
    1404                 {
    1405                         if ( $4 == OperKinds::GThan || $4 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1406                         else if ( $4 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
    1407                         else $$ = forCtrl( $3, $1, $3->clone(), $4, nullptr, nullptr );
    1408                 }
    1409         | comma_expression ';' '@' updowneq '@' '~' '@' // CFA
    1410                 { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1411 
    1412         | declaration comma_expression                                          // CFA
    1413                 { $$ = forCtrl( $1, NEW_ZERO, OperKinds::LThan, $2, NEW_ONE ); }
    1414         | declaration downupdowneq comma_expression                     // CFA
    1415                 { $$ = forCtrl( $1, UPDOWN( $2, NEW_ZERO, $3 ), $2, UPDOWN( $2, $3->clone(), NEW_ZERO ), NEW_ONE ); }
    1416 
    1417         | declaration comma_expression updowneq comma_expression // CFA
    1418                 { $$ = forCtrl( $1, UPDOWN( $3, $2->clone(), $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), NEW_ONE ); }
    1419         | declaration '@' updowneq comma_expression                     // CFA
    1420                 {
    1421                         if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1422                         else $$ = forCtrl( $1, $4, $3, nullptr, NEW_ONE );
    1423                 }
    1424         | declaration comma_expression updowneq '@'                     // CFA
    1425                 {
    1426                         if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1427                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
    1428                         else $$ = forCtrl( $1, $2, $3, nullptr, NEW_ONE );
    1429                 }
    1430 
    1431         | declaration comma_expression updowneq comma_expression '~' comma_expression // CFA
    1432                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), $6 ); }
    1433         | declaration '@' updowneq comma_expression '~' comma_expression // CFA
    1434                 {
    1435                         if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1436                         else $$ = forCtrl( $1, $4, $3, nullptr, $6 );
    1437                 }
    1438         | declaration comma_expression updowneq '@' '~' comma_expression // CFA
    1439                 {
    1440                         if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1441                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
    1442                         else $$ = forCtrl( $1, $2, $3, nullptr, $6 );
    1443                 }
    1444         | declaration comma_expression updowneq comma_expression '~' '@' // CFA
    1445                 { $$ = forCtrl( $1, UPDOWN( $3, $2, $4 ), $3, UPDOWN( $3, $4->clone(), $2->clone() ), nullptr ); }
    1446         | declaration '@' updowneq comma_expression '~' '@' // CFA
    1447                 {
    1448                         if ( $3 == OperKinds::LThan || $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1449                         else $$ = forCtrl( $1, $4, $3, nullptr, nullptr );
    1450                 }
    1451         | declaration comma_expression updowneq '@' '~' '@'     // CFA
    1452                 {
    1453                         if ( $3 == OperKinds::GThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
    1454                         else if ( $3 == OperKinds::LEThan ) { SemanticError( yylloc, "Equality with missing comparison is meaningless. Use \"~\"." ); $$ = nullptr; }
    1455                         else $$ = forCtrl( $1, $2, $3, nullptr, nullptr );
    1456                 }
    1457         | declaration '@' updowneq '@' '~' '@'                          // CFA, error
    1458                 { SemanticError( yylloc, "Missing start value so cannot compare." ); $$ = nullptr; }
     1319                { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1320                                                OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1321        | comma_expression ';' '=' comma_expression                     // CFA
     1322                { $$ = forCtrl( $4, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ),
     1323                                                OperKinds::LEThan, $4->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1324        | comma_expression ';' comma_expression inclexcl comma_expression // CFA
     1325                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1326        | comma_expression ';' comma_expression inclexcl comma_expression '~' comma_expression // CFA
     1327                { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); }
    14591328
    14601329        | comma_expression ';' TYPEDEFname                                      // CFA, array type
    14611330                {
    1462                         SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    1463                         //$$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
    1464                 }
    1465         | comma_expression ';' downupdowneq TYPEDEFname         // CFA, array type
    1466                 {
    1467                         if ( $3 == OperKinds::LEThan || $3 == OperKinds::GEThan ) { SemanticError( yylloc, "All enumation ranges are equal (all values). Remove \"=~\"." ); $$ = nullptr; }
    1468                         SemanticError( yylloc, "Type iterator is currently unimplemented." ); $$ = nullptr;
    1469                 }
     1331                        SemanticError( yylloc, "Array interator is currently unimplemented." ); $$ = nullptr;
     1332                        $$ = forCtrl( new ExpressionNode( build_varref( $3 ) ), $1, nullptr, OperKinds::Range, nullptr, nullptr );
     1333                }
     1334
     1335                // There is a S/R conflicit if ~ and -~ are factored out.
     1336        | comma_expression ';' comma_expression '~' '@'         // CFA
     1337                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1338        | comma_expression ';' comma_expression ErangeDown '@' // CFA
     1339                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); }
     1340        | comma_expression ';' comma_expression '~' '@' '~' comma_expression // CFA
     1341                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, $7 ); }
     1342        | comma_expression ';' comma_expression ErangeDown '@' '~' comma_expression // CFA
     1343                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::GThan, nullptr, $7 ); }
     1344        | comma_expression ';' comma_expression '~' '@' '~' '@' // CFA
     1345                { $$ = forCtrl( $3, $1, $3->clone(), OperKinds::LThan, nullptr, nullptr ); }
    14701346        ;
    14711347
    1472 downupdowneq:
    1473         ErangeDown
    1474                 { $$ = OperKinds::GThan; }
     1348inclexcl:
     1349        '~'
     1350                { $$ = OperKinds::LThan; }
    14751351        | ErangeUpEq
    14761352                { $$ = OperKinds::LEThan; }
    1477         | ErangeDownEq
    1478                 { $$ = OperKinds::GEThan; }
    1479         ;
    1480 
    1481 updown:
    1482         '~'
    1483                 { $$ = OperKinds::LThan; }
    14841353        | ErangeDown
    14851354                { $$ = OperKinds::GThan; }
    1486         ;
    1487 
    1488 updowneq:
    1489         updown
    1490         | ErangeUpEq
    1491                 { $$ = OperKinds::LEThan; }
    14921355        | ErangeDownEq
    14931356                { $$ = OperKinds::GEThan; }
     
    25322395          '{' enumerator_list comma_opt '}'
    25332396                { $$ = DeclarationNode::newEnum( $3->name, $5, true )->addQualifiers( $2 ); }
    2534         | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    2535                 { SemanticError( yylloc, "Unvalued enumerated type is currently unimplemented." ); $$ = nullptr; }
    25362397        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
    25372398                {
Note: See TracChangeset for help on using the changeset viewer.