Home | History | Annotate | Download | only in C
      1 /*
      2  [The "BSD license"]
      3  Copyright (c) 2005-2009 Jim Idle, Temporal Wave LLC
      4  http://www.temporal-wave.com
      5  http://www.linkedin.com/in/jimidle
      6 
      7  All rights reserved.
      8 
      9  Redistribution and use in source and binary forms, with or without
     10  modification, are permitted provided that the following conditions
     11  are met:
     12  1. Redistributions of source code must retain the above copyright
     13     notice, this list of conditions and the following disclaimer.
     14  2. Redistributions in binary form must reproduce the above copyright
     15     notice, this list of conditions and the following disclaimer in the
     16     documentation and/or other materials provided with the distribution.
     17  3. The name of the author may not be used to endorse or promote products
     18     derived from this software without specific prior written permission.
     19 
     20  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     21  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     22  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     23  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     24  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     25  NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     29  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 */
     31 
     32 /** Templates for building ASTs during normal parsing.
     33  *
     34  *  Deal with many combinations.  Dimensions are:
     35  *  Auto build or rewrite
     36  *    no label, label, list label  (label/no-label handled together)
     37  *    child, root
     38  *    token, set, rule, wildcard
     39  *
     40  *  The situation is not too bad as rewrite (->) usage makes ^ and !
     41  *  invalid. There is no huge explosion of combinations.
     42  */
     43 
     44 @rule.setErrorReturnValue() ::= <<
     45 retval.tree = (<ASTLabelType>)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
     46 >>
     47 
     48 // TOKEN AST STUFF
     49 
     50 /** ID and output=AST */
     51 tokenRef(token,label,elementIndex,terminalOptions) ::= <<
     52 <super.tokenRef(...)>
     53 <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
     54 <label>_tree = (<ASTLabelType>)(ADAPTOR->create(ADAPTOR, <label>));
     55 ADAPTOR->addChild(ADAPTOR, root_0, <label>_tree);
     56 <if(backtracking)>}<endif>
     57 >>
     58 
     59 /** ID! and output=AST (same as plain tokenRef) */
     60 tokenRefBang(token,label,elementIndex,terminalOptions) ::= "<super.tokenRef(...)>"
     61 
     62 /** ID^ and output=AST */
     63 tokenRefRuleRoot(token,label,elementIndex,terminalOptions) ::= <<
     64 <super.tokenRef(...)>
     65 <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
     66 <label>_tree = <createNodeFromToken(...)>;
     67 root_0 = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <label>_tree, root_0));
     68 <if(backtracking)>}<endif>
     69 >>
     70 
     71 /** ids+=ID! and output=AST */
     72 tokenRefBangAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
     73 <tokenRefBang(...)>
     74 <listLabel(elem=label,...)>
     75 >>
     76 
     77 
     78 /** label+=TOKEN when output=AST but not rewrite alt */
     79 tokenRefAndListLabel(token,label,elementIndex,terminalOptions) ::= <<
     80 <tokenRef(...)>
     81 <listLabel(elem=label,...)>
     82 >>
     83 
     84 
     85 /** Match label+=TOKEN^ when output=AST but not rewrite alt */
     86 tokenRefRuleRootAndListLabel(token,label,terminalOptions,elementIndex) ::= <<
     87 <tokenRefRuleRoot(...)>
     88 <listLabel(elem=label,...)>
     89 >>
     90 
     91 // SET AST
     92 
     93 // the match set stuff is interesting in that it uses an argument list
     94 // to pass code to the default matchSet; another possible way to alter
     95 // inherited code.  I don't use the region stuff because I need to pass
     96 // different chunks depending on the operator.  I don't like making
     97 // the template name have the operator as the number of templates gets
     98 // large but this is the most flexible--this is as opposed to having
     99 // the code generator call matchSet then add root code or ruleroot code
    100 // plus list label plus ...  The combinations might require complicated
    101 // rather than just added on code.  Investigate that refactoring when
    102 // I have more time.
    103 
    104 matchSet(s,label,terminalOptions,elementIndex,postmatchCode) ::= <<
    105 <super.matchSet(postmatchCode={<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif>ADAPTOR->addChild(ADAPTOR, root_0, <createNodeFromToken(...)>);},...)>
    106 >>
    107 
    108 matchRuleBlockSet(s,label,terminalOptions,elementIndex,postmatchCode,treeLevel="0") ::= <<
    109 <matchSet(...)>
    110 >>
    111 
    112 matchSetBang(s,label,elementIndex,terminalOptions,postmatchCode) ::= "<super.matchSet(...)>"
    113 
    114 // note there is no matchSetTrack because -> rewrites force sets to be
    115 // plain old blocks of alts: (A|B|...|C)
    116 
    117 matchSetRuleRoot(s,label,terminalOptions,elementIndex,debug) ::= <<
    118 <if(label)>
    119 <label>=(<labelType>)LT(1);<\n>
    120 <endif>
    121 <super.matchSet(postmatchCode={<if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif>root_0 = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createNodeFromToken(...)>, root_0));},...)>
    122 >>
    123 
    124 // RULE REF AST
    125 
    126 /** rule when output=AST */
    127 ruleRef(rule,label,elementIndex,args,scope) ::= <<
    128 <super.ruleRef(...)>
    129 <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif>ADAPTOR->addChild(ADAPTOR, root_0, <label>.tree);
    130 >>
    131 
    132 /** rule! is same as normal rule ref */
    133 ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
    134 
    135 /** rule^ */
    136 ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
    137 <super.ruleRef(...)>
    138 <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) <endif>root_0 = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <label>.tree, root_0));
    139 >>
    140 
    141 /** x+=rule when output=AST */
    142 ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
    143 <ruleRef(...)>
    144 <listLabelAST(...)>
    145 >>
    146 
    147 /** x+=rule! when output=AST is a rule ref with list addition */
    148 ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
    149 <ruleRefBang(...)>
    150 <listLabelAST(...)>
    151 >>
    152 
    153 /** x+=rule^ */
    154 ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
    155 <ruleRefRuleRoot(...)>
    156 <listLabelAST(...)>
    157 >>
    158 
    159 // WILDCARD AST
    160 
    161 wildcard(token,label,elementIndex,terminalOptions) ::= <<
    162 <super.wildcard(...)>
    163 <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
    164 <label>_tree = (<ASTLabelType>)(ADAPTOR->create(ADAPTOR, <label>));
    165 ADAPTOR->addChild(ADAPTOR, root_0, <label>_tree);
    166 <if(backtracking)>}<endif>
    167 >>
    168 
    169 wildcardBang(token,label,elementIndex,terminalOptions) ::= "<super.wildcard(...)>"
    170 
    171 wildcardRuleRoot(label,elementIndex) ::= <<
    172 <super.wildcard(...)>
    173 <if(backtracking)>if ( <actions.(actionScope).synpredgate> ) {<endif>
    174 <label>_tree = (<ASTLabelType>)(ADAPTOR->create(ADAPTOR, <label>));
    175 root_0 = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <label>_tree, root_0));
    176 <if(backtracking)>}<endif>
    177 >>
    178 
    179 createNodeFromToken(label,terminalOptions) ::= <<
    180 <if(terminalOptions.node)>
    181 <terminalOptions.node>New(<label>) <! new MethodNode(IDLabel) !>
    182 <else>
    183 (<ASTLabelType>)(ADAPTOR->create(ADAPTOR, <label>))
    184 <endif>
    185 >>
    186 
    187 ruleCleanUp() ::= <<
    188 <super.ruleCleanUp()>
    189 <if(backtracking)>
    190 if ( <actions.(actionScope).synpredgate> )
    191 {<\n>
    192 <endif>
    193 <if(!ruleDescriptor.isSynPred)>
    194 	retval.stop = LT(-1);<\n>
    195 <endif>
    196 	retval.tree = (<ASTLabelType>)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
    197 	ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
    198     <ruleDescriptor.allTokenRefsInAltsWithRewrites
    199     :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);}; separator="\n">
    200     <ruleDescriptor.allRuleRefsInAltsWithRewrites
    201     :{it | if (stream_<it> != NULL) stream_<it>->free(stream_<it>);}; separator="\n">
    202 <if(backtracking)>
    203 }<\n>
    204 <endif>
    205 >>
    206