Changes in / [82da9b8:d2f5469]


Ignore:
Files:
4 deleted
5 edited

Legend:

Unmodified
Added
Removed
  • doc/aaron_comp_II/comp_II.tex

    r82da9b8 rd2f5469  
    3737\setlength{\headsep}{0.25in}
    3838
    39 \usepackage{caption}
    40 \usepackage{subcaption}
    41 
    4239%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    4340
     
    6562%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
    6663
    67 \newcommand{\bigO}[1]{O\!\left( #1 \right)}
     64\newcommand{\bigO}[1]{O\left( #1 \right)}
    6865
    6966\begin{document}
     
    407404If 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.
    408405The 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 
    410406The discussion below presents a number of largely orthagonal axes for expression resolution algorithm design to be investigated, noting prior work where applicable.
    411 Though 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.
    412407
    413408\subsection{Argument-Parameter Matching}
    414 The 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.
    415 All 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}
    420 int *p;  // $p_i$
    421 char *p; // $p_c$
    422 
    423 double *f(int*, int*); // $f_d$
    424 char *f(char*, char*); // $f_c$
    425 
    426 f( 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 
    434 Note 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)}
    437 Baker's algorithm for expression resolution~\cite{Baker82} pre-computes argument candidates, from the leaves of the expression tree up.
     409The 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'')}
     412Baker's algorithm for expression resolution\cite{Baker82} pre-computes argument candidates, from the leaves of the expression tree up.
    438413For each candidate function, Baker attempts to match argument types to parameter types in sequence, failing if any parameter cannot be matched.
    439414
    440 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.
    441 This 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.
    442 It 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)}
    445 Unlike 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.
     415Bilson\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.
     416This 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.
     417It 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'')}
     420Unlike 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.
    446421As 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.
    447422
    448423\subsubsection{Hybrid}
    449424This proposal includes the investigation of hybrid top-down/bottom-up argument-parameter matching.
    450 A 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.
    451 This approach may involve switching from one type to another at different levels of the expression tree.
    452 For instance:
     425A 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.
     426This may include switches from one type to another at different levels of the expression tree, for instance:
    453427\begin{lstlisting}
    454428forall(otype T)
     
    459433int x = f( f( '!' ) );
    460434\end{lstlisting}
    461 The 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 
    463 Deciding 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}
    466 With 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©.
     435Here, 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
     437Deciding 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.
    467438
    468439\subsection{Implicit Conversion Application}
    469 Baker'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.
     440Baker'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.
    470441Integrating implicit conversion handling into their algorithms provides some choice of implementation approach.
    471442
  • src/Parser/ParseNode.h

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

    r82da9b8 rd2f5469  
    1010// Created On       : Sat May 16 14:59:41 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 10 22:08:38 2016
    13 // Update Count     : 173
     12// Last Modified On : Wed Aug 10 13:54:21 2016
     13// Update Count     : 170
    1414//
    1515
     
    224224          case Case:
    225225                return new CaseStmt( labs, maybeBuild<Expression>(get_control() ), branches );
    226                 assert( false );
    227226          case Default:
    228227                return new CaseStmt( labs, 0, branches, true );
    229                 assert( false );
    230228          case While:
    231229                // assert( branches.size() == 1 );
     
    270268          case Break:
    271269                return new BranchStmt( labs, get_target(), BranchStmt::Break );
    272                 assert( false );
    273270          case Continue:
    274271                return new BranchStmt( labs, get_target(), BranchStmt::Continue );
    275                 assert( false );
    276272          case Return:
    277273          case Throw :
     
    318314        std::list<Statement *> branches;
    319315        buildList<Statement, StatementNode>( then_stmt, branches );
    320         assert( branches.size() == 1 );
     316        assert( branches.size() >= 1 );
    321317        thenb = branches.front();
    322318
     
    324320                std::list<Statement *> branches;
    325321                buildList<Statement, StatementNode>( else_stmt, branches );
    326                 assert( branches.size() == 1 );
     322                assert( branches.size() >= 1 );
    327323                elseb = branches.front();
    328324        } // if
     
    333329        std::list<Statement *> branches;
    334330        buildList<Statement, StatementNode>( stmt, branches );
    335         assert( branches.size() >= 0 );                                         // size == 0 for switch (...) {}, i.e., no declaration or statements
     331        assert( branches.size() >= 1 );
    336332        return new SwitchStmt( noLabels, maybeBuild<Expression>(ctl), branches );
    337 }
    338 Statement *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 }
    343 Statement *build_default() {
    344         std::list<Statement *> branches;
    345         return new CaseStmt( noLabels, nullptr, branches, true );
    346333}
    347334
     
    373360        delete forctl;
    374361        return new ForStmt( noLabels, init, cond, incr, branches.front() );
    375 }
    376 
    377 Statement *build_branch( std::string identifier, BranchStmt::Type kind ) {
    378         return new BranchStmt( noLabels, identifier, kind );
    379362}
    380363
  • src/Parser/parser.cc

    r82da9b8 rd2f5469  
    10351035     657,   658,   659,   660,   661,   662,   663,   673,   680,   682,
    10361036     692,   693,   698,   700,   706,   708,   712,   713,   718,   723,
    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,
     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,
    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 725 "parser.yy"
     5716#line 726 "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"
     5723#line 729 "parser.yy"
    57245724    { (yyval.sn) = new StatementNode2( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); }
    57255725    break;
     
    57285728
    57295729/* Line 1806 of yacc.c  */
    5730 #line 729 "parser.yy"
     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 731 "parser.yy"
     5737#line 734 "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 741 "parser.yy"
     5752#line 745 "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 743 "parser.yy"
     5759#line 747 "parser.yy"
    57605760    {
     5761                        //StatementNode *sw = new StatementNode( StatementNode::Switch, $3, $8 );
    57615762                        StatementNode *sw = new StatementNode2( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) );
    57625763                        (yyval.sn) = (yyvsp[(7) - (9)].decl) != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( (yyvsp[(7) - (9)].decl) ))->set_link( sw )) ) : sw;
     
    57675768
    57685769/* Line 1806 of yacc.c  */
    5769 #line 753 "parser.yy"
     5770#line 758 "parser.yy"
    57705771    { (yyval.en) = (yyvsp[(1) - (1)].en); }
    57715772    break;
     
    57745775
    57755776/* Line 1806 of yacc.c  */
    5776 #line 755 "parser.yy"
     5777#line 760 "parser.yy"
    57775778    { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); }
    57785779    break;
     
    57815782
    57825783/* Line 1806 of yacc.c  */
    5783 #line 760 "parser.yy"
     5784#line 765 "parser.yy"
    57845785    { (yyval.sn) = new StatementNode( StatementNode::Case, (yyvsp[(1) - (1)].en), 0 ); }
    57855786    break;
     
    57885789
    57895790/* Line 1806 of yacc.c  */
    5790 #line 762 "parser.yy"
     5791#line 767 "parser.yy"
    57915792    { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_link( new StatementNode( StatementNode::Case, (yyvsp[(3) - (3)].en), 0 ) ) ); }
    57925793    break;
     
    57955796
    57965797/* Line 1806 of yacc.c  */
    5797 #line 766 "parser.yy"
     5798#line 771 "parser.yy"
    57985799    { (yyval.sn) = (yyvsp[(2) - (3)].sn); }
    57995800    break;
     
    58025803
    58035804/* Line 1806 of yacc.c  */
    5804 #line 767 "parser.yy"
     5805#line 772 "parser.yy"
    58055806    { (yyval.sn) = new StatementNode( StatementNode::Default ); }
    58065807    break;
     
    58095810
    58105811/* Line 1806 of yacc.c  */
    5811 #line 773 "parser.yy"
     5812#line 778 "parser.yy"
    58125813    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_link( (yyvsp[(2) - (2)].sn) )); }
    58135814    break;
     
    58165817
    58175818/* Line 1806 of yacc.c  */
    5818 #line 777 "parser.yy"
     5819#line 782 "parser.yy"
    58195820    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); }
    58205821    break;
     
    58235824
    58245825/* Line 1806 of yacc.c  */
    5825 #line 782 "parser.yy"
     5826#line 787 "parser.yy"
    58265827    { (yyval.sn) = 0; }
    58275828    break;
     
    58305831
    58315832/* Line 1806 of yacc.c  */
    5832 #line 788 "parser.yy"
     5833#line 793 "parser.yy"
    58335834    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); }
    58345835    break;
     
    58375838
    58385839/* Line 1806 of yacc.c  */
    5839 #line 790 "parser.yy"
     5840#line 795 "parser.yy"
    58405841    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(3) - (3)].sn) ) ) ) ); }
    58415842    break;
     
    58445845
    58455846/* Line 1806 of yacc.c  */
    5846 #line 795 "parser.yy"
     5847#line 800 "parser.yy"
    58475848    { (yyval.sn) = 0; }
    58485849    break;
     
    58515852
    58525853/* Line 1806 of yacc.c  */
    5853 #line 801 "parser.yy"
     5854#line 806 "parser.yy"
    58545855    { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); }
    58555856    break;
     
    58585859
    58595860/* Line 1806 of yacc.c  */
    5860 #line 803 "parser.yy"
     5861#line 808 "parser.yy"
    58615862    { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new CompoundStmtNode( (StatementNode *)mkList( (*(yyvsp[(2) - (3)].sn), *(yyvsp[(3) - (3)].sn) ) ) ) ); }
    58625863    break;
     
    58655866
    58665867/* Line 1806 of yacc.c  */
    5867 #line 805 "parser.yy"
     5868#line 810 "parser.yy"
    58685869    { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); }
    58695870    break;
     
    58725873
    58735874/* Line 1806 of yacc.c  */
    5874 #line 807 "parser.yy"
     5875#line 812 "parser.yy"
    58755876    { (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) ) ) ) ) ) ); }
    58765877    break;
     
    58795880
    58805881/* Line 1806 of yacc.c  */
    5881 #line 812 "parser.yy"
     5882#line 817 "parser.yy"
    58825883    { (yyval.sn) = new StatementNode( StatementNode::Break ); }
    58835884    break;
     
    58865887
    58875888/* Line 1806 of yacc.c  */
    5888 #line 818 "parser.yy"
     5889#line 823 "parser.yy"
    58895890    { (yyval.sn) = 0; }
    58905891    break;
     
    58935894
    58945895/* Line 1806 of yacc.c  */
    5895 #line 820 "parser.yy"
     5896#line 825 "parser.yy"
    58965897    { (yyval.sn) = 0; }
    58975898    break;
     
    59005901
    59015902/* Line 1806 of yacc.c  */
    5902 #line 825 "parser.yy"
     5903#line 830 "parser.yy"
    59035904    { (yyval.sn) = new StatementNode2( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); }
    59045905    break;
     
    59075908
    59085909/* Line 1806 of yacc.c  */
    5909 #line 827 "parser.yy"
     5910#line 832 "parser.yy"
    59105911    { (yyval.sn) = new StatementNode2( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn) ) ); }
    59115912    break;
     
    59145915
    59155916/* Line 1806 of yacc.c  */
    5916 #line 829 "parser.yy"
     5917#line 834 "parser.yy"
    59175918    { (yyval.sn) = new StatementNode2( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); }
    59185919    break;
     
    59215922
    59225923/* Line 1806 of yacc.c  */
    5923 #line 834 "parser.yy"
     5924#line 839 "parser.yy"
    59245925    { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); }
    59255926    break;
     
    59285929
    59295930/* Line 1806 of yacc.c  */
    5930 #line 836 "parser.yy"
     5931#line 841 "parser.yy"
    59315932    { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); }
    59325933    break;
     
    59355936
    59365937/* Line 1806 of yacc.c  */
    5937 #line 842 "parser.yy"
    5938     { (yyval.sn) = new StatementNode2( build_branch( *(yyvsp[(2) - (3)].tok), BranchStmt::Goto ) ); }
     5938#line 846 "parser.yy"
     5939    { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(2) - (3)].tok) ); }
    59395940    break;
    59405941
     
    59425943
    59435944/* Line 1806 of yacc.c  */
    5944 #line 846 "parser.yy"
     5945#line 850 "parser.yy"
    59455946    { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(3) - (4)].en) ); }
    59465947    break;
     
    59495950
    59505951/* Line 1806 of yacc.c  */
    5951 #line 850 "parser.yy"
    5952     { (yyval.sn) = new StatementNode2( build_branch( "", BranchStmt::Continue ) ); }
     5952#line 853 "parser.yy"
     5953    { (yyval.sn) = new StatementNode( StatementNode::Continue ); }
    59535954    break;
    59545955
     
    59565957
    59575958/* Line 1806 of yacc.c  */
    5958 #line 855 "parser.yy"
    5959     { (yyval.sn) = new StatementNode2( build_branch( *(yyvsp[(2) - (3)].tok), BranchStmt::Continue ) ); delete (yyvsp[(2) - (3)].tok); }
     5959#line 857 "parser.yy"
     5960    { (yyval.sn) = new StatementNode( StatementNode::Continue, (yyvsp[(2) - (3)].tok) ); }
    59605961    break;
    59615962
     
    59635964
    59645965/* Line 1806 of yacc.c  */
    5965 #line 859 "parser.yy"
    5966     { (yyval.sn) = new StatementNode2( build_branch( "", BranchStmt::Break ) ); }
     5966#line 860 "parser.yy"
     5967    { (yyval.sn) = new StatementNode( StatementNode::Break ); }
    59675968    break;
    59685969
     
    59715972/* Line 1806 of yacc.c  */
    59725973#line 864 "parser.yy"
    5973     { (yyval.sn) = new StatementNode2( build_branch( *(yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); delete (yyvsp[(2) - (3)].tok); }
     5974    { (yyval.sn) = new StatementNode( StatementNode::Break, (yyvsp[(2) - (3)].tok) ); }
    59745975    break;
    59755976
     
    91509151
    91519152/* Line 1806 of yacc.c  */
    9152 #line 9153 "Parser/parser.cc"
     9153#line 9154 "Parser/parser.cc"
    91539154      default: break;
    91549155    }
  • src/Parser/parser.yy

    r82da9b8 rd2f5469  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Wed Aug 10 23:03:05 2016
    13 // Update Count     : 1846
     12// Last Modified On : Wed Aug 10 13:09:53 2016
     13// Update Count     : 1844
    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 ); }
    725726                { $$ = new StatementNode2( build_if( $3, $5, nullptr ) ); }
    726727        | IF '(' comma_expression ')' statement ELSE statement
     728                //{ $$ = new StatementNode( StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7 )) ); }
    727729                { $$ = new StatementNode2( build_if( $3, $5, $7 ) ); }
    728730        | SWITCH '(' comma_expression ')' case_clause           // CFA
     731                //{ $$ = new StatementNode( StatementNode::Switch, $3, $5 ); }
    729732                { $$ = new StatementNode2( build_switch( $3, $5 ) ); }
    730733        | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA
     
    739742                }
    740743        | CHOOSE '(' comma_expression ')' case_clause           // CFA
     744                //{ $$ = new StatementNode( StatementNode::Switch, $3, $5 ); }
    741745                { $$ = new StatementNode2( build_switch( $3, $5 ) ); }
    742746        | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA
    743747                {
     748                        //StatementNode *sw = new StatementNode( StatementNode::Switch, $3, $8 );
    744749                        StatementNode *sw = new StatementNode2( build_switch( $3, $8 ) );
    745750                        $$ = $7 != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( $7 ))->set_link( sw )) ) : sw;
     
    839844jump_statement:
    840845        GOTO IDENTIFIER ';'
    841                 //{ $$ = new StatementNode( StatementNode::Goto, $2 ); }
    842                 { $$ = new StatementNode2( build_branch( *$2, BranchStmt::Goto ) ); }
     846                { $$ = new StatementNode( StatementNode::Goto, $2 ); }
    843847        | GOTO '*' comma_expression ';'                                         // GCC, computed goto
    844848                // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3);
     
    847851        | CONTINUE ';'
    848852                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    849                 //{ $$ = new StatementNode( StatementNode::Continue ); }
    850                 { $$ = new StatementNode2( build_branch( "", BranchStmt::Continue ) ); }
     853                { $$ = new StatementNode( StatementNode::Continue ); }
    851854        | CONTINUE IDENTIFIER ';'                                                       // CFA, multi-level continue
    852855                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    853856                // the target of the transfer appears only at the start of an iteration statement.
    854                 //{ $$ = new StatementNode( StatementNode::Continue, $2 ); }
    855                 { $$ = new StatementNode2( build_branch( *$2, BranchStmt::Continue ) ); delete $2; }
     857                { $$ = new StatementNode( StatementNode::Continue, $2 ); }
    856858        | BREAK ';'
    857859                // A semantic check is required to ensure this statement appears only in the body of an iteration statement.
    858                 //{ $$ = new StatementNode( StatementNode::Break ); }
    859                 { $$ = new StatementNode2( build_branch( "", BranchStmt::Break ) ); }
     860                { $$ = new StatementNode( StatementNode::Break ); }
    860861        | BREAK IDENTIFIER ';'                                                          // CFA, multi-level exit
    861862                // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and
    862863                // the target of the transfer appears only at the start of an iteration statement.
    863                 //{ $$ = new StatementNode( StatementNode::Break, $2 ); }
    864                 { $$ = new StatementNode2( build_branch( *$2, BranchStmt::Break ) ); delete $2; }
     864                { $$ = new StatementNode( StatementNode::Break, $2 ); }
    865865        | RETURN comma_expression_opt ';'
    866866                { $$ = new StatementNode( StatementNode::Return, $2, 0 ); }
Note: See TracChangeset for help on using the changeset viewer.