Changes in / [82da9b8:d2f5469]
- Files:
-
- 4 deleted
- 5 edited
-
doc/aaron_comp_II/comp_II.tex (modified) (4 diffs)
-
doc/aaron_comp_II/conversion_dag.eps (deleted)
-
doc/aaron_comp_II/conversion_dag.odg (deleted)
-
doc/aaron_comp_II/resolution_dag.eps (deleted)
-
doc/aaron_comp_II/resolution_dag.odg (deleted)
-
src/Parser/ParseNode.h (modified) (2 diffs)
-
src/Parser/StatementNode.cc (modified) (7 diffs)
-
src/Parser/parser.cc (modified) (38 diffs)
-
src/Parser/parser.yy (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
doc/aaron_comp_II/comp_II.tex
r82da9b8 rd2f5469 37 37 \setlength{\headsep}{0.25in} 38 38 39 \usepackage{caption}40 \usepackage{subcaption}41 42 39 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 43 40 … … 65 62 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 66 63 67 \newcommand{\bigO}[1]{O\ !\left( #1 \right)}64 \newcommand{\bigO}[1]{O\left( #1 \right)} 68 65 69 66 \begin{document} … … 407 404 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. 408 405 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 410 406 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.412 407 413 408 \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. 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. 438 413 For each candidate function, Baker attempts to match argument types to parameter types in sequence, failing if any parameter cannot be matched. 439 414 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 thatmatch the type of each parameter of each candidate function, from the top-level expression down; memoization of these requests is presented as an optimization.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. 446 421 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. 447 422 448 423 \subsubsection{Hybrid} 449 424 This 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: 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: 453 427 \begin{lstlisting} 454 428 forall(otype T) … … 459 433 int x = f( f( '!' ) ); 460 434 \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©. 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. 467 438 468 439 \subsection{Implicit Conversion Application} 469 Baker's and Cormack'salgorithms 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.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. 470 441 Integrating implicit conversion handling into their algorithms provides some choice of implementation approach. 471 442 -
src/Parser/ParseNode.h
r82da9b8 rd2f5469 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 21:51:49201613 // Update Count : 43 712 // Last Modified On : Wed Aug 10 13:08:46 2016 13 // Update Count : 436 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();420 417 421 418 //############################################################################## -
src/Parser/StatementNode.cc
r82da9b8 rd2f5469 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 22:08:38201613 // Update Count : 17 312 // Last Modified On : Wed Aug 10 13:54:21 2016 13 // Update Count : 170 14 14 // 15 15 … … 224 224 case Case: 225 225 return new CaseStmt( labs, maybeBuild<Expression>(get_control() ), branches ); 226 assert( false );227 226 case Default: 228 227 return new CaseStmt( labs, 0, branches, true ); 229 assert( false );230 228 case While: 231 229 // assert( branches.size() == 1 ); … … 270 268 case Break: 271 269 return new BranchStmt( labs, get_target(), BranchStmt::Break ); 272 assert( false );273 270 case Continue: 274 271 return new BranchStmt( labs, get_target(), BranchStmt::Continue ); 275 assert( false );276 272 case Return: 277 273 case Throw : … … 318 314 std::list<Statement *> branches; 319 315 buildList<Statement, StatementNode>( then_stmt, branches ); 320 assert( branches.size() == 1 );316 assert( branches.size() >= 1 ); 321 317 thenb = branches.front(); 322 318 … … 324 320 std::list<Statement *> branches; 325 321 buildList<Statement, StatementNode>( else_stmt, branches ); 326 assert( branches.size() == 1 );322 assert( branches.size() >= 1 ); 327 323 elseb = branches.front(); 328 324 } // if … … 333 329 std::list<Statement *> branches; 334 330 buildList<Statement, StatementNode>( stmt, branches ); 335 assert( branches.size() >= 0 ); // size == 0 for switch (...) {}, i.e., no declaration or statements331 assert( branches.size() >= 1 ); 336 332 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 );346 333 } 347 334 … … 373 360 delete forctl; 374 361 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 );379 362 } 380 363 -
src/Parser/parser.cc
r82da9b8 rd2f5469 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 6, 728, 730, 740, 742, 753, 754, 756, 760, 762,1038 7 66, 767, 772, 773, 777, 782, 783, 787, 789, 795,1039 796, 800, 802, 804, 806, 812, 813, 817, 819, 824,1040 8 26, 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, 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 5"parser.yy"5716 #line 726 "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 72 7"parser.yy"5723 #line 729 "parser.yy" 5724 5724 { (yyval.sn) = new StatementNode2( build_if( (yyvsp[(3) - (7)].en), (yyvsp[(5) - (7)].sn), (yyvsp[(7) - (7)].sn) ) ); } 5725 5725 break; … … 5728 5728 5729 5729 /* Line 1806 of yacc.c */ 5730 #line 7 29"parser.yy"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 1"parser.yy"5737 #line 734 "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 1"parser.yy"5752 #line 745 "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 3"parser.yy"5759 #line 747 "parser.yy" 5760 5760 { 5761 //StatementNode *sw = new StatementNode( StatementNode::Switch, $3, $8 ); 5761 5762 StatementNode *sw = new StatementNode2( build_switch( (yyvsp[(3) - (9)].en), (yyvsp[(8) - (9)].sn) ) ); 5762 5763 (yyval.sn) = (yyvsp[(7) - (9)].decl) != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( (yyvsp[(7) - (9)].decl) ))->set_link( sw )) ) : sw; … … 5767 5768 5768 5769 /* Line 1806 of yacc.c */ 5769 #line 75 3"parser.yy"5770 #line 758 "parser.yy" 5770 5771 { (yyval.en) = (yyvsp[(1) - (1)].en); } 5771 5772 break; … … 5774 5775 5775 5776 /* Line 1806 of yacc.c */ 5776 #line 7 55"parser.yy"5777 #line 760 "parser.yy" 5777 5778 { (yyval.en) = new ExpressionNode( build_range( (yyvsp[(1) - (3)].en), (yyvsp[(3) - (3)].en) ) ); } 5778 5779 break; … … 5781 5782 5782 5783 /* Line 1806 of yacc.c */ 5783 #line 76 0"parser.yy"5784 #line 765 "parser.yy" 5784 5785 { (yyval.sn) = new StatementNode( StatementNode::Case, (yyvsp[(1) - (1)].en), 0 ); } 5785 5786 break; … … 5788 5789 5789 5790 /* Line 1806 of yacc.c */ 5790 #line 76 2"parser.yy"5791 #line 767 "parser.yy" 5791 5792 { (yyval.sn) = (StatementNode *)((yyvsp[(1) - (3)].sn)->set_link( new StatementNode( StatementNode::Case, (yyvsp[(3) - (3)].en), 0 ) ) ); } 5792 5793 break; … … 5795 5796 5796 5797 /* Line 1806 of yacc.c */ 5797 #line 7 66"parser.yy"5798 #line 771 "parser.yy" 5798 5799 { (yyval.sn) = (yyvsp[(2) - (3)].sn); } 5799 5800 break; … … 5802 5803 5803 5804 /* Line 1806 of yacc.c */ 5804 #line 7 67"parser.yy"5805 #line 772 "parser.yy" 5805 5806 { (yyval.sn) = new StatementNode( StatementNode::Default ); } 5806 5807 break; … … 5809 5810 5810 5811 /* Line 1806 of yacc.c */ 5811 #line 77 3"parser.yy"5812 #line 778 "parser.yy" 5812 5813 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (2)].sn)->set_link( (yyvsp[(2) - (2)].sn) )); } 5813 5814 break; … … 5816 5817 5817 5818 /* Line 1806 of yacc.c */ 5818 #line 7 77"parser.yy"5819 #line 782 "parser.yy" 5819 5820 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); } 5820 5821 break; … … 5823 5824 5824 5825 /* Line 1806 of yacc.c */ 5825 #line 78 2"parser.yy"5826 #line 787 "parser.yy" 5826 5827 { (yyval.sn) = 0; } 5827 5828 break; … … 5830 5831 5831 5832 /* Line 1806 of yacc.c */ 5832 #line 7 88"parser.yy"5833 #line 793 "parser.yy" 5833 5834 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(2) - (2)].sn) ) ); } 5834 5835 break; … … 5837 5838 5838 5839 /* Line 1806 of yacc.c */ 5839 #line 79 0"parser.yy"5840 #line 795 "parser.yy" 5840 5841 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( new CompoundStmtNode( (yyvsp[(3) - (3)].sn) ) ) ) ); } 5841 5842 break; … … 5844 5845 5845 5846 /* Line 1806 of yacc.c */ 5846 #line 795"parser.yy"5847 #line 800 "parser.yy" 5847 5848 { (yyval.sn) = 0; } 5848 5849 break; … … 5851 5852 5852 5853 /* Line 1806 of yacc.c */ 5853 #line 80 1"parser.yy"5854 #line 806 "parser.yy" 5854 5855 { (yyval.sn) = (yyvsp[(1) - (2)].sn)->append_last_case( (yyvsp[(2) - (2)].sn) ); } 5855 5856 break; … … 5858 5859 5859 5860 /* Line 1806 of yacc.c */ 5860 #line 80 3"parser.yy"5861 #line 808 "parser.yy" 5861 5862 { (yyval.sn) = (yyvsp[(1) - (3)].sn)->append_last_case( new CompoundStmtNode( (StatementNode *)mkList( (*(yyvsp[(2) - (3)].sn), *(yyvsp[(3) - (3)].sn) ) ) ) ); } 5862 5863 break; … … 5865 5866 5866 5867 /* Line 1806 of yacc.c */ 5867 #line 8 05"parser.yy"5868 #line 810 "parser.yy" 5868 5869 { (yyval.sn) = (StatementNode *)( (yyvsp[(1) - (3)].sn)->set_link( (yyvsp[(2) - (3)].sn)->append_last_case( (yyvsp[(3) - (3)].sn) ))); } 5869 5870 break; … … 5872 5873 5873 5874 /* Line 1806 of yacc.c */ 5874 #line 8 07"parser.yy"5875 #line 812 "parser.yy" 5875 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) ) ) ) ) ) ); } 5876 5877 break; … … 5879 5880 5880 5881 /* Line 1806 of yacc.c */ 5881 #line 81 2"parser.yy"5882 #line 817 "parser.yy" 5882 5883 { (yyval.sn) = new StatementNode( StatementNode::Break ); } 5883 5884 break; … … 5886 5887 5887 5888 /* Line 1806 of yacc.c */ 5888 #line 8 18"parser.yy"5889 #line 823 "parser.yy" 5889 5890 { (yyval.sn) = 0; } 5890 5891 break; … … 5893 5894 5894 5895 /* Line 1806 of yacc.c */ 5895 #line 82 0"parser.yy"5896 #line 825 "parser.yy" 5896 5897 { (yyval.sn) = 0; } 5897 5898 break; … … 5900 5901 5901 5902 /* Line 1806 of yacc.c */ 5902 #line 8 25"parser.yy"5903 #line 830 "parser.yy" 5903 5904 { (yyval.sn) = new StatementNode2( build_while( (yyvsp[(3) - (5)].en), (yyvsp[(5) - (5)].sn) ) ); } 5904 5905 break; … … 5907 5908 5908 5909 /* Line 1806 of yacc.c */ 5909 #line 8 27"parser.yy"5910 #line 832 "parser.yy" 5910 5911 { (yyval.sn) = new StatementNode2( build_while( (yyvsp[(5) - (7)].en), (yyvsp[(2) - (7)].sn) ) ); } 5911 5912 break; … … 5914 5915 5915 5916 /* Line 1806 of yacc.c */ 5916 #line 8 29"parser.yy"5917 #line 834 "parser.yy" 5917 5918 { (yyval.sn) = new StatementNode2( build_for( (yyvsp[(4) - (6)].fctl), (yyvsp[(6) - (6)].sn) ) ); } 5918 5919 break; … … 5921 5922 5922 5923 /* Line 1806 of yacc.c */ 5923 #line 83 4"parser.yy"5924 #line 839 "parser.yy" 5924 5925 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (6)].en), (yyvsp[(4) - (6)].en), (yyvsp[(6) - (6)].en) ); } 5925 5926 break; … … 5928 5929 5929 5930 /* Line 1806 of yacc.c */ 5930 #line 8 36"parser.yy"5931 #line 841 "parser.yy" 5931 5932 { (yyval.fctl) = new ForCtl( (yyvsp[(1) - (4)].decl), (yyvsp[(2) - (4)].en), (yyvsp[(4) - (4)].en) ); } 5932 5933 break; … … 5935 5936 5936 5937 /* Line 1806 of yacc.c */ 5937 #line 84 2"parser.yy"5938 { (yyval.sn) = new StatementNode 2( build_branch( *(yyvsp[(2) - (3)].tok), BranchStmt::Goto) ); }5938 #line 846 "parser.yy" 5939 { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(2) - (3)].tok) ); } 5939 5940 break; 5940 5941 … … 5942 5943 5943 5944 /* Line 1806 of yacc.c */ 5944 #line 8 46"parser.yy"5945 #line 850 "parser.yy" 5945 5946 { (yyval.sn) = new StatementNode( StatementNode::Goto, (yyvsp[(3) - (4)].en) ); } 5946 5947 break; … … 5949 5950 5950 5951 /* Line 1806 of yacc.c */ 5951 #line 85 0"parser.yy"5952 { (yyval.sn) = new StatementNode 2( build_branch( "", BranchStmt::Continue )); }5952 #line 853 "parser.yy" 5953 { (yyval.sn) = new StatementNode( StatementNode::Continue ); } 5953 5954 break; 5954 5955 … … 5956 5957 5957 5958 /* Line 1806 of yacc.c */ 5958 #line 85 5"parser.yy"5959 { (yyval.sn) = new StatementNode 2( 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) ); } 5960 5961 break; 5961 5962 … … 5963 5964 5964 5965 /* Line 1806 of yacc.c */ 5965 #line 8 59"parser.yy"5966 { (yyval.sn) = new StatementNode 2( build_branch( "", BranchStmt::Break )); }5966 #line 860 "parser.yy" 5967 { (yyval.sn) = new StatementNode( StatementNode::Break ); } 5967 5968 break; 5968 5969 … … 5971 5972 /* Line 1806 of yacc.c */ 5972 5973 #line 864 "parser.yy" 5973 { (yyval.sn) = new StatementNode 2( build_branch( *(yyvsp[(2) - (3)].tok), BranchStmt::Break ) ); delete (yyvsp[(2) - (3)].tok); }5974 { (yyval.sn) = new StatementNode( StatementNode::Break, (yyvsp[(2) - (3)].tok) ); } 5974 5975 break; 5975 5976 … … 9150 9151 9151 9152 /* Line 1806 of yacc.c */ 9152 #line 915 3"Parser/parser.cc"9153 #line 9154 "Parser/parser.cc" 9153 9154 default: break; 9154 9155 } -
src/Parser/parser.yy
r82da9b8 rd2f5469 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 23:03:05201613 // Update Count : 184 612 // Last Modified On : Wed Aug 10 13:09:53 2016 13 // Update Count : 1844 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 ); } 725 726 { $$ = new StatementNode2( build_if( $3, $5, nullptr ) ); } 726 727 | IF '(' comma_expression ')' statement ELSE statement 728 //{ $$ = new StatementNode( StatementNode::If, $3, (StatementNode *)mkList((*$5, *$7 )) ); } 727 729 { $$ = new StatementNode2( build_if( $3, $5, $7 ) ); } 728 730 | SWITCH '(' comma_expression ')' case_clause // CFA 731 //{ $$ = new StatementNode( StatementNode::Switch, $3, $5 ); } 729 732 { $$ = new StatementNode2( build_switch( $3, $5 ) ); } 730 733 | SWITCH '(' comma_expression ')' '{' push declaration_list_opt switch_clause_list_opt '}' // CFA … … 739 742 } 740 743 | CHOOSE '(' comma_expression ')' case_clause // CFA 744 //{ $$ = new StatementNode( StatementNode::Switch, $3, $5 ); } 741 745 { $$ = new StatementNode2( build_switch( $3, $5 ) ); } 742 746 | CHOOSE '(' comma_expression ')' '{' push declaration_list_opt choose_clause_list_opt '}' // CFA 743 747 { 748 //StatementNode *sw = new StatementNode( StatementNode::Switch, $3, $8 ); 744 749 StatementNode *sw = new StatementNode2( build_switch( $3, $8 ) ); 745 750 $$ = $7 != 0 ? new CompoundStmtNode( (StatementNode *)((new StatementNode( $7 ))->set_link( sw )) ) : sw; … … 839 844 jump_statement: 840 845 GOTO IDENTIFIER ';' 841 //{ $$ = new StatementNode( StatementNode::Goto, $2 ); } 842 { $$ = new StatementNode2( build_branch( *$2, BranchStmt::Goto ) ); } 846 { $$ = new StatementNode( StatementNode::Goto, $2 ); } 843 847 | GOTO '*' comma_expression ';' // GCC, computed goto 844 848 // The syntax for the GCC computed goto violates normal expression precedence, e.g., goto *i+3; => goto *(i+3); … … 847 851 | CONTINUE ';' 848 852 // 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 ); } 851 854 | CONTINUE IDENTIFIER ';' // CFA, multi-level continue 852 855 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 853 856 // 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 ); } 856 858 | BREAK ';' 857 859 // 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 ); } 860 861 | BREAK IDENTIFIER ';' // CFA, multi-level exit 861 862 // A semantic check is required to ensure this statement appears only in the body of an iteration statement, and 862 863 // 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 ); } 865 865 | RETURN comma_expression_opt ';' 866 866 { $$ = new StatementNode( StatementNode::Return, $2, 0 ); }
Note:
See TracChangeset
for help on using the changeset viewer.