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