Changeset 82da9b8


Ignore:
Timestamp:
Aug 11, 2016, 2:38:02 PM (5 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
a2c5c17
Parents:
d2f5469 (diff), 27fefeb6 (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:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Files:
4 added
5 edited

Legend:

Unmodified
Added
Removed
  • doc/aaron_comp_II/comp_II.tex

    rd2f5469 r82da9b8  
    3737\setlength{\headsep}{0.25in}
    3838
     39\usepackage{caption}
     40\usepackage{subcaption}
     41
    3942%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    4043
     
    6265%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    6366
    64 \newcommand{\bigO}[1]{O\left( #1 \right)}
     67\newcommand{\bigO}[1]{O\!\left( #1 \right)}
    6568
    6669\begin{document}
     
    404407If cross-argument resolution dependencies cannot be completely eliminated, effective caching strategies to reduce duplicated work between equivalent argument-parameter matches in different combinations may mitigate the asymptotic defecits of the whole-combination matching approach.
    405408The final area of investigation is heuristics and algorithmic approaches to reduce the number of argument interpretations considered in the common case; if argument-parameter matches cannot be made independent, even small reductions in $i$ should yield significant reductions in the $i^{p+1}$ resolver runtime factor.
     409
    406410The discussion below presents a number of largely orthagonal axes for expression resolution algorithm design to be investigated, noting prior work where applicable.
     411Though some of the proposed improvements to the expression resolution algorithm are based on heuristics rather than asymptoticly superior algorithms, it should be noted that user programmers often employ idioms and other programming patterns to reduce the mental burden of producing correct code, and if these patterns can be identified and exploited by the compiler then the significant reduction in expression resolution time for common, idiomatic expressions should result in lower total compilation time even for code including difficult-to-resolve expressions that push the expression resolver to its theoretical worst case.
    407412
    408413\subsection{Argument-Parameter Matching}
    409 The first axis we consider is argument-parameter matching --- whether the type matching for a candidate function to a set of candidate arguments is directed by the argument types or the parameter types.
    410 
    411 \subsubsection{Argument-directed (``Bottom-up'')}
    412 Baker's algorithm for expression resolution\cite{Baker82} pre-computes argument candidates, from the leaves of the expression tree up.
     414The first axis for consideration is argument-parameter matching direction --- whether the type matching for a candidate function to a set of candidate arguments is directed by the argument types or the parameter types.
     415All expression resolution algorithms form a DAG of interpretations, some explicitly, some implicitly; in this DAG, arcs point from function-call interpretations to argument interpretations, as below:
     416\begin{figure}[h]
     417\centering
     418\begin{subfigure}[h]{2in}
     419\begin{lstlisting}
     420int *p;  // $p_i$
     421char *p; // $p_c$
     422
     423double *f(int*, int*); // $f_d$
     424char *f(char*, char*); // $f_c$
     425
     426f( f( p, p ), p );
     427\end{lstlisting}
     428\end{subfigure}~\begin{subfigure}[h]{2in}
     429\includegraphics{resolution_dag}
     430\end{subfigure}
     431\caption{Resolution DAG for a simple expression. Functions that do not have a valid argument matching are covered with an \textsf{X}.}\label{fig:res_dag}
     432\end{figure}
     433
     434Note that some interpretations may be part of more than one super-interpretation, as with $p_i$ in the bottom row, while some valid subexpression interpretations, like $f_d$ in the middle row, are not used in any interpretation of their containing expression.
     435
     436\subsubsection{Argument-directed (Bottom-up)}
     437Baker's algorithm for expression resolution~\cite{Baker82} pre-computes argument candidates, from the leaves of the expression tree up.
    413438For each candidate function, Baker attempts to match argument types to parameter types in sequence, failing if any parameter cannot be matched.
    414439
    415 Bilson\cite{Bilson03} similarly pre-computes argument candidates in the original \CFA compiler, but then explicitly enumerates all possible argument combinations for a multi-parameter function; these argument combinations are matched to the parameter types of the candidate function as a unit rather than individual arguments.
    416 This is less efficient than Baker's approach, as the same argument may be compared to the same parameter many times, but allows a more straightforward handling of polymorphic type binding and multiple return types.
    417 It is possible the efficiency losses here relative to Baker could be significantly reduced by application of memoization to the argument-parameter type comparisons.
    418 
    419 \subsubsection{Parameter-directed (``Top-down'')}
    420 Unlike Baker and Bilson, Cormack's algorithm\cite{Cormack81} requests argument candidates which match the type of each parameter of each candidate function, from the top-level expression down; memoization of these requests is presented as an optimization.
     440Bilson~\cite{Bilson03} similarly pre-computes argument candidates in the original \CFA compiler, but then explicitly enumerates all possible argument combinations for a multi-parameter function; these argument combinations are matched to the parameter types of the candidate function as a unit rather than individual arguments.
     441This approach is less efficient than Baker's approach, as the same argument may be compared to the same parameter many times, but allows a more straightforward handling of polymorphic type-binding and multiple return-types.
     442It is possible the efficiency losses here relative to Baker could be significantly reduced by keeping a memoized cache of argument-parameter type comparisons and reading previously-seen argument-parameter matches from this cache rather than recomputing them.
     443
     444\subsubsection{Parameter-directed (Top-down)}
     445Unlike Baker and Bilson, Cormack's algorithm~\cite{Cormack81} requests argument candidates that match the type of each parameter of each candidate function, from the top-level expression down; memoization of these requests is presented as an optimization.
    421446As presented, this algorithm requires the result of the expression to have a known type, though an algorithm based on Cormack's could reasonably request a candidate set of any return type, though such a set may be quite large.
    422447
    423448\subsubsection{Hybrid}
    424449This proposal includes the investigation of hybrid top-down/bottom-up argument-parameter matching.
    425 A reasonable hybrid approach might be to take a top-down approach when the expression to be matched is known to have a fixed type, and a bottom-up approach in untyped contexts.
    426 This may include switches from one type to another at different levels of the expression tree, for instance:
     450A reasonable hybrid approach might take a top-down approach when the expression to be matched has a fixed type, and a bottom-up approach in untyped contexts.
     451This approach may involve switching from one type to another at different levels of the expression tree.
     452For instance:
    427453\begin{lstlisting}
    428454forall(otype T)
     
    433459int x = f( f( '!' ) );
    434460\end{lstlisting}
    435 Here, the outer call to ©f© must have a return type that is (implicitly convertable to) ©int©, so a top-down approach could be used to select \textit{(1)} as the proper interpretation of ©f©. \textit{(1)}'s parameter ©x© here, however, is an unbound type variable, and can thus take a value of any complete type, providing no guidance for the choice of candidate for the inner ©f©. The leaf expression ©'!'©, however, gives us a zero-cost interpretation of the inner ©f© as \textit{(2)}, providing a minimal-cost expression resolution where ©T© is bound to ©void*©.
    436 
    437 Deciding when to switch between bottom-up and top-down resolution in a hybrid algorithm is a necessarily heuristic process, and though finding good heuristics for it is an open question, one reasonable approach might be to switch from top-down to bottom-up when the number of candidate functions exceeds some threshold.
     461The outer call to ©f© must have a return type that is (implicitly convertable to) ©int©, so a top-down approach is used to select \textit{(1)} as the proper interpretation of ©f©. \textit{(1)}'s parameter ©x©, however, is an unbound type variable, and can thus take a value of any complete type, providing no guidance for the choice of candidate for the inner call to ©f©. The leaf expression ©'!'©, however, determines a zero-cost interpretation of the inner ©f© as \textit{(2)}, providing a minimal-cost expression resolution where ©T© is bound to ©void*©.
     462
     463Deciding when to switch between bottom-up and top-down resolution to minimize wasted work in a hybrid algorithm is a necessarily heuristic process, and though finding good heuristics for which subexpressions to swich matching strategies on is an open question, one reasonable approach might be to set a threshold $t$ for the number of candidate functions, and to use top-down resolution for any subexpression with fewer than $t$ candidate functions, to minimize the number of unmatchable argument interpretations computed, but to use bottom-up resolution for any subexpression with at least $t$ candidate functions, to reduce duplication in argument interpretation computation between the different candidate functions.
     464
     465\subsubsection{Common Subexpression Caching}
     466With any of these argument-parameter approaches, it may be a useful optimization to cache the resolution results for common subexpressions; in Figure~\ref{fig:res_dag} this optimization would result in the list of interpretations $[p_c, p_i]$ for ©p© only being calculated once, and re-used for each of the three instances of ©p©.
    438467
    439468\subsection{Implicit Conversion Application}
    440 Baker's\cite{Baker82} and Cormack's\cite{Cormack81} algorithms do not account for implicit conversions\footnote{Baker does briefly comment on an approach for handling implicit conversions.}; both assume that there is at most one valid interpretation of a given expression for each distinct type.
     469Baker's and Cormack's algorithms do not account for implicit conversions\footnote{Baker does briefly comment on an approach for handling implicit conversions.}; both assume that there is at most one valid interpretation of a given expression for each distinct type.
    441470Integrating implicit conversion handling into their algorithms provides some choice of implementation approach.
    442471
  • src/Parser/ParseNode.h

    rd2f5469 r82da9b8  
    1010// Created On       : Sat May 16 13:28:16 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 10 13:08:46 2016
    13 // Update Count     : 436
     12// Last Modified On : Wed Aug 10 21:51:49 2016
     13// Update Count     : 437
    1414//
    1515
     
    415415Statement *build_while( ExpressionNode *ctl, StatementNode *stmt, bool kind = false );
    416416Statement *build_for( ForCtl *forctl, StatementNode *stmt );
     417Statement *build_branch( std::string identifier, BranchStmt::Type kind );
     418Statement *build_case( ExpressionNode *ctl );
     419Statement *build_default();
    417420
    418421//##############################################################################
  • src/Parser/StatementNode.cc

    rd2f5469 r82da9b8  
    1010// Created On       : Sat May 16 14:59:41 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 10 13:54:21 2016
    13 // Update Count     : 170
     12// Last Modified On : Wed Aug 10 22:08:38 2016
     13// Update Count     : 173
    1414//
    1515
     
    224224          case Case:
    225225                return new CaseStmt( labs, maybeBuild<Expression>(get_control() ), branches );
     226                assert( false );
    226227          case Default:
    227228                return new CaseStmt( labs, 0, branches, true );
     229                assert( false );
    228230          case While:
    229231                // assert( branches.size() == 1 );
     
    268270          case Break:
    269271                return new BranchStmt( labs, get_target(), BranchStmt::Break );
     272                assert( false );
    270273          case Continue:
    271274                return new BranchStmt( labs, get_target(), BranchStmt::Continue );
     275                assert( false );
    272276          case Return:
    273277          case Throw :
     
    314318        std::list<Statement *> branches;
    315319        buildList<Statement, StatementNode>( then_stmt, branches );
    316         assert( branches.size() >= 1 );
     320        assert( branches.size() == 1 );
    317321        thenb = branches.front();
    318322
     
    320324                std::list<Statement *> branches;
    321325                buildList<Statement, StatementNode>( else_stmt, branches );
    322                 assert( branches.size() >= 1 );
     326                assert( branches.size() == 1 );
    323327                elseb = branches.front();
    324328        } // if
     
    329333        std::list<Statement *> branches;
    330334        buildList<Statement, StatementNode>( stmt, branches );
    331         assert( branches.size() >= 1 );
     335        assert( branches.size() >= 0 );                                         // size == 0 for switch (...) {}, i.e., no declaration or statements
    332336        return new SwitchStmt( noLabels, maybeBuild<Expression>(ctl), branches );
     337}
     338Statement *build_case( ExpressionNode *ctl ) {
     339        std::list<Statement *> branches;
     340        buildList<Statement, StatementNode>( nullptr, branches );
     341        return new CaseStmt( noLabels, maybeBuild<Expression>(ctl), branches );
     342}
     343Statement *build_default() {
     344        std::list<Statement *> branches;
     345        return new CaseStmt( noLabels, nullptr, branches, true );
    333346}
    334347
     
    360373        delete forctl;
    361374        return new ForStmt( noLabels, init, cond, incr, branches.front() );
     375}
     376
     377Statement *build_branch( std::string identifier, BranchStmt::Type kind ) {
     378        return new BranchStmt( noLabels, identifier, kind );
    362379}
    363380
  • src/Parser/parser.cc

    rd2f5469 r82da9b8  
    10351035     657,   658,   659,   660,   661,   662,   663,   673,   680,   682,
    10361036     692,   693,   698,   700,   706,   708,   712,   713,   718,   723,
    1037      727,   730,   733,   743,   746,   758,   759,   761,   765,   767,
    1038      771,   772,   777,   778,   782,   787,   788,   792,   794,   800,
    1039      801,   805,   807,   809,   811,   817,   818,   822,   824,   829,
    1040      831,   833,   838,   840,   845,   847,   851,   854,   858,   861,
     1037     726,   728,   730,   740,   742,   753,   754,   756,   760,   762,
     1038     766,   767,   772,   773,   777,   782,   783,   787,   789,   795,
     1039     796,   800,   802,   804,   806,   812,   813,   817,   819,   824,
     1040     826,   828,   833,   835,   840,   843,   847,   851,   856,   860,
    10411041     865,   867,   871,   873,   880,   882,   884,   893,   895,   897,
    10421042     899,   901,   906,   908,   910,   912,   917,   930,   931,   936,
     
    57145714
    57155715/* Line 1806 of yacc.c  */
    5716 #line 726 "parser.yy"
     5716#line 725 "parser.yy"
    57175717    { (yyval.sn) = new StatementNode2( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); }
    57185718    break;
     
    57215721
    57225722/* Line 1806 of yacc.c  */
     5723#line 727 "parser.yy"
     5724    { (yyval.sn) = new StatementNode2( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); }
     5725    break;
     5726
     5727  case 151:
     5728
     5729/* Line 1806 of yacc.c  */
    57235730#line 729 "parser.yy"
    5724     { (yyval.sn) = new StatementNode2( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); }
    5725     break;
    5726 
    5727   case 151:
    5728 
    5729 /* Line 1806 of yacc.c  */
    5730 #line 732 "parser.yy"
    57315731    { (yyval.sn) = new StatementNode2( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
    57325732    break;
     
    57355735
    57365736/* Line 1806 of yacc.c  */
    5737 #line 734 "parser.yy"
     5737#line 731 "parser.yy"
    57385738    {
    57395739                        StatementNode *sw = new StatementNode2( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
     
    57505750
    57515751/* Line 1806 of yacc.c  */
    5752 #line 745 "parser.yy"
     5752#line 741 "parser.yy"
    57535753    { (yyval.sn) = new StatementNode2( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
    57545754    break;
     
    57575757
    57585758/* Line 1806 of yacc.c  */
    5759 #line 747 "parser.yy"
     5759#line 743 "parser.yy"
    57605760    {
    5761                         //StatementNode *sw = new StatementNode( StatementNode::Switch, $3, $8 );
    57625761                        StatementNode *sw = new StatementNode2( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
    57635762                        (yyval.sn) = (yyvsp[(7) - (9)].decl) != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( (yyvsp[(7) - (9)].decl) ))->set_link( sw )) ) : sw;
     
    57685767
    57695768/* Line 1806 of yacc.c  */
    5770 #line 758 "parser.yy"
     5769#line 753 "parser.yy"
    57715770    { (yyval.en) = (yyvsp[(1) - (1)].en); }
    57725771    break;
     
    57755774
    57765775/* Line 1806 of yacc.c  */
     5776#line 755 "parser.yy"
     5777    { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
     5778    break;
     5779
     5780  case 158:
     5781
     5782/* Line 1806 of yacc.c  */
    57775783#line 760 "parser.yy"
    5778     { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    5779     break;
    5780 
    5781   case 158:
    5782 
    5783 /* Line 1806 of yacc.c  */
    5784 #line 765 "parser.yy"
    57855784    { (yyval.sn) = new StatementNode( StatementNode::Case, (yyvsp[(1) - (1)].en), 0 ); }
    57865785    break;
     
    57895788
    57905789/* Line 1806 of yacc.c  */
     5790#line 762 "parser.yy"
     5791    { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_link( new StatementNode( StatementNode::Case, (yyvsp[(3) - (3)].en), 0 ) ) ); }
     5792    break;
     5793
     5794  case 160:
     5795
     5796/* Line 1806 of yacc.c  */
     5797#line 766 "parser.yy"
     5798    { (yyval.sn) = (yyvsp[(2) - (3)].sn); }
     5799    break;
     5800
     5801  case 161:
     5802
     5803/* Line 1806 of yacc.c  */
    57915804#line 767 "parser.yy"
    5792     { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_link( new StatementNode( StatementNode::Case, (yyvsp[(3) - (3)].en), 0 ) ) ); }
    5793     break;
    5794 
    5795   case 160:
    5796 
    5797 /* Line 1806 of yacc.c  */
    5798 #line 771 "parser.yy"
    5799     { (yyval.sn) = (yyvsp[(2) - (3)].sn); }
    5800     break;
    5801 
    5802   case 161:
    5803 
    5804 /* Line 1806 of yacc.c  */
    5805 #line 772 "parser.yy"
    58065805    { (yyval.sn) = new StatementNode( StatementNode::Default ); }
    58075806    break;
     
    58105809
    58115810/* Line 1806 of yacc.c  */
    5812 #line 778 "parser.yy"
     5811#line 773 "parser.yy"
    58135812    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_link( (yyvsp[(2) - (2)].sn) )); }
    58145813    break;
     
    58175816
    58185817/* Line 1806 of yacc.c  */
     5818#line 777 "parser.yy"
     5819    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); }
     5820    break;
     5821
     5822  case 165:
     5823
     5824/* Line 1806 of yacc.c  */
    58195825#line 782 "parser.yy"
     5826    { (yyval.sn) = 0; }
     5827    break;
     5828
     5829  case 167:
     5830
     5831/* Line 1806 of yacc.c  */
     5832#line 788 "parser.yy"
    58205833    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); }
    58215834    break;
    58225835
    5823   case 165:
    5824 
    5825 /* Line 1806 of yacc.c  */
    5826 #line 787 "parser.yy"
     5836  case 168:
     5837
     5838/* Line 1806 of yacc.c  */
     5839#line 790 "parser.yy"
     5840    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(3) - (3)].sn) ) ) ) ); }
     5841    break;
     5842
     5843  case 169:
     5844
     5845/* Line 1806 of yacc.c  */
     5846#line 795 "parser.yy"
    58275847    { (yyval.sn) = 0; }
    58285848    break;
    58295849
    5830   case 167:
    5831 
    5832 /* Line 1806 of yacc.c  */
    5833 #line 793 "parser.yy"
    5834     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); }
    5835     break;
    5836 
    5837   case 168:
    5838 
    5839 /* Line 1806 of yacc.c  */
    5840 #line 795 "parser.yy"
    5841     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(3) - (3)].sn) ) ) ) ); }
    5842     break;
    5843 
    5844   case 169:
    5845 
    5846 /* Line 1806 of yacc.c  */
    5847 #line 800 "parser.yy"
     5850  case 171:
     5851
     5852/* Line 1806 of yacc.c  */
     5853#line 801 "parser.yy"
     5854    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); }
     5855    break;
     5856
     5857  case 172:
     5858
     5859/* Line 1806 of yacc.c  */
     5860#line 803 "parser.yy"
     5861    { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new CompoundStmtNode( (StatementNode *)mkList( (*(yyvsp[(2) - (3)].sn), *(yyvsp[(3) - (3)].sn) ) ) ) ); }
     5862    break;
     5863
     5864  case 173:
     5865
     5866/* Line 1806 of yacc.c  */
     5867#line 805 "parser.yy"
     5868    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); }
     5869    break;
     5870
     5871  case 174:
     5872
     5873/* Line 1806 of yacc.c  */
     5874#line 807 "parser.yy"
     5875    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_link( (yyvsp[(2) - (4)].sn)->append_last_case( new CompoundStmtNode( (StatementNode *)mkList( (*(yyvsp[(3) - (4)].sn), *(yyvsp[(4) - (4)].sn) ) ) ) ) ) ); }
     5876    break;
     5877
     5878  case 175:
     5879
     5880/* Line 1806 of yacc.c  */
     5881#line 812 "parser.yy"
     5882    { (yyval.sn) = new StatementNode( StatementNode::Break ); }
     5883    break;
     5884
     5885  case 177:
     5886
     5887/* Line 1806 of yacc.c  */
     5888#line 818 "parser.yy"
    58485889    { (yyval.sn) = 0; }
    58495890    break;
    58505891
    5851   case 171:
    5852 
    5853 /* Line 1806 of yacc.c  */
    5854 #line 806 "parser.yy"
    5855     { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); }
    5856     break;
    5857 
    5858   case 172:
    5859 
    5860 /* Line 1806 of yacc.c  */
    5861 #line 808 "parser.yy"
    5862     { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new CompoundStmtNode( (StatementNode *)mkList( (*(yyvsp[(2) - (3)].sn), *(yyvsp[(3) - (3)].sn) ) ) ) ); }
    5863     break;
    5864 
    5865   case 173:
    5866 
    5867 /* Line 1806 of yacc.c  */
    5868 #line 810 "parser.yy"
    5869     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); }
    5870     break;
    5871 
    5872   case 174:
    5873 
    5874 /* Line 1806 of yacc.c  */
    5875 #line 812 "parser.yy"
    5876     { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (4)].sn)->set_link( (yyvsp[(2) - (4)].sn)->append_last_case( new CompoundStmtNode( (StatementNode *)mkList( (*(yyvsp[(3) - (4)].sn), *(yyvsp[(4) - (4)].sn) ) ) ) ) ) ); }
    5877     break;
    5878 
    5879   case 175:
    5880 
    5881 /* Line 1806 of yacc.c  */
    5882 #line 817 "parser.yy"
    5883     { (yyval.sn) = new StatementNode( StatementNode::Break ); }
    5884     break;
    5885 
    5886   case 177:
    5887 
    5888 /* Line 1806 of yacc.c  */
    5889 #line 823 "parser.yy"
     5892  case 178:
     5893
     5894/* Line 1806 of yacc.c  */
     5895#line 820 "parser.yy"
    58905896    { (yyval.sn) = 0; }
    58915897    break;
    58925898
    5893   case 178:
     5899  case 179:
    58945900
    58955901/* Line 1806 of yacc.c  */
    58965902#line 825 "parser.yy"
    5897     { (yyval.sn) = 0; }
    5898     break;
    5899 
    5900   case 179:
    5901 
    5902 /* Line 1806 of yacc.c  */
    5903 #line 830 "parser.yy"
    59045903    { (yyval.sn) = new StatementNode2( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
    59055904    break;
     
    59085907
    59095908/* Line 1806 of yacc.c  */
    5910 #line 832 "parser.yy"
     5909#line 827 "parser.yy"
    59115910    { (yyval.sn) = new StatementNode2( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn) ) ); }
    59125911    break;
     
    59155914
    59165915/* Line 1806 of yacc.c  */
     5916#line 829 "parser.yy"
     5917    { (yyval.sn) = new StatementNode2( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); }
     5918    break;
     5919
     5920  case 182:
     5921
     5922/* Line 1806 of yacc.c  */
    59175923#line 834 "parser.yy"
    5918     { (yyval.sn) = new StatementNode2( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); }
    5919     break;
    5920 
    5921   case 182:
    5922 
    5923 /* Line 1806 of yacc.c  */
    5924 #line 839 "parser.yy"
    59255924    { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); }
    59265925    break;
     
    59295928
    59305929/* Line 1806 of yacc.c  */
    5931 #line 841 "parser.yy"
     5930#line 836 "parser.yy"
    59325931    { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); }
    59335932    break;
     
    59365935
    59375936/* Line 1806 of yacc.c  */
     5937#line 842 "parser.yy"
     5938    { (yyval.sn) = new StatementNode2( build_branch( *(yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); }
     5939    break;
     5940
     5941  case 185:
     5942
     5943/* Line 1806 of yacc.c  */
    59385944#line 846 "parser.yy"
    5939     { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(2) - (3)].tok) ); }
    5940     break;
    5941 
    5942   case 185:
     5945    { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(3) - (4)].en) ); }
     5946    break;
     5947
     5948  case 186:
    59435949
    59445950/* Line 1806 of yacc.c  */
    59455951#line 850 "parser.yy"
    5946     { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(3) - (4)].en) ); }
    5947     break;
    5948 
    5949   case 186:
    5950 
    5951 /* Line 1806 of yacc.c  */
    5952 #line 853 "parser.yy"
    5953     { (yyval.sn) = new StatementNode( StatementNode::Continue ); }
     5952    { (yyval.sn) = new StatementNode2( build_branch( "", BranchStmt::Continue ) ); }
    59545953    break;
    59555954
     
    59575956
    59585957/* Line 1806 of yacc.c  */
    5959 #line 857 "parser.yy"
    5960     { (yyval.sn) = new StatementNode( StatementNode::Continue, (yyvsp[(2) - (3)].tok) ); }
     5958#line 855 "parser.yy"
     5959    { (yyval.sn) = new StatementNode2( build_branch( *(yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); delete (yyvsp[(2) - (3)].tok); }
    59615960    break;
    59625961
     
    59645963
    59655964/* Line 1806 of yacc.c  */
    5966 #line 860 "parser.yy"
    5967     { (yyval.sn) = new StatementNode( StatementNode::Break ); }
     5965#line 859 "parser.yy"
     5966    { (yyval.sn) = new StatementNode2( build_branch( "", BranchStmt::Break ) ); }
    59685967    break;
    59695968
     
    59725971/* Line 1806 of yacc.c  */
    59735972#line 864 "parser.yy"
    5974     { (yyval.sn) = new StatementNode( StatementNode::Break, (yyvsp[(2) - (3)].tok) ); }
     5973    { (yyval.sn) = new StatementNode2( build_branch( *(yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); delete (yyvsp[(2) - (3)].tok); }
    59755974    break;
    59765975
     
    91519150
    91529151/* Line 1806 of yacc.c  */
    9153 #line 9154 "Parser/parser.cc"
     9152#line 9153 "Parser/parser.cc"
    91549153      default: break;
    91559154    }
  • src/Parser/parser.yy

    rd2f5469 r82da9b8  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 10 13:09:53 2016
    13 // Update Count     : 1844
     12// Last Modified On : Wed Aug 10 23:03:05 2016
     13// Update Count     : 1846
    1414//
    1515
     
    723723        IF '(' comma_expression ')' statement                           %prec THEN
    724724                // explicitly deal with the shift/reduce conflict on if/else
    725                 //{ $$ = new StatementNode( StatementNode::If, $3, $5 ); }
    726725                { $$ = new StatementNode2( build_if( $3, $5, nullptr ) ); }
    727726        | IF '(' comma_expression ')' statement ELSE statement
    728                 //{ $$ = new StatementNode( StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7 )) ); }
    729727                { $$ = new StatementNode2( build_if( $3, $5, $7 ) ); }
    730728        | SWITCH '(' comma_expression ')' case_clause           // CFA
    731                 //{ $$ = new StatementNode( StatementNode::Switch, $3, $5 ); }
    732729                { $$ = new StatementNode2( build_switch( $3, $5 ) ); }
    733730        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
     
    742739                }
    743740        | CHOOSE '(' comma_expression ')' case_clause           // CFA
    744                 //{ $$ = new StatementNode( StatementNode::Switch, $3, $5 ); }
    745741                { $$ = new StatementNode2( build_switch( $3, $5 ) ); }
    746742        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA
    747743                {
    748                         //StatementNode *sw = new StatementNode( StatementNode::Switch, $3, $8 );
    749744                        StatementNode *sw = new StatementNode2( build_switch( $3, $8 ) );
    750745                        $$ = $7 != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( $7 ))->set_link( sw )) ) : sw;
     
    844839jump_statement:
    845840        GOTO IDENTIFIER ';'
    846                 { $$ = new StatementNode( StatementNode::Goto, $2 ); }
     841                //{ $$ = new StatementNode( StatementNode::Goto, $2 ); }
     842                { $$ = new StatementNode2( build_branch( *$2, BranchStmt::Goto ) ); }
    847843        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    848844                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    851847        | CONTINUE ';'
    852848                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    853                 { $$ = new StatementNode( StatementNode::Continue ); }
     849                //{ $$ = new StatementNode( StatementNode::Continue ); }
     850                { $$ = new StatementNode2( build_branch( "", BranchStmt::Continue ) ); }
    854851        | CONTINUE IDENTIFIER ';'                                                       // CFA, multi-level continue
    855852                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    856853                // the target of the transfer appears only at the start of an iteration statement.
    857                 { $$ = new StatementNode( StatementNode::Continue, $2 ); }
     854                //{ $$ = new StatementNode( StatementNode::Continue, $2 ); }
     855                { $$ = new StatementNode2( build_branch( *$2, BranchStmt::Continue ) ); delete $2; }
    858856        | BREAK ';'
    859857                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    860                 { $$ = new StatementNode( StatementNode::Break ); }
     858                //{ $$ = new StatementNode( StatementNode::Break ); }
     859                { $$ = new StatementNode2( build_branch( "", BranchStmt::Break ) ); }
    861860        | BREAK IDENTIFIER ';'                                                          // CFA, multi-level exit
    862861                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    863862                // the target of the transfer appears only at the start of an iteration statement.
    864                 { $$ = new StatementNode( StatementNode::Break, $2 ); }
     863                //{ $$ = new StatementNode( StatementNode::Break, $2 ); }
     864                { $$ = new StatementNode2( build_branch( *$2, BranchStmt::Break ) ); delete $2; }
    865865        | RETURN comma_expression_opt ';'
    866866                { $$ = new StatementNode( StatementNode::Return, $2, 0 ); }
Note: See TracChangeset for help on using the changeset viewer.