Changeset 2a301ff for src/Parser


Ignore:
Timestamp:
Aug 31, 2023, 11:31:15 PM (15 months ago)
Author:
JiadaL <j82liang@…>
Branches:
master
Children:
950c58e
Parents:
92355883 (diff), 686912c (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Resolve conflict

Location:
src/Parser
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/StatementNode.cc

    r92355883 r2a301ff  
    1010// Author           : Rodolfo G. Esteves
    1111// Created On       : Sat May 16 14:59:41 2015
    12 // Last Modified By : Andrew Beach
    13 // Last Modified On : Tue Apr 11 10:16:00 2023
    14 // Update Count     : 428
     12// Last Modified By : Peter A. Buhr
     13// Last Modified On : Fri Aug 11 11:44:15 2023
     14// Update Count     : 429
    1515//
    1616
     
    361361
    362362ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt ) {
    363     ast::WhenClause * clause = new ast::WhenClause( loc );
    364     clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
    365     clause->stmt = maybeMoveBuild( stmt );
    366     clause->target = maybeMoveBuild( targetExpr );
    367     return new ast::WaitUntilStmt::ClauseNode( clause );
     363        ast::WhenClause * clause = new ast::WhenClause( loc );
     364        clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     365        clause->stmt = maybeMoveBuild( stmt );
     366        clause->target = maybeMoveBuild( targetExpr );
     367        return new ast::WaitUntilStmt::ClauseNode( clause );
    368368}
    369369ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation & loc, ExpressionNode * when, StatementNode * stmt ) {
    370     ast::WhenClause * clause = new ast::WhenClause( loc );
    371     clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
    372     clause->stmt = maybeMoveBuild( stmt );
    373     return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause );
    374 }
    375 ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation & loc, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt ) {
    376     ast::WhenClause * clause = new ast::WhenClause( loc );
    377     clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
    378     clause->stmt = maybeMoveBuild( stmt );
    379     clause->target = maybeMoveBuild( timeout );
    380     return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::TIMEOUT, clause );
     370        ast::WhenClause * clause = new ast::WhenClause( loc );
     371        clause->when_cond = notZeroExpr( maybeMoveBuild( when ) );
     372        clause->stmt = maybeMoveBuild( stmt );
     373        return new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::ELSE, clause );
    381374}
    382375
    383376ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation & loc, ast::WaitUntilStmt::ClauseNode * root ) {
    384     ast::WaitUntilStmt * retStmt = new ast::WaitUntilStmt( loc );
    385     retStmt->predicateTree = root;
    386    
    387     // iterative tree traversal
    388     std::vector<ast::WaitUntilStmt::ClauseNode *> nodeStack; // stack needed for iterative traversal
    389     ast::WaitUntilStmt::ClauseNode * currNode = nullptr;
    390     ast::WaitUntilStmt::ClauseNode * lastInternalNode = nullptr;
    391     ast::WaitUntilStmt::ClauseNode * cleanup = nullptr; // used to cleanup removed else/timeout
    392     nodeStack.push_back(root);
    393 
    394     do {
    395         currNode = nodeStack.back();
    396         nodeStack.pop_back(); // remove node since it will be processed
    397 
    398         switch (currNode->op) {
    399             case ast::WaitUntilStmt::ClauseNode::LEAF:
    400                 retStmt->clauses.push_back(currNode->leaf);
    401                 break;
    402             case ast::WaitUntilStmt::ClauseNode::ELSE:
    403                 retStmt->else_stmt = currNode->leaf->stmt
    404                     ? ast::deepCopy( currNode->leaf->stmt )
    405                     : nullptr;
    406                
    407                 retStmt->else_cond = currNode->leaf->when_cond
    408                     ? ast::deepCopy( currNode->leaf->when_cond )
    409                     : nullptr;
    410 
    411                 delete currNode->leaf;
    412                 break;
    413             case ast::WaitUntilStmt::ClauseNode::TIMEOUT:
    414                 retStmt->timeout_time = currNode->leaf->target
    415                     ? ast::deepCopy( currNode->leaf->target )
    416                     : nullptr;
    417                 retStmt->timeout_stmt = currNode->leaf->stmt
    418                     ? ast::deepCopy( currNode->leaf->stmt )
    419                     : nullptr;
    420                 retStmt->timeout_cond = currNode->leaf->when_cond
    421                     ? ast::deepCopy( currNode->leaf->when_cond )
    422                     : nullptr;
    423 
    424                 delete currNode->leaf;
    425                 break;
    426             default:
    427                 nodeStack.push_back( currNode->right ); // process right after left
    428                 nodeStack.push_back( currNode->left );
    429 
    430                 // Cut else/timeout out of the tree
    431                 if ( currNode->op == ast::WaitUntilStmt::ClauseNode::LEFT_OR ) {
    432                     if ( lastInternalNode )
    433                         lastInternalNode->right = currNode->left;
    434                     else    // if not set then root is LEFT_OR
    435                         retStmt->predicateTree = currNode->left;
    436    
    437                     currNode->left = nullptr;
    438                     cleanup = currNode;
    439                 }
    440                
    441                 lastInternalNode = currNode;
    442                 break;
    443         }
    444     } while ( !nodeStack.empty() );
    445 
    446     if ( cleanup ) delete cleanup;
    447 
    448     return retStmt;
     377        ast::WaitUntilStmt * retStmt = new ast::WaitUntilStmt( loc );
     378        retStmt->predicateTree = root;
     379
     380        // iterative tree traversal
     381        std::vector<ast::WaitUntilStmt::ClauseNode *> nodeStack; // stack needed for iterative traversal
     382        ast::WaitUntilStmt::ClauseNode * currNode = nullptr;
     383        ast::WaitUntilStmt::ClauseNode * lastInternalNode = nullptr;
     384        ast::WaitUntilStmt::ClauseNode * cleanup = nullptr; // used to cleanup removed else/timeout
     385        nodeStack.push_back(root);
     386
     387        do {
     388                currNode = nodeStack.back();
     389                nodeStack.pop_back(); // remove node since it will be processed
     390
     391                switch (currNode->op) {
     392                case ast::WaitUntilStmt::ClauseNode::LEAF:
     393                        retStmt->clauses.push_back(currNode->leaf);
     394                        break;
     395                case ast::WaitUntilStmt::ClauseNode::ELSE:
     396                        retStmt->else_stmt = currNode->leaf->stmt
     397                                ? ast::deepCopy( currNode->leaf->stmt )
     398                                : nullptr;
     399                        retStmt->else_cond = currNode->leaf->when_cond
     400                                ? ast::deepCopy( currNode->leaf->when_cond )
     401                                : nullptr;
     402
     403                        delete currNode->leaf;
     404                        break;
     405                case ast::WaitUntilStmt::ClauseNode::TIMEOUT:
     406                        retStmt->timeout_time = currNode->leaf->target
     407                                ? ast::deepCopy( currNode->leaf->target )
     408                                : nullptr;
     409                        retStmt->timeout_stmt = currNode->leaf->stmt
     410                                ? ast::deepCopy( currNode->leaf->stmt )
     411                                : nullptr;
     412                        retStmt->timeout_cond = currNode->leaf->when_cond
     413                                ? ast::deepCopy( currNode->leaf->when_cond )
     414                                : nullptr;
     415
     416                        delete currNode->leaf;
     417                        break;
     418                default:
     419                        nodeStack.push_back( currNode->right ); // process right after left
     420                        nodeStack.push_back( currNode->left );
     421
     422                        // Cut else/timeout out of the tree
     423                        if ( currNode->op == ast::WaitUntilStmt::ClauseNode::LEFT_OR ) {
     424                                if ( lastInternalNode )
     425                                        lastInternalNode->right = currNode->left;
     426                                else // if not set then root is LEFT_OR
     427                                        retStmt->predicateTree = currNode->left;
     428
     429                                currNode->left = nullptr;
     430                                cleanup = currNode;
     431                        }
     432
     433                        lastInternalNode = currNode;
     434                        break;
     435                }
     436        } while ( !nodeStack.empty() );
     437
     438        if ( cleanup ) delete cleanup;
     439
     440        return retStmt;
    449441}
    450442
  • src/Parser/StatementNode.h

    r92355883 r2a301ff  
    99// Author           : Andrew Beach
    1010// Created On       : Wed Apr  5 11:42:00 2023
    11 // Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Apr 11  9:43:00 2023
    13 // Update Count     : 1
     11// Last Modified By : Peter A. Buhr
     12// Last Modified On : Fri Aug 11 11:44:07 2023
     13// Update Count     : 2
    1414//
    1515
     
    102102ast::WaitUntilStmt::ClauseNode * build_waituntil_clause( const CodeLocation &, ExpressionNode * when, ExpressionNode * targetExpr, StatementNode * stmt );
    103103ast::WaitUntilStmt::ClauseNode * build_waituntil_else( const CodeLocation &, ExpressionNode * when, StatementNode * stmt );
    104 ast::WaitUntilStmt::ClauseNode * build_waituntil_timeout( const CodeLocation &, ExpressionNode * when, ExpressionNode * timeout, StatementNode * stmt );
    105104ast::WaitUntilStmt * build_waituntil_stmt( const CodeLocation &, ast::WaitUntilStmt::ClauseNode * root );
    106105ast::Stmt * build_with( const CodeLocation &, ExpressionNode * exprs, StatementNode * stmt );
  • src/Parser/TypedefTable.cc

    r92355883 r2a301ff  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Feb 15 08:27:24 2022
    13 // Update Count     : 275
     12// Last Modified On : Wed Jul 12 06:11:28 2023
     13// Update Count     : 276
    1414//
    1515
     
    1717#include "TypedefTable.h"
    1818
    19 #include <cassert>                                // for assert
    20 #include <string>                                 // for string
    21 #include <iostream>                               // for iostream
     19#include <cassert>                                                                              // for assert
     20#include <string>                                                                               // for string
     21#include <iostream>                                                                             // for iostream
    2222
    23 #include "ExpressionNode.h"                       // for LabelNode
    24 #include "ParserTypes.h"                          // for Token
    25 #include "StatementNode.h"                        // for CondCtl, ForCtrl
     23#include "ExpressionNode.h"                                                             // for LabelNode
     24#include "ParserTypes.h"                                                                // for Token
     25#include "StatementNode.h"                                                              // for CondCtl, ForCtrl
    2626// This (generated) header must come late as it is missing includes.
    27 #include "parser.hh"              // for IDENTIFIER, TYPEDEFname, TYPEGENname
     27#include "parser.hh"                                                                    // for IDENTIFIER, TYPEDEFname, TYPEGENname
    2828
    2929using namespace std;
     
    7272// "struct". Only generate the typedef, if the name is not in use. The typedef is implicitly (silently) removed if the
    7373// name is explicitly used.
    74 void TypedefTable::makeTypedef( const string & name, int kind ) {
     74void TypedefTable::makeTypedef( const string & name, int kind, const char * locn __attribute__((unused)) ) {
    7575//    Check for existence is necessary to handle:
    7676//        struct Fred {};
     
    8080//           Fred();
    8181//        }
     82        debugPrint( cerr << "Make typedef at " << locn << " \"" << name << "\" as " << kindName( kind ) << " scope " << kindTable.currentScope() << endl );
    8283        if ( ! typedefTable.exists( name ) ) {
    8384                typedefTable.addToEnclosingScope( name, kind, "MTD" );
     
    8586} // TypedefTable::makeTypedef
    8687
    87 void TypedefTable::makeTypedef( const string & name ) {
    88         return makeTypedef( name, TYPEDEFname );
     88void TypedefTable::makeTypedef( const string & name, const char * locn __attribute__((unused)) ) {
     89        debugPrint( cerr << "Make typedef at " << locn << " \"" << name << " scope " << kindTable.currentScope() << endl );
     90        return makeTypedef( name, TYPEDEFname, "makeTypede" );
    8991} // TypedefTable::makeTypedef
    9092
    9193void TypedefTable::addToScope( const string & identifier, int kind, const char * locn __attribute__((unused)) ) {
    9294        KindTable::size_type scope = kindTable.currentScope();
    93         debugPrint( cerr << "Adding current at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << endl );
     95        debugPrint( cerr << "Adding current at " << locn << " \"" << identifier << "\" as " << kindName( kind ) << " scope " << scope << endl );
    9496        kindTable.insertAt( scope, identifier, kind );
    9597} // TypedefTable::addToScope
     
    98100        KindTable::size_type scope = kindTable.currentScope() - 1 - kindTable.getNote( kindTable.currentScope() - 1 ).level;
    99101//      size_type scope = level - kindTable.getNote( kindTable.currentScope() - 1 ).level;
    100         debugPrint( cerr << "Adding enclosing at " << locn << " " << identifier << " as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl );
     102        debugPrint( cerr << "Adding enclosing at " << locn << " \"" << identifier << "\" as " << kindName( kind ) << " scope " << scope << " level " << level << " note " << kindTable.getNote( kindTable.currentScope() - 1 ).level << endl );
    101103        pair< KindTable::iterator, bool > ret = kindTable.insertAt( scope, identifier, kind );
    102104        if ( ! ret.second ) ret.first->second = kind;           // exists => update
  • src/Parser/TypedefTable.h

    r92355883 r2a301ff  
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Feb 15 08:06:37 2020
    13 // Update Count     : 117
     12// Last Modified On : Wed Jul 12 06:09:37 2023
     13// Update Count     : 118
    1414//
    1515
     
    2121
    2222class TypedefTable {
    23         struct Note { size_t level; bool forall; };
     23        struct Note {
     24                size_t level;
     25                bool forall;
     26        };
    2427        typedef ScopedMap< std::string, int, Note > KindTable;
    2528        KindTable kindTable;
     
    3134        bool existsCurr( const std::string & identifier ) const;
    3235        int isKind( const std::string & identifier ) const;
    33         void makeTypedef( const std::string & name, int kind );
    34         void makeTypedef( const std::string & name );
     36        void makeTypedef( const std::string & name, int kind, const char * );
     37        void makeTypedef( const std::string & name, const char * );
    3538        void addToScope( const std::string & identifier, int kind, const char * );
    3639        void addToEnclosingScope( const std::string & identifier, int kind, const char * );
  • src/Parser/parser.yy

    r92355883 r2a301ff  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jun 17 18:53:24 2023
    13 // Update Count     : 6347
     12// Last Modified On : Tue Jul 18 22:51:30 2023
     13// Update Count     : 6391
    1414//
    1515
     
    385385%type<str> string_literal_list
    386386
    387 %type<enum_hiding> hide_opt                                     visible_hide_opt
     387%type<enum_hiding> hide_opt                             visible_hide_opt
    388388
    389389// expressions
    390390%type<expr> constant
    391 %type<expr> tuple                                                       tuple_expression_list
     391%type<expr> tuple                                               tuple_expression_list
    392392%type<oper> ptrref_operator                             unary_operator                          assignment_operator                     simple_assignment_operator      compound_assignment_operator
    393393%type<expr> primary_expression                  postfix_expression                      unary_expression
    394 %type<expr> cast_expression_list                        cast_expression                         exponential_expression          multiplicative_expression       additive_expression
    395 %type<expr> shift_expression                            relational_expression           equality_expression
     394%type<expr> cast_expression_list                cast_expression                         exponential_expression          multiplicative_expression       additive_expression
     395%type<expr> shift_expression                    relational_expression           equality_expression
    396396%type<expr> AND_expression                              exclusive_OR_expression         inclusive_OR_expression
    397397%type<expr> logical_AND_expression              logical_OR_expression
    398398%type<expr> conditional_expression              constant_expression                     assignment_expression           assignment_expression_opt
    399 %type<expr> comma_expression                            comma_expression_opt
    400 %type<expr> argument_expression_list_opt        argument_expression_list        argument_expression                     default_initializer_opt
     399%type<expr> comma_expression                    comma_expression_opt
     400%type<expr> argument_expression_list_opt argument_expression_list       argument_expression                     default_initializer_opt
    401401%type<ifctl> conditional_declaration
    402 %type<forctl> for_control_expression            for_control_expression_list
     402%type<forctl> for_control_expression    for_control_expression_list
    403403%type<oper> upupeq updown updowneq downupdowneq
    404404%type<expr> subrange
    405405%type<decl> asm_name_opt
    406 %type<expr> asm_operands_opt                            asm_operands_list                       asm_operand
     406%type<expr> asm_operands_opt                    asm_operands_list                       asm_operand
    407407%type<labels> label_list
    408408%type<expr> asm_clobbers_list_opt
     
    412412
    413413// statements
    414 %type<stmt> statement                                           labeled_statement                       compound_statement
     414%type<stmt> statement                                   labeled_statement                       compound_statement
    415415%type<stmt> statement_decl                              statement_decl_list                     statement_list_nodecl
    416416%type<stmt> selection_statement                 if_statement
    417 %type<clause> switch_clause_list_opt            switch_clause_list
     417%type<clause> switch_clause_list_opt    switch_clause_list
    418418%type<expr> case_value
    419 %type<clause> case_clause                               case_value_list                         case_label                                      case_label_list
     419%type<clause> case_clause                               case_value_list                         case_label      case_label_list
    420420%type<stmt> iteration_statement                 jump_statement
    421 %type<stmt> expression_statement                        asm_statement
     421%type<stmt> expression_statement                asm_statement
    422422%type<stmt> with_statement
    423423%type<expr> with_clause_opt
     
    427427%type<stmt> mutex_statement
    428428%type<expr> when_clause                                 when_clause_opt                         waitfor         waituntil               timeout
    429 %type<stmt> waitfor_statement                           waituntil_statement
     429%type<stmt> waitfor_statement                   waituntil_statement
    430430%type<wfs> wor_waitfor_clause
    431431%type<wucn> waituntil_clause                    wand_waituntil_clause       wor_waituntil_clause
     
    601601// around the list separator.
    602602//
    603 //  int f( forall(T) T (*f1) T , forall( S ) S (*f2)( S ) );
     603//  XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
    604604//      push               pop   push                   pop
    605605
     
    689689        // | RESUME '(' comma_expression ')' compound_statement
    690690        //      { SemanticError( yylloc, "Resume expression is currently unimplemented." ); $$ = nullptr; }
    691         | IDENTIFIER IDENTIFIER                                                         // invalid syntax rules
     691        | IDENTIFIER IDENTIFIER                                                         // invalid syntax rule
    692692                { IdentifierBeforeIdentifier( *$1.str, *$2.str, "n expression" ); $$ = nullptr; }
    693         | IDENTIFIER type_qualifier                                                     // invalid syntax rules
     693        | IDENTIFIER type_qualifier                                                     // invalid syntax rule
    694694                { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; }
    695         | IDENTIFIER storage_class                                                      // invalid syntax rules
     695        | IDENTIFIER storage_class                                                      // invalid syntax rule
    696696                { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; }
    697         | IDENTIFIER basic_type_name                                            // invalid syntax rules
     697        | IDENTIFIER basic_type_name                                            // invalid syntax rule
    698698                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    699         | IDENTIFIER TYPEDEFname                                                        // invalid syntax rules
     699        | IDENTIFIER TYPEDEFname                                                        // invalid syntax rule
    700700                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    701         | IDENTIFIER TYPEGENname                                                        // invalid syntax rules
     701        | IDENTIFIER TYPEGENname                                                        // invalid syntax rule
    702702                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    703703        ;
     
    12751275        | DEFAULT ':'                                                           { $$ = new ClauseNode( build_default( yylloc ) ); }
    12761276                // A semantic check is required to ensure only one default clause per switch/choose statement.
    1277         | DEFAULT error                                                                         //  invalid syntax rules
     1277        | DEFAULT error                                                                         //  invalid syntax rule
    12781278                { SemanticError( yylloc, "syntax error, colon missing after default." ); $$ = nullptr; }
    12791279        ;
     
    14051405                        else { SemanticError( yylloc, MISSING_HIGH ); $$ = nullptr; }
    14061406                }
    1407         | comma_expression updowneq comma_expression '~' '@' // CFA, invalid syntax rules
     1407        | comma_expression updowneq comma_expression '~' '@' // CFA, invalid syntax rule
    14081408                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1409         | '@' updowneq '@'                                                                      // CFA, invalid syntax rules
     1409        | '@' updowneq '@'                                                                      // CFA, invalid syntax rule
    14101410                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1411         | '@' updowneq comma_expression '~' '@'                         // CFA, invalid syntax rules
     1411        | '@' updowneq comma_expression '~' '@'                         // CFA, invalid syntax rule
    14121412                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1413         | comma_expression updowneq '@' '~' '@'                         // CFA, invalid syntax rules
     1413        | comma_expression updowneq '@' '~' '@'                         // CFA, invalid syntax rule
    14141414                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    1415         | '@' updowneq '@' '~' '@'                                                      // CFA, invalid syntax rules
     1415        | '@' updowneq '@' '~' '@'                                                      // CFA, invalid syntax rule
    14161416                { SemanticError( yylloc, MISSING_ANON_FIELD ); $$ = nullptr; }
    14171417
     
    14341434                        else $$ = forCtrl( yylloc, $3, $1, $3->clone(), $4, nullptr, NEW_ONE );
    14351435                }
    1436         | comma_expression ';' '@' updowneq '@'                         // CFA, invalid syntax rules
     1436        | comma_expression ';' '@' updowneq '@'                         // CFA, invalid syntax rule
    14371437                { SemanticError( yylloc, "syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    14381438
    14391439        | comma_expression ';' comma_expression updowneq comma_expression '~' comma_expression // CFA
    14401440                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), $7 ); }
    1441         | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, invalid syntax rules
     1441        | comma_expression ';' '@' updowneq comma_expression '~' comma_expression // CFA, invalid syntax rule
    14421442                {
    14431443                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     
    14521452        | comma_expression ';' comma_expression updowneq comma_expression '~' '@' // CFA
    14531453                { $$ = forCtrl( yylloc, $3, $1, UPDOWN( $4, $3->clone(), $5 ), $4, UPDOWN( $4, $5->clone(), $3->clone() ), nullptr ); }
    1454         | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, invalid syntax rules
     1454        | comma_expression ';' '@' updowneq comma_expression '~' '@' // CFA, invalid syntax rule
    14551455                {
    14561456                        if ( $4 == OperKinds::LThan || $4 == OperKinds::LEThan ) { SemanticError( yylloc, MISSING_LOW ); $$ = nullptr; }
     
    15111511                        else $$ = forCtrl( yylloc, $1, $2, $3, nullptr, nullptr );
    15121512                }
    1513         | declaration '@' updowneq '@' '~' '@'                          // CFA, invalid syntax rules
     1513        | declaration '@' updowneq '@' '~' '@'                          // CFA, invalid syntax rule
    15141514                { SemanticError( yylloc, "syntax error, missing low/high value for up/down-to range so index is uninitialized." ); $$ = nullptr; }
    15151515
     
    16661666                { $$ = build_waitfor_timeout( yylloc, $1, $3, $4, maybe_build_compound( yylloc, $5 ) ); }
    16671667        // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    1668         | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // invalid syntax rules
     1668        | wor_waitfor_clause wor when_clause_opt timeout statement wor ELSE statement // invalid syntax rule
    16691669                { SemanticError( yylloc, "syntax error, else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    16701670        | wor_waitfor_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
     
    17081708        | wor_waituntil_clause wor when_clause_opt ELSE statement
    17091709                { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_else( yylloc, $3, maybe_build_compound( yylloc, $5 ) ) ); }
    1710         | wor_waituntil_clause wor when_clause_opt timeout statement    %prec THEN
    1711                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1, build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ) ); }
    1712         // "else" must be conditional after timeout or timeout is never triggered (i.e., it is meaningless)
    1713         | wor_waituntil_clause wor when_clause_opt timeout statement wor ELSE statement // invalid syntax rules
    1714                 { SemanticError( yylloc, "syntax error, else clause must be conditional after timeout or timeout never triggered." ); $$ = nullptr; }
    1715         | wor_waituntil_clause wor when_clause_opt timeout statement wor when_clause ELSE statement
    1716                 { $$ = new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::LEFT_OR, $1,
    1717                 new ast::WaitUntilStmt::ClauseNode( ast::WaitUntilStmt::ClauseNode::Op::OR,
    1718                     build_waituntil_timeout( yylloc, $3, $4, maybe_build_compound( yylloc, $5 ) ),
    1719                     build_waituntil_else( yylloc, $7, maybe_build_compound( yylloc, $9 ) ) ) ); }
    17201710        ;
    17211711
    17221712waituntil_statement:
    17231713        wor_waituntil_clause                                                            %prec THEN
    1724                 // SKULLDUGGERY: create an empty compound statement to test parsing of waituntil statement.
    1725                 {
    1726             $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) );
    1727             // $$ = new StatementNode( build_compound( yylloc, nullptr ) );
    1728         }
     1714                { $$ = new StatementNode( build_waituntil_stmt( yylloc, $1 ) ); }
    17291715        ;
    17301716
     
    18681854
    18691855KR_parameter_list:
    1870         push c_declaration pop ';'
    1871                 { $$ = $2; }
    1872         | KR_parameter_list push c_declaration pop ';'
    1873                 { $$ = $1->appendList( $3 ); }
     1856        c_declaration ';'
     1857                { $$ = $1; }
     1858        | KR_parameter_list c_declaration ';'
     1859                { $$ = $1->appendList( $2 ); }
    18741860        ;
    18751861
     
    20071993        TYPEDEF cfa_variable_specifier
    20081994                {
    2009                         typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname, "1" );
     1995                        typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname, "cfa_typedef_declaration 1" );
    20101996                        $$ = $2->addTypedef();
    20111997                }
    20121998        | TYPEDEF cfa_function_specifier
    20131999                {
    2014                         typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname, "2" );
     2000                        typedefTable.addToEnclosingScope( *$2->name, TYPEDEFname, "cfa_typedef_declaration 2" );
    20152001                        $$ = $2->addTypedef();
    20162002                }
    20172003        | cfa_typedef_declaration pop ',' push identifier
    20182004                {
    2019                         typedefTable.addToEnclosingScope( *$5, TYPEDEFname, "3" );
     2005                        typedefTable.addToEnclosingScope( *$5, TYPEDEFname, "cfa_typedef_declaration 3" );
    20202006                        $$ = $1->appendList( $1->cloneType( $5 ) );
    20212007                }
     
    20282014        TYPEDEF type_specifier declarator
    20292015                {
    2030                         typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "4" );
     2016                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "typedef_declaration 1" );
    20312017                        if ( $2->type->forall || ($2->type->kind == TypeData::Aggregate && $2->type->aggregate.params) ) {
    20322018                                SemanticError( yylloc, "forall qualifier in typedef is currently unimplemented." ); $$ = nullptr;
    20332019                        } else $$ = $3->addType( $2 )->addTypedef(); // watchout frees $2 and $3
    20342020                }
    2035         | typedef_declaration pop ',' push declarator
    2036                 {
    2037                         typedefTable.addToEnclosingScope( *$5->name, TYPEDEFname, "5" );
    2038                         $$ = $1->appendList( $1->cloneBaseType( $5 )->addTypedef() );
     2021        | typedef_declaration ',' declarator
     2022                {
     2023                        typedefTable.addToEnclosingScope( *$3->name, TYPEDEFname, "typedef_declaration 2" );
     2024                        $$ = $1->appendList( $1->cloneBaseType( $3 )->addTypedef() );
    20392025                }
    20402026        | type_qualifier_list TYPEDEF type_specifier declarator // remaining OBSOLESCENT (see 2 )
     
    20522038                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
    20532039                }
    2054         | typedef_expression pop ',' push identifier '=' assignment_expression
     2040        | typedef_expression ',' identifier '=' assignment_expression
    20552041                {
    20562042                        SemanticError( yylloc, "TYPEDEF expression is deprecated, use typeof(...) instead." ); $$ = nullptr;
     
    24652451        | aggregate_key attribute_list_opt identifier
    24662452                {
    2467                         typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
     2453                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname, "aggregate_type: 1" );
    24682454                        forall = false;                                                         // reset
    24692455                }
     
    24742460        | aggregate_key attribute_list_opt TYPEDEFname          // unqualified type name
    24752461                {
    2476                         typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
     2462                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname, "aggregate_type: 2" );
    24772463                        forall = false;                                                         // reset
    24782464                }
     
    24842470        | aggregate_key attribute_list_opt TYPEGENname          // unqualified type name
    24852471                {
    2486                         typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname ); // create typedef
     2472                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname, "aggregate_type: 3" );
    24872473                        forall = false;                                                         // reset
    24882474                }
     
    25052491        aggregate_key attribute_list_opt identifier
    25062492                {
    2507                         typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname );
     2493                        typedefTable.makeTypedef( *$3, forall || typedefTable.getEnclForall() ? TYPEGENname : TYPEDEFname, "aggregate_type_nobody" );
    25082494                        forall = false;                                                         // reset
    25092495                        $$ = DeclarationNode::newAggregate( $1, $3, nullptr, nullptr, false )->addQualifiers( $2 );
     
    26802666        ENUM attribute_list_opt '{' enumerator_list comma_opt '}'
    26812667                { $$ = DeclarationNode::newEnum( nullptr, $4, true, false )->addQualifiers( $2 ); }
     2668        | ENUM attribute_list_opt '!' '{' enumerator_list comma_opt '}' // invalid syntax rule
     2669                { SemanticError( yylloc, "syntax error, hiding '!' the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr; }
    26822670        | ENUM attribute_list_opt identifier
    2683                 { typedefTable.makeTypedef( *$3 ); }
     2671                { typedefTable.makeTypedef( *$3, "enum_type 1" ); }
    26842672          hide_opt '{' enumerator_list comma_opt '}'
    26852673                { $$ = DeclarationNode::newEnum( $3, $7, true, false, nullptr, $5 )->addQualifiers( $2 ); }
    2686         | ENUM attribute_list_opt typedef_name                          // unqualified type name
    2687           hide_opt '{' enumerator_list comma_opt '}'
     2674        | ENUM attribute_list_opt typedef_name hide_opt '{' enumerator_list comma_opt '}' // unqualified type name
    26882675                { $$ = DeclarationNode::newEnum( $3->name, $6, true, false, nullptr, $4 )->addQualifiers( $2 ); }
    26892676        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '{' enumerator_list comma_opt '}'
     
    26942681                        $$ = DeclarationNode::newEnum( nullptr, $7, true, true, $3 )->addQualifiers( $5 );
    26952682                }
     2683        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt '!' '{' enumerator_list comma_opt '}' // unqualified type name
     2684                { SemanticError( yylloc, "syntax error, hiding '!' the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr; }
     2685        | ENUM '(' ')' attribute_list_opt '{' enumerator_list comma_opt '}'
     2686                {
     2687                        $$ = DeclarationNode::newEnum( nullptr, $6, true, true )->addQualifiers( $4 );
     2688                }
     2689        | ENUM '(' ')' attribute_list_opt '!' '{' enumerator_list comma_opt '}' // invalid syntax rule
     2690                { SemanticError( yylloc, "syntax error, hiding '!' the enumerator names of an anonymous enumeration means the names are inaccessible." ); $$ = nullptr; }
    26962691        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt identifier attribute_list_opt
    26972692                {
     
    26992694                                SemanticError( yylloc, "syntax error, storage-class and CV qualifiers are not meaningful for enumeration constants, which are const." );
    27002695                        }
    2701                         typedefTable.makeTypedef( *$6 );
     2696                        typedefTable.makeTypedef( *$6, "enum_type 2" );
    27022697                }
    27032698          hide_opt '{' enumerator_list comma_opt '}'
     
    27052700                        $$ = DeclarationNode::newEnum( $6, $11, true, true, $3, $9 )->addQualifiers( $5 )->addQualifiers( $7 );
    27062701                }
    2707         | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt
    2708           hide_opt '{' enumerator_list comma_opt '}'
     2702        | ENUM '(' ')' attribute_list_opt identifier attribute_list_opt hide_opt '{' enumerator_list comma_opt '}'
     2703                {
     2704                        $$ = DeclarationNode::newEnum( $5, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );
     2705                }
     2706        | ENUM '(' cfa_abstract_parameter_declaration ')' attribute_list_opt typedef_name attribute_list_opt hide_opt '{' enumerator_list comma_opt '}'
    27092707                {
    27102708                        $$ = DeclarationNode::newEnum( $6->name, $10, true, true, $3, $8 )->addQualifiers( $5 )->addQualifiers( $7 );
     2709                }
     2710        | ENUM '(' ')' attribute_list_opt typedef_name attribute_list_opt hide_opt '{' enumerator_list comma_opt '}'
     2711                {
     2712                        $$ = DeclarationNode::newEnum( $5->name, $9, true, true, nullptr, $7 )->addQualifiers( $4 )->addQualifiers( $6 );
    27112713                }
    27122714        | enum_type_nobody
     
    27222724enum_type_nobody:                                                                               // enum - {...}
    27232725        ENUM attribute_list_opt identifier
    2724                 { typedefTable.makeTypedef( *$3 ); $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 ); }
     2726                {
     2727                        typedefTable.makeTypedef( *$3, "enum_type_nobody 1" );
     2728                        $$ = DeclarationNode::newEnum( $3, nullptr, false, false )->addQualifiers( $2 );
     2729                }
    27252730        | ENUM attribute_list_opt type_name
    2726                 { typedefTable.makeTypedef( *$3->type->symbolic.name ); $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 ); }
     2731                {
     2732                        typedefTable.makeTypedef( *$3->type->symbolic.name, "enum_type_nobody 2" );
     2733                        $$ = DeclarationNode::newEnum( $3->type->symbolic.name, nullptr, false, false )->addQualifiers( $2 );
     2734                }
    27272735        ;
    27282736
     
    27922800                { $$ = nullptr; }
    27932801        | parameter_list
    2794         | parameter_list pop ',' push ELLIPSIS
     2802        | parameter_list ',' ELLIPSIS
    27952803                { $$ = $1->addVarArgs(); }
    27962804        ;
     
    27992807        abstract_parameter_declaration
    28002808        | parameter_declaration
    2801         | parameter_list pop ',' push abstract_parameter_declaration
    2802                 { $$ = $1->appendList( $5 ); }
    2803         | parameter_list pop ',' push parameter_declaration
    2804                 { $$ = $1->appendList( $5 ); }
     2809        | parameter_list ',' abstract_parameter_declaration
     2810                { $$ = $1->appendList( $3 ); }
     2811        | parameter_list ',' parameter_declaration
     2812                { $$ = $1->appendList( $3 ); }
    28052813        ;
    28062814
     
    29692977        type_class identifier_or_type_name
    29702978                {
    2971                         typedefTable.addToScope( *$2, TYPEDEFname, "9" );
     2979                        typedefTable.addToScope( *$2, TYPEDEFname, "type_parameter 1" );
    29722980                        if ( $1 == ast::TypeDecl::Otype ) { SemanticError( yylloc, "otype keyword is deprecated, use T " ); }
    29732981                        if ( $1 == ast::TypeDecl::Dtype ) { SemanticError( yylloc, "dtype keyword is deprecated, use T &" ); }
     
    29772985                { $$ = DeclarationNode::newTypeParam( $1, $2 )->addTypeInitializer( $4 )->addAssertions( $5 ); }
    29782986        | identifier_or_type_name new_type_class
    2979                 { typedefTable.addToScope( *$1, TYPEDEFname, "9" ); }
     2987                { typedefTable.addToScope( *$1, TYPEDEFname, "type_parameter 2" ); }
    29802988          type_initializer_opt assertion_list_opt
    29812989                { $$ = DeclarationNode::newTypeParam( $2, $1 )->addTypeInitializer( $4 )->addAssertions( $5 ); }
    29822990        | '[' identifier_or_type_name ']'
    29832991                {
    2984                         typedefTable.addToScope( *$2, TYPEDIMname, "9" );
     2992                        typedefTable.addToScope( *$2, TYPEDIMname, "type_parameter 3" );
    29852993                        $$ = DeclarationNode::newTypeParam( ast::TypeDecl::Dimension, $2 );
    29862994                }
     
    30643072        identifier_or_type_name
    30653073                {
    3066                         typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "10" );
     3074                        typedefTable.addToEnclosingScope( *$1, TYPEDEFname, "type_declarator_name 1" );
    30673075                        $$ = DeclarationNode::newTypeDecl( $1, nullptr );
    30683076                }
    30693077        | identifier_or_type_name '(' type_parameter_list ')'
    30703078                {
    3071                         typedefTable.addToEnclosingScope( *$1, TYPEGENname, "11" );
     3079                        typedefTable.addToEnclosingScope( *$1, TYPEGENname, "type_declarator_name 2" );
    30723080                        $$ = DeclarationNode::newTypeDecl( $1, $3 );
    30733081                }
     
    31633171        | IDENTIFIER IDENTIFIER
    31643172                { IdentifierBeforeIdentifier( *$1.str, *$2.str, " declaration" ); $$ = nullptr; }
    3165         | IDENTIFIER type_qualifier                                                     // invalid syntax rules
     3173        | IDENTIFIER type_qualifier                                                     // invalid syntax rule
    31663174                { IdentifierBeforeType( *$1.str, "type qualifier" ); $$ = nullptr; }
    3167         | IDENTIFIER storage_class                                                      // invalid syntax rules
     3175        | IDENTIFIER storage_class                                                      // invalid syntax rule
    31683176                { IdentifierBeforeType( *$1.str, "storage class" ); $$ = nullptr; }
    3169         | IDENTIFIER basic_type_name                                            // invalid syntax rules
     3177        | IDENTIFIER basic_type_name                                            // invalid syntax rule
    31703178                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    3171         | IDENTIFIER TYPEDEFname                                                        // invalid syntax rules
     3179        | IDENTIFIER TYPEDEFname                                                        // invalid syntax rule
    31723180                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    3173         | IDENTIFIER TYPEGENname                                                        // invalid syntax rules
     3181        | IDENTIFIER TYPEGENname                                                        // invalid syntax rule
    31743182                { IdentifierBeforeType( *$1.str, "type" ); $$ = nullptr; }
    31753183        | external_function_definition
     
    34583466
    34593467variable_function:
    3460         '(' variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3461                 { $$ = $2->addParamList( $6 ); }
    3462         | '(' attribute_list variable_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3463                 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
     3468        '(' variable_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3469                { $$ = $2->addParamList( $5 ); }
     3470        | '(' attribute_list variable_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3471                { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); }
    34643472        | '(' variable_function ')'                                                     // redundant parenthesis
    34653473                { $$ = $2; }
     
    34813489
    34823490function_no_ptr:
    3483         paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3484                 { $$ = $1->addParamList( $4 ); }
    3485         | '(' function_ptr ')' '(' push parameter_type_list_opt pop ')'
    3486                 { $$ = $2->addParamList( $6 ); }
    3487         | '(' attribute_list function_ptr ')' '(' push parameter_type_list_opt pop ')'
    3488                 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
     3491        paren_identifier '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3492                { $$ = $1->addParamList( $3 ); }
     3493        | '(' function_ptr ')' '(' parameter_type_list_opt ')'
     3494                { $$ = $2->addParamList( $5 ); }
     3495        | '(' attribute_list function_ptr ')' '(' parameter_type_list_opt ')'
     3496                { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); }
    34893497        | '(' function_no_ptr ')'                                                       // redundant parenthesis
    34903498                { $$ = $2; }
     
    35353543        paren_identifier '(' identifier_list ')'                        // function_declarator handles empty parameter
    35363544                { $$ = $1->addIdList( $3 ); }
    3537         | '(' KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
    3538                 { $$ = $2->addParamList( $6 ); }
    3539         | '(' attribute_list KR_function_ptr ')' '(' push parameter_type_list_opt pop ')'
    3540                 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
     3545        | '(' KR_function_ptr ')' '(' parameter_type_list_opt ')'
     3546                { $$ = $2->addParamList( $5 ); }
     3547        | '(' attribute_list KR_function_ptr ')' '(' parameter_type_list_opt ')'
     3548                { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); }
    35413549        | '(' KR_function_no_ptr ')'                                            // redundant parenthesis
    35423550                { $$ = $2; }
     
    35823590                {
    35833591                        // hide type name in enclosing scope by variable name
    3584                         typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "ID" );
     3592                        typedefTable.addToEnclosingScope( *$1->name, IDENTIFIER, "paren_type" );
    35853593                }
    35863594        | '(' paren_type ')'
     
    36273635
    36283636variable_type_function:
    3629         '(' variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3630                 { $$ = $2->addParamList( $6 ); }
    3631         | '(' attribute_list variable_type_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3632                 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
     3637        '(' variable_type_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3638                { $$ = $2->addParamList( $5 ); }
     3639        | '(' attribute_list variable_type_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3640                { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); }
    36333641        | '(' variable_type_function ')'                                        // redundant parenthesis
    36343642                { $$ = $2; }
     
    36503658
    36513659function_type_no_ptr:
    3652         paren_type '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3653                 { $$ = $1->addParamList( $4 ); }
    3654         | '(' function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    3655                 { $$ = $2->addParamList( $6 ); }
    3656         | '(' attribute_list function_type_ptr ')' '(' push parameter_type_list_opt pop ')'
    3657                 { $$ = $3->addQualifiers( $2 )->addParamList( $7 ); }
     3660        paren_type '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3661                { $$ = $1->addParamList( $3 ); }
     3662        | '(' function_type_ptr ')' '(' parameter_type_list_opt ')'
     3663                { $$ = $2->addParamList( $5 ); }
     3664        | '(' attribute_list function_type_ptr ')' '(' parameter_type_list_opt ')'
     3665                { $$ = $3->addQualifiers( $2 )->addParamList( $6 ); }
    36583666        | '(' function_type_no_ptr ')'                                          // redundant parenthesis
    36593667                { $$ = $2; }
     
    37263734
    37273735identifier_parameter_function:
    3728         paren_identifier '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3729                 { $$ = $1->addParamList( $4 ); }
    3730         | '(' identifier_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3731                 { $$ = $2->addParamList( $6 ); }
     3736        paren_identifier '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3737                { $$ = $1->addParamList( $3 ); }
     3738        | '(' identifier_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3739                { $$ = $2->addParamList( $5 ); }
    37323740        | '(' identifier_parameter_function ')'                         // redundant parenthesis
    37333741                { $$ = $2; }
     
    37793787
    37803788type_parameter_function:
    3781         typedef_name '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3782                 { $$ = $1->addParamList( $4 ); }
    3783         | '(' type_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3784                 { $$ = $2->addParamList( $6 ); }
     3789        typedef_name '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3790                { $$ = $1->addParamList( $3 ); }
     3791        | '(' type_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3792                { $$ = $2->addParamList( $5 ); }
    37853793        ;
    37863794
     
    38293837
    38303838abstract_function:
    3831         '(' push parameter_type_list_opt pop ')'                        // empty parameter list OBSOLESCENT (see 3)
    3832                 { $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
    3833         | '(' abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3834                 { $$ = $2->addParamList( $6 ); }
     3839        '(' parameter_type_list_opt ')'                 // empty parameter list OBSOLESCENT (see 3)
     3840                { $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
     3841        | '(' abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3842                { $$ = $2->addParamList( $5 ); }
    38353843        | '(' abstract_function ')'                                                     // redundant parenthesis
    38363844                { $$ = $2; }
     
    39523960
    39533961abstract_parameter_function:
    3954         '(' push parameter_type_list_opt pop ')'                        // empty parameter list OBSOLESCENT (see 3)
    3955                 { $$ = DeclarationNode::newFunction( nullptr, nullptr, $3, nullptr ); }
    3956         | '(' abstract_parameter_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    3957                 { $$ = $2->addParamList( $6 ); }
     3962        '(' parameter_type_list_opt ')'                 // empty parameter list OBSOLESCENT (see 3)
     3963                { $$ = DeclarationNode::newFunction( nullptr, nullptr, $2, nullptr ); }
     3964        | '(' abstract_parameter_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     3965                { $$ = $2->addParamList( $5 ); }
    39583966        | '(' abstract_parameter_function ')'                           // redundant parenthesis
    39593967                { $$ = $2; }
     
    39924000// This pattern parses a declaration of an abstract variable, but does not allow "int ()" for a function pointer.
    39934001//
    3994 //              struct S {
    3995 //          int;
    3996 //          int *;
    3997 //          int [10];
    3998 //          int (*)();
    3999 //      };
     4002//   struct S {
     4003//       int;
     4004//       int *;
     4005//       int [10];
     4006//       int (*)();
     4007//   };
    40004008
    40014009variable_abstract_declarator:
     
    40314039
    40324040variable_abstract_function:
    4033         '(' variable_abstract_ptr ')' '(' push parameter_type_list_opt pop ')' // empty parameter list OBSOLESCENT (see 3)
    4034                 { $$ = $2->addParamList( $6 ); }
     4041        '(' variable_abstract_ptr ')' '(' parameter_type_list_opt ')' // empty parameter list OBSOLESCENT (see 3)
     4042                { $$ = $2->addParamList( $5 ); }
    40354043        | '(' variable_abstract_function ')'                            // redundant parenthesis
    40364044                { $$ = $2; }
Note: See TracChangeset for help on using the changeset viewer.