Changeset 3d26610 for src/Parser


Ignore:
Timestamp:
May 31, 2018, 4:05:01 PM (6 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, with_gc
Children:
b368dd8
Parents:
bd946e4
Message:

more push/pop updates

Location:
src/Parser
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • src/Parser/TypedefTable.cc

    rbd946e4 r3d26610  
    1010// Created On       : Sat May 16 15:20:13 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 22 08:40:01 2018
    13 // Update Count     : 121
     12// Last Modified On : Wed May 30 18:04:38 2018
     13// Update Count     : 148
    1414//
    1515
     
    2020#if 0
    2121#include <iostream>
    22 #define debugPrint( x ) cerr << x
     22#define debugPrint( code ) code
    2323#else
    24 #define debugPrint( x )
     24#define debugPrint( code )
    2525#endif
    2626
     
    2929TypedefTable::~TypedefTable() {
    3030        if ( ! SemanticErrorThrow && kindTable.currentScope() != 0 ) {
    31                 // std::cerr << "scope failure " << kindTable.currentScope() << endl;
     31                std::cerr << "scope failure " << kindTable.currentScope() << endl;
    3232        } // if
    3333} // TypedefTable::~TypedefTable
     
    5454void TypedefTable::makeTypedef( const string & name ) {
    5555        if ( ! typedefTable.exists( name ) ) {
    56                 typedefTable.addToEnclosingScope( name, TYPEDEFname );
     56                typedefTable.addToEnclosingScope( name, TYPEDEFname /*, "MTD"*/ );
    5757        } // if
    5858} // TypedefTable::makeTypedef
    5959
    60 void TypedefTable::addToEnclosingScope( const std::string & identifier, int kind ) {
     60void 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
     67void TypedefTable::addToEnclosingScope( const std::string & identifier, int kind /*, const char * locn*/ ) {
    6168        assert( kindTable.currentScope() >= 1 );
    6269        auto scope = kindTable.currentScope() - 1;
    63         debugPrint( "Adding " << identifier << " as kind " << kind << " scope " << scope << endl );
     70        debugPrint( cerr << "Adding2 at " /* << locn */ << " " << identifier << " as kind " << kind << " scope " << scope << endl );
    6471        auto ret = kindTable.insertAt( scope, identifier, kind );
    6572        if ( ! ret.second ) ret.first->second = kind;           // exists => update
     
    6875void TypedefTable::enterScope() {
    6976        kindTable.beginScope();
    70         debugPrint( "Entering scope " << kindTable.currentScope() << endl );
     77        debugPrint( cerr << "Entering scope " << kindTable.currentScope() << endl );
     78        debugPrint( print() );
    7179} // TypedefTable::enterScope
    7280
    7381void TypedefTable::leaveScope() {
    74         debugPrint( "Leaving scope " << kindTable.currentScope() << endl );
     82        debugPrint( cerr << "Leaving scope " << kindTable.currentScope() << endl );
     83        debugPrint( print() );
    7584        kindTable.endScope();
    7685} // TypedefTable::leaveScope
    7786
    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 // }
     87void 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}
    88103
    89104// Local Variables: //
  • src/Parser/TypedefTable.h

    rbd946e4 r3d26610  
    1010// Created On       : Sat May 16 15:24:36 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue May 22 08:39:29 2018
    13 // Update Count     : 77
     12// Last Modified On : Wed May 30 17:02:49 2018
     13// Update Count     : 82
    1414//
    1515
     
    3232        void changeKind( const std::string & identifier, int kind );
    3333        void makeTypedef( const std::string & name );
    34         void addToEnclosingScope( const std::string & identifier, int kind );
     34        void addToScope( const std::string & identifier, int kind /*, const char **/ );
     35        void addToEnclosingScope( const std::string & identifier, int kind /*, const char */ );
    3536
    3637        void enterScope();
    3738        void leaveScope();
     39
     40        void print( void ) const;
    3841}; // TypedefTable
    3942
  • src/Parser/parser.yy

    rbd946e4 r3d26610  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed May 30 20:29:03 2018
    13 // Update Count     : 3432
     12// Last Modified On : Thu May 31 15:11:40 2018
     13// Update Count     : 3444
    1414//
    1515
     
    265265%type<sn> statement                                             labeled_statement                       compound_statement
    266266%type<sn> statement_decl                                statement_decl_list                     statement_list_nodecl
    267 %type<sn> selection_statement
     267%type<sn> selection_statement                   if_statement
    268268%type<sn> switch_clause_list_opt                switch_clause_list
    269269%type<en> case_value
     
    404404//************************* Namespace Management ********************************
    405405
    406 // The grammar in the ANSI C standard is not strictly context-free, since it relies upon the distinct terminal symbols
    407 // "identifier", "TYPEDEFname", and "TYPEGENname" that are lexically identical.  While it is possible to write a purely
    408 // context-free grammar, such a grammar would obscure the relationship between syntactic and semantic constructs.
    409 // Hence, this grammar uses the ANSI style.
    410 //
    411 // Cforall compounds this problem by introducing type names local to the scope of a declaration (for instance, those
    412 // introduced through "forall" qualifiers), and by introducing "type generators" -- parameterized types.  This latter
    413 // type name creates a third class of identifiers that must be distinguished by the scanner.
    414 //
    415 // Since the scanner cannot distinguish among the different classes of identifiers without some context information, it
    416 // accesses a data structure (TypedefTable) to allow classification of an identifier that it has just read.  Semantic
    417 // actions during the parser update this data structure when the class of identifiers change.
    418 //
    419 // Because the Cforall language is block-scoped, an identifier can change its class in a local scope; it must revert to
    420 // its original class at the end of the block.  Since type names can be local to a particular declaration, each
    421 // declaration is itself a scope.  This requires distinguishing between type names that are local to the current
    422 // declaration scope and those that persist past the end of the declaration (i.e., names defined in "typedef" or "otype"
    423 // declarations).
    424 //
    425 // The non-terminals "push" and "pop" denote the opening and closing of scopes.  Every push must have a matching pop,
    426 // although it is regrettable the matching pairs do not always occur within the same rule.  These non-terminals may
    427 // appear in more contexts than strictly necessary from a semantic point of view.
     406// The C grammar is not context free because it relies on the distinct terminal symbols "identifier" and "TYPEDEFname",
     407// which are lexically identical.
     408//
     409//   typedef int foo; // identifier foo must now be scanned as TYPEDEFname
     410//   foo f;           // to allow it to appear in this context
     411//
     412// While it may be possible to write a purely context-free grammar, such a grammar would obscure the relationship
     413// between syntactic and semantic constructs.  Cforall compounds this problem by introducing type names local to the
     414// scope of a declaration (for instance, those introduced through "forall" qualifiers), and by introducing "type
     415// generators" -- parameterized types.  This latter type name creates a third class of identifiers, "TYPEGENname", which
     416// must be distinguished by the lexical scanner.
     417//
     418// Since the scanner cannot distinguish among the different classes of identifiers without some context information,
     419// there is a type table (typedefTable), which holds type names and identifiers that override type names, for each named
     420// scope. During parsing, semantic actions update the type table by adding new identifiers in the current scope. For
     421// each context that introduces a name scope, a new level is created in the type table and that level is popped on
     422// exiting the scope.  Since type names can be local to a particular declaration, each declaration is itself a scope.
     423// This requires distinguishing between type names that are local to the current declaration scope and those that
     424// persist past the end of the declaration (i.e., names defined in "typedef" or "otype" declarations).
     425//
     426// The non-terminals "push" and "pop" denote the opening and closing of named scopes. Every push has a matching pop in
     427// the production rule. There are multiple lists of declarations, where each declaration is a named scope, so pop/push
     428// around the list separator.
     429//
     430//  int f( forall(T) T (*f1) T , forall( S ) S (*f2)( S ) );
     431//      push               pop   push                   pop
    428432
    429433push:
     
    952956
    953957selection_statement:
    954         IF '(' push if_control_expression ')' statement pop             %prec THEN
    955                 // explicitly deal with the shift/reduce conflict on if/else
    956                 { $$ = new StatementNode( build_if( $4, $6, nullptr ) ); }
    957         | IF '(' push if_control_expression ')' statement ELSE statement pop
    958                 { $$ = new StatementNode( build_if( $4, $6, $8 ) ); }
     958                        // pop causes a S/R conflict without separating the IF statement into a non-terminal even after resolving
     959                        // the inherent S/R conflict with THEN/ELSE.
     960        push if_statement pop
     961                { $$ = $2; }
    959962        | SWITCH '(' comma_expression ')' case_clause
    960963                { $$ = new StatementNode( build_switch( true, $3, $5 ) ); }
     
    977980                }
    978981        ;
     982
     983if_statement:
     984        IF '(' if_control_expression ')' statement                      %prec THEN
     985                // explicitly deal with the shift/reduce conflict on if/else
     986                { $$ = new StatementNode( build_if( $3, $5, nullptr ) ); }
     987        | IF '(' if_control_expression ')' statement ELSE statement
     988                { $$ = new StatementNode( build_if( $3, $5, $7 ) ); }
     989        ;
     990
    979991
    980992if_control_expression:
     
    11721184
    11731185handler_clause:
    1174         handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop
    1175                 { $$ = new StatementNode( build_catch( $1, $5, $7, $9 ) ); }
    1176         | handler_clause handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop
    1177                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $6, $8, $10 ) ) ); }
     1186        handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop
     1187                { $$ = new StatementNode( build_catch( $1, $4, $6, $8 ) ); }
     1188        | handler_clause handler_key '(' push exception_declaration pop handler_predicate_opt ')' compound_statement pop
     1189                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $5, $7, $9 ) ) ); }
    11781190        ;
    11791191
Note: See TracChangeset for help on using the changeset viewer.