Changeset 82da9b8
- Timestamp:
- Aug 11, 2016, 2:38:02 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, 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. - Files:
-
- 4 added
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/aaron_comp_II/comp_II.tex
rd2f5469 r82da9b8 37 37 \setlength{\headsep}{0.25in} 38 38 39 \usepackage{caption} 40 \usepackage{subcaption} 41 39 42 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 40 43 … … 62 65 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 63 66 64 \newcommand{\bigO}[1]{O\ left( #1 \right)}67 \newcommand{\bigO}[1]{O\!\left( #1 \right)} 65 68 66 69 \begin{document} … … 404 407 If 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. 405 408 The 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 406 410 The 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. 407 412 408 413 \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. 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. 413 438 For each candidate function, Baker attempts to match argument types to parameter types in sequence, failing if any parameter cannot be matched. 414 439 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 returntypes.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 whichmatch the type of each parameter of each candidate function, from the top-level expression down; memoization of these requests is presented as an optimization.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. 421 446 As 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. 422 447 423 448 \subsubsection{Hybrid} 424 449 This 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: 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: 427 453 \begin{lstlisting} 428 454 forall(otype T) … … 433 459 int x = f( f( '!' ) ); 434 460 \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. 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©. 438 467 439 468 \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.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. 441 470 Integrating implicit conversion handling into their algorithms provides some choice of implementation approach. 442 471 -
src/Parser/ParseNode.h
rd2f5469 r82da9b8 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 10 13:08:46201613 // Update Count : 43 612 // Last Modified On : Wed Aug 10 21:51:49 2016 13 // Update Count : 437 14 14 // 15 15 … … 415 415 Statement *build_while( ExpressionNode *ctl, StatementNode *stmt, bool kind = false ); 416 416 Statement *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(); 417 420 418 421 //############################################################################## -
src/Parser/StatementNode.cc
rd2f5469 r82da9b8 10 10 // Created On : Sat May 16 14:59:41 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 10 13:54:21201613 // Update Count : 17 012 // Last Modified On : Wed Aug 10 22:08:38 2016 13 // Update Count : 173 14 14 // 15 15 … … 224 224 case Case: 225 225 return new CaseStmt( labs, maybeBuild<Expression>(get_control() ), branches ); 226 assert( false ); 226 227 case Default: 227 228 return new CaseStmt( labs, 0, branches, true ); 229 assert( false ); 228 230 case While: 229 231 // assert( branches.size() == 1 ); … … 268 270 case Break: 269 271 return new BranchStmt( labs, get_target(), BranchStmt::Break ); 272 assert( false ); 270 273 case Continue: 271 274 return new BranchStmt( labs, get_target(), BranchStmt::Continue ); 275 assert( false ); 272 276 case Return: 273 277 case Throw : … … 314 318 std::list<Statement *> branches; 315 319 buildList<Statement, StatementNode>( then_stmt, branches ); 316 assert( branches.size() >= 1 );320 assert( branches.size() == 1 ); 317 321 thenb = branches.front(); 318 322 … … 320 324 std::list<Statement *> branches; 321 325 buildList<Statement, StatementNode>( else_stmt, branches ); 322 assert( branches.size() >= 1 );326 assert( branches.size() == 1 ); 323 327 elseb = branches.front(); 324 328 } // if … … 329 333 std::list<Statement *> branches; 330 334 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 332 336 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 ); 333 346 } 334 347 … … 360 373 delete forctl; 361 374 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 ); 362 379 } 363 380 -
src/Parser/parser.cc
rd2f5469 r82da9b8 1035 1035 657, 658, 659, 660, 661, 662, 663, 673, 680, 682, 1036 1036 692, 693, 698, 700, 706, 708, 712, 713, 718, 723, 1037 72 7, 730, 733, 743, 746, 758, 759, 761, 765, 767,1038 7 71, 772, 777, 778, 782, 787, 788, 792, 794, 800,1039 801, 805, 807, 809, 811, 817, 818, 822, 824, 829,1040 8 31, 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, 1041 1041 865, 867, 871, 873, 880, 882, 884, 893, 895, 897, 1042 1042 899, 901, 906, 908, 910, 912, 917, 930, 931, 936, … … 5714 5714 5715 5715 /* Line 1806 of yacc.c */ 5716 #line 72 6"parser.yy"5716 #line 725 "parser.yy" 5717 5717 { (yyval.sn) = new StatementNode2( build_if( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn), nullptr ) ); } 5718 5718 break; … … 5721 5721 5722 5722 /* 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 */ 5723 5730 #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"5731 5731 { (yyval.sn) = new StatementNode2( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5732 5732 break; … … 5735 5735 5736 5736 /* Line 1806 of yacc.c */ 5737 #line 73 4"parser.yy"5737 #line 731 "parser.yy" 5738 5738 { 5739 5739 StatementNode *sw = new StatementNode2( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) ); … … 5750 5750 5751 5751 /* Line 1806 of yacc.c */ 5752 #line 74 5"parser.yy"5752 #line 741 "parser.yy" 5753 5753 { (yyval.sn) = new StatementNode2( build_switch( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5754 5754 break; … … 5757 5757 5758 5758 /* Line 1806 of yacc.c */ 5759 #line 74 7"parser.yy"5759 #line 743 "parser.yy" 5760 5760 { 5761 //StatementNode *sw = new StatementNode( StatementNode::Switch, $3, $8 );5762 5761 StatementNode *sw = new StatementNode2( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) ); 5763 5762 (yyval.sn) = (yyvsp[(7) - (9)].decl) != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( (yyvsp[(7) - (9)].decl) ))->set_link( sw )) ) : sw; … … 5768 5767 5769 5768 /* Line 1806 of yacc.c */ 5770 #line 75 8"parser.yy"5769 #line 753 "parser.yy" 5771 5770 { (yyval.en) = (yyvsp[(1) - (1)].en); } 5772 5771 break; … … 5775 5774 5776 5775 /* 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 */ 5777 5783 #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"5785 5784 { (yyval.sn) = new StatementNode( StatementNode::Case, (yyvsp[(1) - (1)].en), 0 ); } 5786 5785 break; … … 5789 5788 5790 5789 /* 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 */ 5791 5804 #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"5806 5805 { (yyval.sn) = new StatementNode( StatementNode::Default ); } 5807 5806 break; … … 5810 5809 5811 5810 /* Line 1806 of yacc.c */ 5812 #line 77 8"parser.yy"5811 #line 773 "parser.yy" 5813 5812 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_link( (yyvsp[(2) - (2)].sn) )); } 5814 5813 break; … … 5817 5816 5818 5817 /* 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 */ 5819 5825 #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" 5820 5833 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); } 5821 5834 break; 5822 5835 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" 5827 5847 { (yyval.sn) = 0; } 5828 5848 break; 5829 5849 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" 5848 5889 { (yyval.sn) = 0; } 5849 5890 break; 5850 5891 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" 5890 5896 { (yyval.sn) = 0; } 5891 5897 break; 5892 5898 5893 case 17 8:5899 case 179: 5894 5900 5895 5901 /* Line 1806 of yacc.c */ 5896 5902 #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"5904 5903 { (yyval.sn) = new StatementNode2( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5905 5904 break; … … 5908 5907 5909 5908 /* Line 1806 of yacc.c */ 5910 #line 8 32"parser.yy"5909 #line 827 "parser.yy" 5911 5910 { (yyval.sn) = new StatementNode2( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn) ) ); } 5912 5911 break; … … 5915 5914 5916 5915 /* 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 */ 5917 5923 #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"5925 5924 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); } 5926 5925 break; … … 5929 5928 5930 5929 /* Line 1806 of yacc.c */ 5931 #line 8 41"parser.yy"5930 #line 836 "parser.yy" 5932 5931 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); } 5933 5932 break; … … 5936 5935 5937 5936 /* 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 */ 5938 5944 #line 846 "parser.yy" 5939 { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[( 2) - (3)].tok) ); }5940 break; 5941 5942 case 18 5:5945 { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(3) - (4)].en) ); } 5946 break; 5947 5948 case 186: 5943 5949 5944 5950 /* Line 1806 of yacc.c */ 5945 5951 #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 ) ); } 5954 5953 break; 5955 5954 … … 5957 5956 5958 5957 /* Line 1806 of yacc.c */ 5959 #line 85 7"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); } 5961 5960 break; 5962 5961 … … 5964 5963 5965 5964 /* Line 1806 of yacc.c */ 5966 #line 8 60"parser.yy"5967 { (yyval.sn) = new StatementNode ( StatementNode::Break); }5965 #line 859 "parser.yy" 5966 { (yyval.sn) = new StatementNode2( build_branch( "", BranchStmt::Break ) ); } 5968 5967 break; 5969 5968 … … 5972 5971 /* Line 1806 of yacc.c */ 5973 5972 #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); } 5975 5974 break; 5976 5975 … … 9151 9150 9152 9151 /* Line 1806 of yacc.c */ 9153 #line 915 4"Parser/parser.cc"9152 #line 9153 "Parser/parser.cc" 9154 9153 default: break; 9155 9154 } -
src/Parser/parser.yy
rd2f5469 r82da9b8 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 10 13:09:53201613 // Update Count : 184 412 // Last Modified On : Wed Aug 10 23:03:05 2016 13 // Update Count : 1846 14 14 // 15 15 … … 723 723 IF '(' comma_expression ')' statement %prec THEN 724 724 // explicitly deal with the shift/reduce conflict on if/else 725 //{ $$ = new StatementNode( StatementNode::If, $3, $5 ); }726 725 { $$ = new StatementNode2( build_if( $3, $5, nullptr ) ); } 727 726 | IF '(' comma_expression ')' statement ELSE statement 728 //{ $$ = new StatementNode( StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7 )) ); }729 727 { $$ = new StatementNode2( build_if( $3, $5, $7 ) ); } 730 728 | SWITCH '(' comma_expression ')' case_clause // CFA 731 //{ $$ = new StatementNode( StatementNode::Switch, $3, $5 ); }732 729 { $$ = new StatementNode2( build_switch( $3, $5 ) ); } 733 730 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA … … 742 739 } 743 740 | CHOOSE '(' comma_expression ')' case_clause // CFA 744 //{ $$ = new StatementNode( StatementNode::Switch, $3, $5 ); }745 741 { $$ = new StatementNode2( build_switch( $3, $5 ) ); } 746 742 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA 747 743 { 748 //StatementNode *sw = new StatementNode( StatementNode::Switch, $3, $8 );749 744 StatementNode *sw = new StatementNode2( build_switch( $3, $8 ) ); 750 745 $$ = $7 != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( $7 ))->set_link( sw )) ) : sw; … … 844 839 jump_statement: 845 840 GOTO IDENTIFIER ';' 846 { $$ = new StatementNode( StatementNode::Goto, $2 ); } 841 //{ $$ = new StatementNode( StatementNode::Goto, $2 ); } 842 { $$ = new StatementNode2( build_branch( *$2, BranchStmt::Goto ) ); } 847 843 | GOTO '*' comma_expression ';' // GCC, computed goto 848 844 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 851 847 | CONTINUE ';' 852 848 // 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 ) ); } 854 851 | CONTINUE IDENTIFIER ';' // CFA, multi-level continue 855 852 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 856 853 // 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; } 858 856 | BREAK ';' 859 857 // 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 ) ); } 861 860 | BREAK IDENTIFIER ';' // CFA, multi-level exit 862 861 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 863 862 // 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; } 865 865 | RETURN comma_expression_opt ';' 866 866 { $$ = new StatementNode( StatementNode::Return, $2, 0 ); }
Note: See TracChangeset
for help on using the changeset viewer.