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

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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.