mirror of
https://github.com/marcin-szczepanski/jFuzzyLogic.git
synced 2024-12-18 16:35:27 +01:00
remove org folder
This commit is contained in:
parent
473a79359a
commit
07a88ed239
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -1,375 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
interface ANTLRCore;
|
|
||||||
|
|
||||||
/** The overall file structure of a recognizer; stores methods for rules
|
|
||||||
* and cyclic DFAs plus support code.
|
|
||||||
*/
|
|
||||||
outputFile(LEXER,PARSER,TREE_PARSER, actionScope, actions,
|
|
||||||
docComment, recognizer,
|
|
||||||
name, tokens, tokenNames, rules, cyclicDFAs,
|
|
||||||
bitsets, buildTemplate, buildAST, rewriteMode, profile,
|
|
||||||
backtracking, synpreds, memoize, numRules,
|
|
||||||
fileName, ANTLRVersion, generatedTimestamp, trace,
|
|
||||||
scopes, superClass, literals);
|
|
||||||
|
|
||||||
/** The header file; make sure to define headerFileExtension() below */
|
|
||||||
optional
|
|
||||||
headerFile(LEXER,PARSER,TREE_PARSER, actionScope, actions,
|
|
||||||
docComment, recognizer,
|
|
||||||
name, tokens, tokenNames, rules, cyclicDFAs,
|
|
||||||
bitsets, buildTemplate, buildAST, rewriteMode, profile,
|
|
||||||
backtracking, synpreds, memoize, numRules,
|
|
||||||
fileName, ANTLRVersion, generatedTimestamp, trace,
|
|
||||||
scopes, superClass, literals);
|
|
||||||
|
|
||||||
lexer(grammar, name, tokens, scopes, rules, numRules, labelType,
|
|
||||||
filterMode, superClass);
|
|
||||||
|
|
||||||
parser(grammar, name, scopes, tokens, tokenNames, rules, numRules,
|
|
||||||
bitsets, ASTLabelType, superClass,
|
|
||||||
labelType, members);
|
|
||||||
|
|
||||||
/** How to generate a tree parser; same as parser except the input
|
|
||||||
* stream is a different type.
|
|
||||||
*/
|
|
||||||
treeParser(grammar, name, scopes, tokens, tokenNames, globalAction, rules,
|
|
||||||
numRules, bitsets, labelType, ASTLabelType,
|
|
||||||
superClass, members);
|
|
||||||
|
|
||||||
/** A simpler version of a rule template that is specific to the imaginary
|
|
||||||
* rules created for syntactic predicates. As they never have return values
|
|
||||||
* nor parameters etc..., just give simplest possible method. Don't do
|
|
||||||
* any of the normal memoization stuff in here either; it's a waste.
|
|
||||||
* As predicates cannot be inlined into the invoking rule, they need to
|
|
||||||
* be in a rule by themselves.
|
|
||||||
*/
|
|
||||||
synpredRule(ruleName, ruleDescriptor, block, description, nakedBlock);
|
|
||||||
|
|
||||||
/** How to generate code for a rule. This includes any return type
|
|
||||||
* data aggregates required for multiple return values.
|
|
||||||
*/
|
|
||||||
rule(ruleName,ruleDescriptor,block,emptyRule,description,exceptions,finally,memoize);
|
|
||||||
|
|
||||||
/** How to generate a rule in the lexer; naked blocks are used for
|
|
||||||
* fragment rules.
|
|
||||||
*/
|
|
||||||
lexerRule(ruleName,nakedBlock,ruleDescriptor,block,memoize);
|
|
||||||
|
|
||||||
/** How to generate code for the implicitly-defined lexer grammar rule
|
|
||||||
* that chooses between lexer rules.
|
|
||||||
*/
|
|
||||||
tokensRule(ruleName,nakedBlock,args,block,ruleDescriptor);
|
|
||||||
|
|
||||||
filteringNextToken();
|
|
||||||
|
|
||||||
filteringActionGate();
|
|
||||||
|
|
||||||
// S U B R U L E S
|
|
||||||
|
|
||||||
/** A (...) subrule with multiple alternatives */
|
|
||||||
block(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description);
|
|
||||||
|
|
||||||
/** A rule block with multiple alternatives */
|
|
||||||
ruleBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description);
|
|
||||||
|
|
||||||
ruleBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description);
|
|
||||||
|
|
||||||
/** A special case of a (...) subrule with a single alternative */
|
|
||||||
blockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,description);
|
|
||||||
|
|
||||||
/** A (..)+ block with 0 or more alternatives */
|
|
||||||
positiveClosureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description);
|
|
||||||
|
|
||||||
positiveClosureBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description);
|
|
||||||
|
|
||||||
/** A (..)* block with 0 or more alternatives */
|
|
||||||
closureBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description);
|
|
||||||
|
|
||||||
closureBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description);
|
|
||||||
|
|
||||||
/** Optional blocks (x)? are translated to (x|) by before code generation
|
|
||||||
* so we can just use the normal block template
|
|
||||||
*/
|
|
||||||
optionalBlock(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description);
|
|
||||||
|
|
||||||
optionalBlockSingleAlt(alts,decls,decision,enclosingBlockLevel,blockLevel,decisionNumber,maxK,maxAlt,description);
|
|
||||||
|
|
||||||
/** An alternative is just a list of elements; at outermost level */
|
|
||||||
alt(elements,altNum,description,autoAST,outerAlt,treeLevel,rew);
|
|
||||||
|
|
||||||
// E L E M E N T S
|
|
||||||
|
|
||||||
/** match a token optionally with a label in front */
|
|
||||||
tokenRef(token,label,elementIndex,hetero);
|
|
||||||
|
|
||||||
/** ids+=ID */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero);
|
|
||||||
|
|
||||||
listLabel(label,elem);
|
|
||||||
|
|
||||||
/** match a character */
|
|
||||||
charRef(char,label);
|
|
||||||
|
|
||||||
/** match a character range */
|
|
||||||
charRangeRef(a,b,label);
|
|
||||||
|
|
||||||
/** For now, sets are interval tests and must be tested inline */
|
|
||||||
matchSet(s,label,elementIndex,postmatchCode);
|
|
||||||
|
|
||||||
matchSetAndListLabel(s,label,elementIndex,postmatchCode);
|
|
||||||
|
|
||||||
/** Match a string literal */
|
|
||||||
lexerStringRef(string,label);
|
|
||||||
|
|
||||||
wildcard(label,elementIndex);
|
|
||||||
|
|
||||||
wildcardAndListLabel(label,elementIndex);
|
|
||||||
|
|
||||||
/** Match . wildcard in lexer */
|
|
||||||
wildcardChar(label, elementIndex);
|
|
||||||
|
|
||||||
wildcardCharListLabel(label, elementIndex);
|
|
||||||
|
|
||||||
/** Match a rule reference by invoking it possibly with arguments
|
|
||||||
* and a return value or values.
|
|
||||||
*/
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope);
|
|
||||||
|
|
||||||
/** ids+=ID */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope);
|
|
||||||
|
|
||||||
/** A lexer rule reference */
|
|
||||||
lexerRuleRef(rule,label,args,elementIndex,scope);
|
|
||||||
|
|
||||||
/** i+=INT in lexer */
|
|
||||||
lexerRuleRefAndListLabel(rule,label,args,elementIndex,scope);
|
|
||||||
|
|
||||||
/** EOF in the lexer */
|
|
||||||
lexerMatchEOF(label,elementIndex);
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser */
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel);
|
|
||||||
|
|
||||||
/** Every predicate is used as a validating predicate (even when it is
|
|
||||||
* also hoisted into a prediction expression).
|
|
||||||
*/
|
|
||||||
validateSemanticPredicate(pred,description);
|
|
||||||
|
|
||||||
// F i x e d D F A (if-then-else)
|
|
||||||
|
|
||||||
dfaState(k,edges,eotPredictsAlt,description,stateNumber,semPredState);
|
|
||||||
|
|
||||||
/** Same as a normal DFA state except that we don't examine lookahead
|
|
||||||
* for the bypass alternative. It delays error detection but this
|
|
||||||
* is faster, smaller, and more what people expect. For (X)? people
|
|
||||||
* expect "if ( LA(1)==X ) match(X);" and that's it.
|
|
||||||
*
|
|
||||||
* If a semPredState, don't force lookahead lookup; preds might not
|
|
||||||
* need.
|
|
||||||
*/
|
|
||||||
dfaOptionalBlockState(k,edges,eotPredictsAlt,description,stateNumber,semPredState);
|
|
||||||
|
|
||||||
/** A DFA state that is actually the loopback decision of a closure
|
|
||||||
* loop. If end-of-token (EOT) predicts any of the targets then it
|
|
||||||
* should act like a default clause (i.e., no error can be generated).
|
|
||||||
* This is used only in the lexer so that for ('a')* on the end of a
|
|
||||||
* rule anything other than 'a' predicts exiting.
|
|
||||||
*
|
|
||||||
* If a semPredState, don't force lookahead lookup; preds might not
|
|
||||||
* need.
|
|
||||||
*/
|
|
||||||
dfaLoopbackState(k,edges,eotPredictsAlt,description,stateNumber,semPredState);
|
|
||||||
|
|
||||||
/** An accept state indicates a unique alternative has been predicted */
|
|
||||||
dfaAcceptState(alt);
|
|
||||||
|
|
||||||
/** A simple edge with an expression. If the expression is satisfied,
|
|
||||||
* enter to the target state. To handle gated productions, we may
|
|
||||||
* have to evaluate some predicates for this edge.
|
|
||||||
*/
|
|
||||||
dfaEdge(labelExpr, targetState, predicates);
|
|
||||||
|
|
||||||
// F i x e d D F A (switch case)
|
|
||||||
|
|
||||||
/** A DFA state where a SWITCH may be generated. The code generator
|
|
||||||
* decides if this is possible: CodeGenerator.canGenerateSwitch().
|
|
||||||
*/
|
|
||||||
dfaStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState);
|
|
||||||
|
|
||||||
dfaOptionalBlockStateSwitch(k,edges,eotPredictsAlt,description,stateNumber,semPredState);
|
|
||||||
|
|
||||||
dfaLoopbackStateSwitch(k, edges,eotPredictsAlt,description,stateNumber,semPredState);
|
|
||||||
|
|
||||||
dfaEdgeSwitch(labels, targetState);
|
|
||||||
|
|
||||||
// C y c l i c D F A
|
|
||||||
|
|
||||||
/** The code to initiate execution of a cyclic DFA; this is used
|
|
||||||
* in the rule to predict an alt just like the fixed DFA case.
|
|
||||||
* The <name> attribute is inherited via the parser, lexer, ...
|
|
||||||
*/
|
|
||||||
dfaDecision(decisionNumber,description);
|
|
||||||
|
|
||||||
/** Generate the tables and support code needed for the DFAState object
|
|
||||||
* argument. Unless there is a semantic predicate (or syn pred, which
|
|
||||||
* become sem preds), all states should be encoded in the state tables.
|
|
||||||
* Consequently, cyclicDFAState/cyclicDFAEdge,eotDFAEdge templates are
|
|
||||||
* not used except for special DFA states that cannot be encoded as
|
|
||||||
* a transition table.
|
|
||||||
*/
|
|
||||||
cyclicDFA(dfa);
|
|
||||||
|
|
||||||
/** A special state in a cyclic DFA; special means has a semantic predicate
|
|
||||||
* or it's a huge set of symbols to check.
|
|
||||||
*/
|
|
||||||
cyclicDFAState(decisionNumber,stateNumber,edges,needErrorClause,semPredState);
|
|
||||||
|
|
||||||
/** Just like a fixed DFA edge, test the lookahead and indicate what
|
|
||||||
* state to jump to next if successful. Again, this is for special
|
|
||||||
* states.
|
|
||||||
*/
|
|
||||||
cyclicDFAEdge(labelExpr, targetStateNumber, edgeNumber, predicates);
|
|
||||||
|
|
||||||
/** An edge pointing at end-of-token; essentially matches any char;
|
|
||||||
* always jump to the target.
|
|
||||||
*/
|
|
||||||
eotDFAEdge(targetStateNumber,edgeNumber, predicates);
|
|
||||||
|
|
||||||
// D F A E X P R E S S I O N S
|
|
||||||
|
|
||||||
andPredicates(left,right);
|
|
||||||
|
|
||||||
orPredicates(operands);
|
|
||||||
|
|
||||||
notPredicate(pred);
|
|
||||||
|
|
||||||
evalPredicate(pred,description);
|
|
||||||
|
|
||||||
evalSynPredicate(pred,description);
|
|
||||||
|
|
||||||
lookaheadTest(atom,k,atomAsInt);
|
|
||||||
|
|
||||||
/** Sometimes a lookahead test cannot assume that LA(k) is in a temp variable
|
|
||||||
* somewhere. Must ask for the lookahead directly.
|
|
||||||
*/
|
|
||||||
isolatedLookaheadTest(atom,k,atomAsInt);
|
|
||||||
|
|
||||||
lookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt);
|
|
||||||
|
|
||||||
isolatedLookaheadRangeTest(lower,upper,k,rangeNumber,lowerAsInt,upperAsInt);
|
|
||||||
|
|
||||||
setTest(ranges);
|
|
||||||
|
|
||||||
// A T T R I B U T E S
|
|
||||||
|
|
||||||
parameterAttributeRef(attr);
|
|
||||||
parameterSetAttributeRef(attr,expr);
|
|
||||||
|
|
||||||
scopeAttributeRef(scope,attr,index,negIndex);
|
|
||||||
scopeSetAttributeRef(scope,attr,expr,index,negIndex);
|
|
||||||
|
|
||||||
/** $x is either global scope or x is rule with dynamic scope; refers
|
|
||||||
* to stack itself not top of stack. This is useful for predicates
|
|
||||||
* like {$function.size()>0 && $function::name.equals("foo")}?
|
|
||||||
*/
|
|
||||||
isolatedDynamicScopeRef(scope);
|
|
||||||
|
|
||||||
/** reference an attribute of rule; might only have single return value */
|
|
||||||
ruleLabelRef(referencedRule,scope,attr);
|
|
||||||
|
|
||||||
returnAttributeRef(ruleDescriptor,attr);
|
|
||||||
returnSetAttributeRef(ruleDescriptor,attr,expr);
|
|
||||||
|
|
||||||
/** How to translate $tokenLabel */
|
|
||||||
tokenLabelRef(label);
|
|
||||||
|
|
||||||
/** ids+=ID {$ids} or e+=expr {$e} */
|
|
||||||
listLabelRef(label);
|
|
||||||
|
|
||||||
// not sure the next are the right approach; and they are evaluated early;
|
|
||||||
// they cannot see TREE_PARSER or PARSER attributes for example. :(
|
|
||||||
|
|
||||||
tokenLabelPropertyRef_text(scope,attr);
|
|
||||||
tokenLabelPropertyRef_type(scope,attr);
|
|
||||||
tokenLabelPropertyRef_line(scope,attr);
|
|
||||||
tokenLabelPropertyRef_pos(scope,attr);
|
|
||||||
tokenLabelPropertyRef_channel(scope,attr);
|
|
||||||
tokenLabelPropertyRef_index(scope,attr);
|
|
||||||
tokenLabelPropertyRef_tree(scope,attr);
|
|
||||||
|
|
||||||
ruleLabelPropertyRef_start(scope,attr);
|
|
||||||
ruleLabelPropertyRef_stop(scope,attr);
|
|
||||||
ruleLabelPropertyRef_tree(scope,attr);
|
|
||||||
ruleLabelPropertyRef_text(scope,attr);
|
|
||||||
ruleLabelPropertyRef_st(scope,attr);
|
|
||||||
|
|
||||||
/** Isolated $RULE ref ok in lexer as it's a Token */
|
|
||||||
lexerRuleLabel(label);
|
|
||||||
|
|
||||||
lexerRuleLabelPropertyRef_type(scope,attr);
|
|
||||||
lexerRuleLabelPropertyRef_line(scope,attr);
|
|
||||||
lexerRuleLabelPropertyRef_pos(scope,attr);
|
|
||||||
lexerRuleLabelPropertyRef_channel(scope,attr);
|
|
||||||
lexerRuleLabelPropertyRef_index(scope,attr);
|
|
||||||
lexerRuleLabelPropertyRef_text(scope,attr);
|
|
||||||
|
|
||||||
// Somebody may ref $template or $tree or $stop within a rule:
|
|
||||||
rulePropertyRef_start(scope,attr);
|
|
||||||
rulePropertyRef_stop(scope,attr);
|
|
||||||
rulePropertyRef_tree(scope,attr);
|
|
||||||
rulePropertyRef_text(scope,attr);
|
|
||||||
rulePropertyRef_st(scope,attr);
|
|
||||||
|
|
||||||
lexerRulePropertyRef_text(scope,attr);
|
|
||||||
lexerRulePropertyRef_type(scope,attr);
|
|
||||||
lexerRulePropertyRef_line(scope,attr);
|
|
||||||
lexerRulePropertyRef_pos(scope,attr);
|
|
||||||
/** Undefined, but present for consistency with Token attributes; set to -1 */
|
|
||||||
lexerRulePropertyRef_index(scope,attr);
|
|
||||||
lexerRulePropertyRef_channel(scope,attr);
|
|
||||||
lexerRulePropertyRef_start(scope,attr);
|
|
||||||
lexerRulePropertyRef_stop(scope,attr);
|
|
||||||
|
|
||||||
ruleSetPropertyRef_tree(scope,attr,expr);
|
|
||||||
ruleSetPropertyRef_st(scope,attr,expr);
|
|
||||||
|
|
||||||
/** How to execute an action */
|
|
||||||
execAction(action);
|
|
||||||
|
|
||||||
// M I S C (properties, etc...)
|
|
||||||
|
|
||||||
codeFileExtension();
|
|
||||||
|
|
||||||
/** Your language needs a header file; e.g., ".h" */
|
|
||||||
optional headerFileExtension();
|
|
||||||
|
|
||||||
true();
|
|
||||||
false();
|
|
@ -1,391 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
group AST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
<if(!TREE_PARSER)><! tree parser would already have imported !>
|
|
||||||
import org.antlr.runtime.tree.*;<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
<parserMembers()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add an adaptor property that knows how to build trees */
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected var adaptor:TreeAdaptor = new CommonTreeAdaptor();<\n>
|
|
||||||
public function set treeAdaptor(adaptor:TreeAdaptor):void {
|
|
||||||
this.adaptor = adaptor;
|
|
||||||
}
|
|
||||||
public function get treeAdaptor():TreeAdaptor {
|
|
||||||
return adaptor;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
<ASTLabelType> tree;
|
|
||||||
public function get tree():Object { return tree; }
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track rule's return AST */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
var root_0:<ASTLabelType> = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelDefs() ::= <<
|
|
||||||
<super.ruleLabelDefs()>
|
|
||||||
<ruleDescriptor.tokenLabels:{var <it.label.text>_tree:<ASTLabelType>=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{var <it.label.text>_tree:<ASTLabelType>=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{var stream_<it>:RewriteRule<rewriteElementType>Stream=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>");}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{var stream_<it>:RewriteRuleSubtreeStream=new RewriteRuleSubtreeStream(adaptor,"rule <it>");}; separator="\n">
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** When doing auto AST construction, we must define some variables;
|
|
||||||
* These should be turned off if doing rewrites. This must be a "mode"
|
|
||||||
* as a rule could have both rewrite and AST within the same alternative
|
|
||||||
* block.
|
|
||||||
*/
|
|
||||||
@alt.declarations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_0 = <ASTLabelType>(adaptor.nil());<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// T r a c k i n g R u l e E l e m e n t s
|
|
||||||
|
|
||||||
/** ID and track it for use in a rewrite rule */
|
|
||||||
tokenRefTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)> <! Track implies no auto AST construction!>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<token>.add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
|
|
||||||
* to the tracking list stream_ID for use in the rewrite.
|
|
||||||
*/
|
|
||||||
tokenRefTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<token>.add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardTrack(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking==0 ) <endif>stream_<rule.name>.add(<label>.tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefTrack(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<rule>.add(<label>.tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// R e w r i t e
|
|
||||||
|
|
||||||
rewriteCode(
|
|
||||||
alts, description,
|
|
||||||
referencedElementsDeep, // ALL referenced elements to right of ->
|
|
||||||
referencedTokenLabels,
|
|
||||||
referencedTokenListLabels,
|
|
||||||
referencedRuleLabels,
|
|
||||||
referencedRuleListLabels,
|
|
||||||
rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::=
|
|
||||||
<<
|
|
||||||
|
|
||||||
// AST REWRITE
|
|
||||||
// elements: <referencedElementsDeep; separator=", ">
|
|
||||||
// token labels: <referencedTokenLabels; separator=", ">
|
|
||||||
// rule labels: <referencedRuleLabels; separator=", ">
|
|
||||||
// token list labels: <referencedTokenListLabels; separator=", ">
|
|
||||||
// rule list labels: <referencedRuleListLabels; separator=", ">
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( this.state.backtracking==0 ) {<\n>
|
|
||||||
<endif>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<rewriteCodeLabels()>
|
|
||||||
root_0 = <ASTLabelType>(adaptor.nil());
|
|
||||||
<alts:rewriteAlt(); separator="else ">
|
|
||||||
<! if tree parser and rewrite=true !>
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = <ASTLabelType>(adaptor.rulePostProcessing(root_0));
|
|
||||||
input.replaceChildren(adaptor.getParent(retval.start),
|
|
||||||
adaptor.getChildIndex(retval.start),
|
|
||||||
adaptor.getChildIndex(_last),
|
|
||||||
retval.tree);
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<! if parser or rewrite!=true, we need to set result !>
|
|
||||||
<if(!TREE_PARSER)>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabels() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{var stream_<it>:RewriteRule<rewriteElementType>Stream=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>",<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{var stream_<it>:RewriteRule<rewriteElementType>Stream=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>", list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{var stream_<it>:RewriteRuleSubtreeStream=new RewriteRuleSubtreeStream(adaptor,"token <it>",<it>!=null?<it>.tree:null);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{var stream_<it>:RewriteRuleSubtreeStream=new RewriteRuleSubtreeStream(adaptor,"token <it>",list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Generate code for an optional rewrite block; note it uses the deep ref'd element
|
|
||||||
* list rather shallow like other blocks.
|
|
||||||
*/
|
|
||||||
rewriteOptionalBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
if ( <referencedElementsDeep:{el | stream_<el>.hasNext}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElementsDeep:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
while ( <referencedElements:{el | stream_<el>.hasNext}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewritePositiveClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
if ( !(<referencedElements:{el | stream_<el>.hasNext}; separator="||">) ) {
|
|
||||||
throw new RewriteEarlyExitException();
|
|
||||||
}
|
|
||||||
while ( <referencedElements:{el | stream_<el>.hasNext}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteAlt(a) ::= <<
|
|
||||||
// <a.description>
|
|
||||||
<if(a.pred)>
|
|
||||||
if (<a.pred>) {
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** For empty rewrites: "r : ... -> ;" */
|
|
||||||
rewriteEmptyAlt() ::= "root_0 = null;"
|
|
||||||
|
|
||||||
rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
var root_<treeLevel>:<ASTLabelType> = <ASTLabelType>(adaptor.nil());
|
|
||||||
<root:rewriteElement()>
|
|
||||||
<children:rewriteElement()>
|
|
||||||
adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteElementList(elements) ::= "<elements:rewriteElement()>"
|
|
||||||
|
|
||||||
rewriteElement(e) ::= <<
|
|
||||||
<@pregen()>
|
|
||||||
<e.el>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ID or ID[args] */
|
|
||||||
rewriteTokenRef(token,elementIndex,hetero,args) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label=ID */
|
|
||||||
rewriteTokenLabelRef(label,elementIndex) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label+=ID */
|
|
||||||
rewriteTokenListLabelRef(label,elementIndex) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) */
|
|
||||||
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) where label+=... */
|
|
||||||
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
|
|
||||||
|
|
||||||
/** Gen ^(ID ...) or ^(ID[args] ...) */
|
|
||||||
rewriteTokenRefRoot(token,elementIndex,hetero,args) ::= <<
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(<createRewriteNodeFromElement(...)>, root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRef(args,token,hetero,elementIndex) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRefRoot(args,token,hetero,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(<createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
root_0 = <action>;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What is the name of the previous value of this rule's root tree? This
|
|
||||||
* let's us refer to $rule to mean previous value. I am reusing the
|
|
||||||
* variable 'tree' sitting in retval struct to hold the value of root_0 right
|
|
||||||
* before I set it during rewrites. The assign will be to retval.tree.
|
|
||||||
*/
|
|
||||||
prevRuleRootRef() ::= "retval"
|
|
||||||
|
|
||||||
rewriteRuleRef(rule) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<rule>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteRuleRefRoot(rule) ::= <<
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(stream_<rule>.nextNode(), root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeAction(action) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, <action>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeActionRoot(action) ::= <<
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(<action>, root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRef(label) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRef(label) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createImaginaryNode(tokenType,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<! new MethodNode(IDLabel, args) !>
|
|
||||||
new <hetero>(<tokenType><if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<ASTLabelType>(adaptor.create(<tokenType>, <args; separator=", "><if(!args)>"<tokenType>"<endif>))
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createRewriteNodeFromElement(token,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.nextToken()<if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)> <! must create new node from old !>
|
|
||||||
adaptor.create(<token>, <args; separator=", ">)
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during normal parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* The situation is not too bad as rewrite (->) usage makes ^ and !
|
|
||||||
* invalid. There is no huge explosion of combinations.
|
|
||||||
*/
|
|
||||||
group ASTParser;
|
|
||||||
|
|
||||||
@rule.setErrorReturnValue() ::= <<
|
|
||||||
retval.tree = <ASTLabelType>(adaptor.errorNode(input, Token(retval.start), input.LT(-1), re));
|
|
||||||
<! trace("<ruleName> returns "+((CommonTree)retval.tree).toStringTree()); !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID and output=AST */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
adaptor.addChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) */
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>"
|
|
||||||
|
|
||||||
/** ID^ and output=AST */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
root_0 = <ASTLabelType>(adaptor.becomeRoot(<label>_tree, root_0));
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID! and output=AST */
|
|
||||||
tokenRefBangAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN when output=AST but not rewrite alt */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match label+=TOKEN^ when output=AST but not rewrite alt */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
// the match set stuff is interesting in that it uses an argument list
|
|
||||||
// to pass code to the default matchSet; another possible way to alter
|
|
||||||
// inherited code. I don't use the region stuff because I need to pass
|
|
||||||
// different chunks depending on the operator. I don't like making
|
|
||||||
// the template name have the operator as the number of templates gets
|
|
||||||
// large but this is the most flexible--this is as opposed to having
|
|
||||||
// the code generator call matchSet then add root code or ruleroot code
|
|
||||||
// plus list label plus ... The combinations might require complicated
|
|
||||||
// rather than just added on code. Investigate that refactoring when
|
|
||||||
// I have more time.
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( state.backtracking==0 ) <endif>adaptor.addChild(root_0, <createNodeFromToken(...)>);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= "<super.matchSet(...)>"
|
|
||||||
|
|
||||||
// note there is no matchSetTrack because -> rewrites force sets to be
|
|
||||||
// plain old blocks of alts: (A|B|...|C)
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<if(label)>
|
|
||||||
<label>=<labelType>(input.LT(1));<\n>
|
|
||||||
<endif>
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( state.backtracking==0 ) <endif>root_0 = <ASTLabelType>(adaptor.becomeRoot(<createNodeFromToken(...)>, root_0));})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule when output=AST */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>adaptor.addChild(root_0, <label>.tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule! is same as normal rule ref */
|
|
||||||
ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
|
|
||||||
|
|
||||||
/** rule^ */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>root_0 = <ASTLabelType>(adaptor.becomeRoot(<label>.tree, root_0));
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule! when output=AST is a rule ref with list addition */
|
|
||||||
ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefBang(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule^ */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// WILDCARD AST
|
|
||||||
|
|
||||||
wildcard(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = <ASTLabelType>(adaptor.create(<label>));
|
|
||||||
adaptor.addChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>"
|
|
||||||
|
|
||||||
wildcardRuleRoot(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = <ASTLabelType>(adaptor.create(<label>));
|
|
||||||
root_0 = <ASTLabelType>(adaptor.becomeRoot(<label>_tree, root_0));
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createNodeFromToken(label,hetero) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(<label>) <! new MethodNode(IDLabel) !>
|
|
||||||
<else>
|
|
||||||
<ASTLabelType>(adaptor.create(<label>))
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<\n><endif>
|
|
||||||
retval.tree = <ASTLabelType>(adaptor.rulePostProcessing(root_0));
|
|
||||||
adaptor.setTokenBoundaries(retval.tree, Token(retval.start), Token(retval.stop));
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
@ -1,257 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during tree parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* Each combination has its own template except that label/no label
|
|
||||||
* is combined into tokenRef, ruleRef, ...
|
|
||||||
*/
|
|
||||||
group ASTTreeParser;
|
|
||||||
|
|
||||||
/** Add a variable to track last element matched */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
var _first_0:<ASTLabelType> = null;
|
|
||||||
var _last:<ASTLabelType> = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What to emit when there is no rewrite rule. For auto build
|
|
||||||
* mode, does nothing.
|
|
||||||
*/
|
|
||||||
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
retval.tree = <ASTLabelType>(_first_0);
|
|
||||||
if ( adaptor.getParent(retval.tree)!=null && adaptor.isNil( adaptor.getParent(retval.tree) ) )
|
|
||||||
retval.tree = <ASTLabelType>(adaptor.getParent(retval.tree));
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser; override here to
|
|
||||||
* add tree construction actions.
|
|
||||||
*/
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel) ::= <<
|
|
||||||
_last = <ASTLabelType>(input.LT(1));
|
|
||||||
{
|
|
||||||
var _save_last_<treeLevel>:<ASTLabelType> = _last;
|
|
||||||
var _first_<treeLevel>:<ASTLabelType> = null;
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
var root_<treeLevel>:<ASTLabelType> = <ASTLabelType>(adaptor.nil());
|
|
||||||
<endif>
|
|
||||||
<root:element()>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 )<endif>
|
|
||||||
<if(root.el.rule)>
|
|
||||||
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>.tree;
|
|
||||||
<else>
|
|
||||||
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>;
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<actionsAfterRoot:element()>
|
|
||||||
<if(nullableChildList)>
|
|
||||||
if ( input.LA(1)==TokenConstants.DOWN ) {
|
|
||||||
match(input, TokenConstants.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
match(input, TokenConstants.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
match(input, TokenConstants.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
match(input, TokenConstants.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
_last = _save_last_<treeLevel>;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) 'cept add
|
|
||||||
* setting of _last
|
|
||||||
*/
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= <<
|
|
||||||
_last = <ASTLabelType>(input.LT(1));
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID auto construct */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = <ASTLabelType>(input.LT(1));
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = <ASTLabelType>(adaptor.dupNode(<label>));
|
|
||||||
<endif><\n>
|
|
||||||
adaptor.addChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 )<endif>
|
|
||||||
if ( _first_<treeLevel>==null ) _first_<treeLevel> = <label>;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN auto construct */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) auto construct */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = <ASTLabelType>(input.LT(1));
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = <ASTLabelType>(adaptor.dupNode(<label>));
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(<label>_tree, root_<treeLevel>));
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) auto construct */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = <ASTLabelType>(input.LT(1));
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = <ASTLabelType>(adaptor.dupNode(<label>));
|
|
||||||
<endif><\n>
|
|
||||||
adaptor.addChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
<noRewrite()> <! set return tree !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = <ASTLabelType>(input.LT(1));
|
|
||||||
<super.matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = <ASTLabelType>(adaptor.dupNode(<label>));
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(<label>_tree, root_<treeLevel>));
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule auto construct */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = <ASTLabelType>(input.LT(1));
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
adaptor.addChild(root_<treeLevel>, <label>.getTree());
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
if ( _first_<treeLevel>==null ) _first_<treeLevel> = <label>.tree;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule auto construct */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) auto construct */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = <ASTLabelType>(input.LT(1));
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>root_<treeLevel> = <ASTLabelType>(adaptor.becomeRoot(<label>.tree, root_<treeLevel>));
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) auto construct */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Streams for token refs are tree nodes now; override to
|
|
||||||
* change nextToken to nextNode.
|
|
||||||
*/
|
|
||||||
createRewriteNodeFromElement(token,hetero,scope) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.nextNode())
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<\n><endif>
|
|
||||||
retval.tree = <ASTLabelType>(adaptor.rulePostProcessing(root_0));
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,547 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
group AST;
|
|
||||||
|
|
||||||
/** Add an adaptor property that knows how to build trees */
|
|
||||||
@headerFile.members() ::= <<
|
|
||||||
/* @headerFile.members() */
|
|
||||||
pANTLR3_BASE_TREE_ADAPTOR adaptor;
|
|
||||||
pANTLR3_VECTOR_FACTORY vectors;
|
|
||||||
/* End @headerFile.members() */
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Install the tree adaptor interface pointer and anything else that
|
|
||||||
* tree parsers and producers require.
|
|
||||||
*/
|
|
||||||
@genericParser.apifuncs() ::= <<
|
|
||||||
<if(PARSER)>
|
|
||||||
ADAPTOR = ANTLR3_TREE_ADAPTORNew(instream->tstream->tokenSource->strFactory);<\n>
|
|
||||||
<endif>
|
|
||||||
ctx->vectors = antlr3VectorFactoryNew(64);
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.cleanup() ::= <<
|
|
||||||
ctx->vectors->close(ctx->vectors);
|
|
||||||
<if(PARSER)>
|
|
||||||
/* We created the adaptor so we must free it
|
|
||||||
*/
|
|
||||||
ADAPTOR->free(ADAPTOR);
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
|
|
||||||
<recognizer.ASTLabelType> tree;
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track rule's return AST */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> root_0;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleInitializations() ::= <<
|
|
||||||
<super.ruleInitializations()>
|
|
||||||
root_0 = NULL;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelDefs() ::= <<
|
|
||||||
<super.ruleLabelDefs()>
|
|
||||||
<ruleDescriptor.tokenLabels:{<ASTLabelType> <it.label.text>_tree;}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{<ASTLabelType> <it.label.text>_tree;}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;}; separator="\n">
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelInitializations() ::= <<
|
|
||||||
<super.ruleLabelInitializations()>
|
|
||||||
<ruleDescriptor.tokenLabels:{<it.label.text>_tree = NULL;}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{<it.label.text>_tree = NULL;}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{stream_<it> = antlr3RewriteRule<rewriteElementType>StreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>"); }; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{stream_<it>=antlr3RewriteRuleSubtreeStreamNewAE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"rule <it>");}; separator="\n">
|
|
||||||
<if(ruleDescriptor.hasMultipleReturnValues)>
|
|
||||||
retval.tree = NULL;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** a rule label including default value */
|
|
||||||
ruleLabelInitVal(label) ::= <<
|
|
||||||
<super.ruleLabelInitVal(...)>
|
|
||||||
<label.label.text>.tree = <initValue(typeName=ruleLabelType(referencedRule=label.referencedRule))>;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** When doing auto AST construction, we must define some variables;
|
|
||||||
* These should be turned off if doing rewrites. This must be a "mode"
|
|
||||||
* as a rule could have both rewrite and AST within the same alternative
|
|
||||||
* block.
|
|
||||||
*/
|
|
||||||
@alt.declarations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@alt.initializations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_0 = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR));<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
// T r a c k i n g R u l e E l e m e n t s
|
|
||||||
//
|
|
||||||
/** ID but track it for use in a rewrite rule */
|
|
||||||
tokenRefTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)> <! Track implies no auto AST construction!>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) <endif>stream_<token>->add(stream_<token>, <label>, NULL);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
|
|
||||||
* to the tracking list stream_ID for use in the rewrite.
|
|
||||||
*/
|
|
||||||
tokenRefTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) <endif>stream_<token>->add(stream_<token>, <label>, NULL);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardTrack(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) <endif>stream_<rule.name>->add(stream_<rule.name>, <label>.tree, NULL);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefTrack(...)>
|
|
||||||
<listLabelTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) <endif>stream_<rule.name>->add(stream_<rule.name>, <label>.tree, NULL);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRootTrack(...)>
|
|
||||||
<listLabelAST(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
/* How to accumulate lists when we are doing rewrite tracking...
|
|
||||||
*/
|
|
||||||
listLabelTrack(label) ::= <<
|
|
||||||
/* listLabelTrack(label)
|
|
||||||
*/
|
|
||||||
if (list_<label> == NULL)
|
|
||||||
{
|
|
||||||
list_<label>=ctx->vectors->newVector(ctx->vectors);
|
|
||||||
}
|
|
||||||
list_<label>->add(list_<label>, <label>.tree, NULL);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/* How to accumulate lists of rule outputs (only allowed with AST
|
|
||||||
* option but if the user is going to walk the tree, they will want
|
|
||||||
* all their custom elements from rule returns.
|
|
||||||
*
|
|
||||||
* Normally, we use inline structures (which the compiler lays down
|
|
||||||
* code to copy from heap allocations. However, here we want to accumulate copies
|
|
||||||
* of the returned structures because we are adding them to a list. This only makes sense if the
|
|
||||||
* grammar is not rewriting the tree as a tree rewrite only preserves the tree, not the object/structure
|
|
||||||
* returned from the rule. The rewrite will extract the tree pointer. However, if we are not going to
|
|
||||||
* do a tree re-write, then the user may wish to iterate the structures returned by the rule in
|
|
||||||
* action code and will expect the user defined returns[] elements to be available when they do this.
|
|
||||||
* Hence we cannot just preserve the tree that was returned. So, we must copy the local structure and provide
|
|
||||||
* a function that can free the allocated space. We cannot know how to free user allocated elements and
|
|
||||||
* presume that the user will know to do this using their own factories for the structures they allocate.
|
|
||||||
*/
|
|
||||||
listLabelAST(label) ::= <<
|
|
||||||
if (list_<label> == NULL)
|
|
||||||
{
|
|
||||||
list_<label>=ctx->vectors->newVector(ctx->vectors);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
RETURN_TYPE_<label> * tcopy;
|
|
||||||
|
|
||||||
tcopy = ANTLR3_CALLOC(1, sizeof(RETURN_TYPE_<label>)); /* Note no memory allocation checks! */
|
|
||||||
ANTLR3_MEMMOVE((void *)(tcopy), (const void *)&<label>, sizeof(RETURN_TYPE_<label>));
|
|
||||||
list_<label>->add(list_<label>, tcopy, freeScope); /* Add whatever the return type is */<\n>
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
// R e w r i t e
|
|
||||||
|
|
||||||
rewriteCode(
|
|
||||||
alts,
|
|
||||||
description,
|
|
||||||
referencedElementsDeep, // ALL referenced elements to right of ->
|
|
||||||
referencedTokenLabels,
|
|
||||||
referencedTokenListLabels,
|
|
||||||
referencedRuleLabels,
|
|
||||||
referencedRuleListLabels,
|
|
||||||
rewriteBlockLevel,
|
|
||||||
enclosingTreeLevel,
|
|
||||||
treeLevel) ::=
|
|
||||||
<<
|
|
||||||
|
|
||||||
/* AST REWRITE
|
|
||||||
* elements : <referencedElementsDeep; separator=", ">
|
|
||||||
* token labels : <referencedTokenLabels; separator=", ">
|
|
||||||
* rule labels : <referencedRuleLabels; separator=", ">
|
|
||||||
* token list labels : <referencedTokenListLabels; separator=", ">
|
|
||||||
* rule list labels : <referencedRuleListLabels; separator=", ">
|
|
||||||
*/
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( BACKTRACKING==0 ) <\n>
|
|
||||||
<endif>
|
|
||||||
{
|
|
||||||
<rewriteCodeLabelsDecl()>
|
|
||||||
<rewriteCodeLabelsInit()>
|
|
||||||
root_0 = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR));
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<alts:rewriteAlt(); separator="else ">
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = (<ASTLabelType>)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
|
|
||||||
INPUT->replaceChildren(INPUT, ADAPTOR->getParent(ADAPTOR, retval.start),
|
|
||||||
ADAPTOR->getChildIndex(ADAPTOR, retval.start),
|
|
||||||
ADAPTOR->getChildIndex(ADAPTOR, _last),
|
|
||||||
retval.tree);
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<prevRuleRootRef()>.tree = root_0; // set result root
|
|
||||||
<rewriteCodeLabelsFree()>
|
|
||||||
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabelsDecl() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{pANTLR3_REWRITE_RULE_<rewriteElementType>_STREAM stream_<it>;};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{pANTLR3_REWRITE_RULE_SUBTREE_STREAM stream_<it>;};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabelsInit() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{stream_<it>=antlr3RewriteRule<rewriteElementType>StreamNewAEE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", <it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{stream_<it>=antlr3RewriteRule<rewriteElementType>StreamNewAEV(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", list_<it>); };
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{stream_<it>=antlr3RewriteRuleSubtreeStreamNewAEE(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", <it>.tree != NULL ? <it>.tree : NULL);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{stream_<it>=antlr3RewriteRuleSubtreeStreamNewAEV(ADAPTOR, RECOGNIZER, (pANTLR3_UINT8)"token <it>", list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
rewriteCodeLabelsFree() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{stream_<it>->free(stream_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{stream_<it>->free(stream_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{stream_<it>->free(stream_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{stream_<it>->free(stream_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Generate code for an optional rewrite block; note it uses the deep ref'd element
|
|
||||||
* list rather shallow like other blocks.
|
|
||||||
*/
|
|
||||||
rewriteOptionalBlock(
|
|
||||||
alt,
|
|
||||||
rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
if ( <referencedElementsDeep:{el | stream_<el>->hasNext(stream_<el>)}; separator="||"> )
|
|
||||||
{
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElementsDeep:{el | stream_<el>->reset(stream_<el>);<\n>}>
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteClosureBlock(
|
|
||||||
alt,
|
|
||||||
rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
while ( <referencedElements:{el | stream_<el>->hasNext(stream_<el>)}; separator="||"> )
|
|
||||||
{
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>->reset(stream_<el>);<\n>}>
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
RewriteEarlyExitException() ::=
|
|
||||||
<<
|
|
||||||
CONSTRUCTEX();
|
|
||||||
EXCEPTION->type = ANTLR3_REWRITE_EARLY_EXCEPTION;
|
|
||||||
EXCEPTION->name = (void *)ANTLR3_REWRITE_EARLY_EXCEPTION_NAME;
|
|
||||||
>>
|
|
||||||
rewritePositiveClosureBlock(
|
|
||||||
alt,
|
|
||||||
rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
if ( !(<referencedElements:{el | stream_<el>->hasNext(stream_<el>)}; separator="||">) )
|
|
||||||
{
|
|
||||||
<RewriteEarlyExitException()>
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
while ( <referencedElements:{el | stream_<el>->hasNext(stream_<el>)}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>->reset(stream_<el>);<\n>}>
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteAlt(a) ::= <<
|
|
||||||
// <a.description>
|
|
||||||
<if(a.pred)>
|
|
||||||
if (<a.pred>)
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** For empty rewrites: "r : ... -> ;" */
|
|
||||||
rewriteEmptyAlt() ::= "root_0 = NULL; /* \<-- rewriteEmptyAlt()) */"
|
|
||||||
|
|
||||||
rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR));
|
|
||||||
<root:rewriteElement()>
|
|
||||||
<children:rewriteElement()>
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteElementList(elements) ::= "<elements:rewriteElement()>"
|
|
||||||
|
|
||||||
rewriteElement(e) ::= <<
|
|
||||||
<@pregen()>
|
|
||||||
<e.el>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ID or ID[args] */
|
|
||||||
rewriteTokenRef(token,elementIndex,hetero,args) ::= <<
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label=ID */
|
|
||||||
rewriteTokenLabelRef(label,elementIndex) ::= <<
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label>->nextNode(stream_<label>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label+=ID */
|
|
||||||
rewriteTokenListLabelRef(label,elementIndex) ::= <<
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label>->nextNode(stream_<label>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) */
|
|
||||||
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRootToken(ADAPTOR, stream_<label>->nextToken(stream_<label>), root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) where label+=... */
|
|
||||||
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
|
|
||||||
|
|
||||||
/** Gen ^(ID ...) or ^(ID[args] ...) */
|
|
||||||
rewriteTokenRefRoot(token,elementIndex,hetero,args) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createRewriteNodeFromElement(...)>, root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRef(args,token,hetero,elementIndex) ::= <<
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRefRoot(args,token,hetero,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
root_0 = <action>;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What is the name of the previous value of this rule's root tree? This
|
|
||||||
* let's us refer to $rule to mean previous value. I am reusing the
|
|
||||||
* variable 'tree' sitting in retval struct to hold the value of root_0 right
|
|
||||||
* before I set it during rewrites. The assign will be to retval.tree.
|
|
||||||
*/
|
|
||||||
prevRuleRootRef() ::= "retval"
|
|
||||||
|
|
||||||
rewriteRuleRef(rule,dup) ::= <<
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<rule>->nextTree(stream_<rule>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteRuleRefRoot(rule,dup) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, stream_<rule>->nextNode(stream_<rule>), root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeAction(action) ::= <<
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <action>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeActionRoot(action) ::= <<
|
|
||||||
root_<treeLevel> = (<ASLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <action>, root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRef(label) ::= <<
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label>->nextTree(stream_<label>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRef(label) ::= <<
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, stream_<label>->nextTree(stream_<label>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, stream_<label>->nextNode(stream_<label>), root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot((<ASTLabelType>)(stream_<label>->nextNode(stream_<label>), root_<treeLevel>));<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createImaginaryNode(tokenType,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<! new MethodNode(IDLabel, args) !>
|
|
||||||
<hetero>New(<tokenType><if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)>
|
|
||||||
|
|
||||||
#if <length(args)> == 2
|
|
||||||
(<ASTLabelType>)ADAPTOR->createTypeTokenText(ADAPTOR, <tokenType>, TOKTEXT(<args; separator=", ">))
|
|
||||||
#else
|
|
||||||
(<ASTLabelType>)ADAPTOR->createTypeText(ADAPTOR, <tokenType>, (pANTLR3_UINT8)<args; separator=", ">)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)ADAPTOR->createTypeText(ADAPTOR, <tokenType>, (pANTLR3_UINT8)"<tokenType>")
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createRewriteNodeFromElement(token,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<hetero>New(stream_<token>->nextToken(stream_<token>)<if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)> <! must create new node from old !>
|
|
||||||
|
|
||||||
#if <length(args)> == 2
|
|
||||||
ADAPTOR->createTypeTokenText(ADAPTOR, <token>->getType(<token>, TOKTEXT(<token>, <args; separator=", ">)) /* JIMI */
|
|
||||||
#else
|
|
||||||
ADAPTOR->createTypeToken(ADAPTOR, <token>->getType(<token>, <token>, <args; separator=", ">)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
<else>
|
|
||||||
stream_<token>->nextNode(stream_<token>)
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,76 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Template overrides to add debugging to AST stuff. Dynamic inheritance
|
|
||||||
* hierarchy is set up as ASTDbg : AST : Dbg : Java by code generator.
|
|
||||||
*/
|
|
||||||
group ASTDbg;
|
|
||||||
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected DebugTreeAdaptor adaptor =
|
|
||||||
new DebugTreeAdaptor(null,new CommonTreeAdaptor());
|
|
||||||
public void setTreeAdaptor(TreeAdaptor adaptor) {
|
|
||||||
this.adaptor = new DebugTreeAdaptor(dbg,adaptor);
|
|
||||||
}
|
|
||||||
public TreeAdaptor getTreeAdaptor() {
|
|
||||||
return adaptor;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
parserCtorBody() ::= <<
|
|
||||||
<super.parserCtorBody()>
|
|
||||||
adaptor.setDebugListener(dbg);
|
|
||||||
>>
|
|
||||||
|
|
||||||
createListenerAndHandshake() ::= <<
|
|
||||||
DebugEventSocketProxy proxy =
|
|
||||||
new DebugEventSocketProxy(this,port,<if(TREE_PARSER)>input.getTreeAdaptor()<else>adaptor<endif>);
|
|
||||||
adaptor.setDebugListener(proxy);
|
|
||||||
setDebugListener(proxy);
|
|
||||||
set<inputStreamType>(new Debug<inputStreamType>(input,proxy));
|
|
||||||
try {
|
|
||||||
proxy.handshake();
|
|
||||||
}
|
|
||||||
catch (IOException ioe) {
|
|
||||||
reportError(ioe);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForPredefinedListener() ::= <<
|
|
||||||
public <name>(<inputStreamType> input, DebugEventListener dbg) {
|
|
||||||
super(input, dbg);
|
|
||||||
<if(profile)>
|
|
||||||
Profiler p = (Profiler)dbg;
|
|
||||||
p.setParser(this);<\n>
|
|
||||||
<endif>
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@rewriteElement.pregen() ::= "dbg.location(<e.line>,<e.pos>);"
|
|
@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during normal parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* The situation is not too bad as rewrite (->) usage makes ^ and !
|
|
||||||
* invalid. There is no huge explosion of combinations.
|
|
||||||
*/
|
|
||||||
group ASTParser;
|
|
||||||
|
|
||||||
@rule.setErrorReturnValue() ::= <<
|
|
||||||
retval.tree = (<ASTLabelType>)(ADAPTOR->errorNode(ADAPTOR, INPUT, retval.start, LT(-1), EXCEPTION));
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID and output=AST */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) {<endif>
|
|
||||||
<label>_tree = ADAPTOR->create(ADAPTOR, <label>);
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_0, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) */
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>"
|
|
||||||
|
|
||||||
/** ID^ and output=AST */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) {<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
root_0 = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <label>_tree, root_0));
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID! and output=AST */
|
|
||||||
tokenRefBangAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
/** label+=TOKEN when output=AST but not rewrite alt */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
/** Match label+=TOKEN^ when output=AST but not rewrite alt */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
// the match set stuff is interesting in that it uses an argument list
|
|
||||||
// to pass code to the default matchSet; another possible way to alter
|
|
||||||
// inherited code. I don't use the region stuff because I need to pass
|
|
||||||
// different chunks depending on the operator. I don't like making
|
|
||||||
// the template name have the operator as the number of templates gets
|
|
||||||
// large but this is the most flexible--this is as opposed to having
|
|
||||||
// the code generator call matchSet then add root code or ruleroot code
|
|
||||||
// plus list label plus ... The combinations might require complicated
|
|
||||||
// rather than just added on code. Investigate that refactoring when
|
|
||||||
// I have more time.
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( BACKTRACKING==0 ) <endif>ADAPTOR->addChild(ADAPTOR, root_0, <createNodeFromToken(...)>);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= "<super.matchSet(...)>"
|
|
||||||
|
|
||||||
// note there is no matchSetTrack because -> rewrites force sets to be
|
|
||||||
// plain old blocks of alts: (A|B|...|C)
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<if(label)>
|
|
||||||
<label>=(<labelType>)LT(1);<\n>
|
|
||||||
<endif>
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( BACKTRACKING==0 ) <endif>root_0 = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <createNodeFromToken(...)>, root_0));})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule when output=AST */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) <endif>ADAPTOR->addChild(ADAPTOR, root_0, <label>.tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule! is same as normal rule ref */
|
|
||||||
ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
|
|
||||||
|
|
||||||
/** rule^ */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) <endif>root_0 = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <label>.tree, root_0));
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabelAST(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule! when output=AST is a rule ref with list addition */
|
|
||||||
ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefBang(...)>
|
|
||||||
<listLabelAST(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule^ */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabelAST(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// WILDCARD AST
|
|
||||||
|
|
||||||
wildcard(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) {<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)(ADAPTOR->create(ADAPTOR, <label>));
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_0, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>"
|
|
||||||
|
|
||||||
wildcardRuleRoot(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING==0 ) {<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)(ADAPTOR->create(ADAPTOR, <label>));
|
|
||||||
root_0 = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <label>_tree, root_0));
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createNodeFromToken(label,hetero) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<hetero>New(<label>) <! new MethodNode(IDLabel) !>
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)(ADAPTOR->create(ADAPTOR, <label>))
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( BACKTRACKING==0 ) {<\n>
|
|
||||||
<endif>
|
|
||||||
|
|
||||||
<if(!ruleDescriptor.isSynPred)>
|
|
||||||
retval.stop = LT(-1);<\n>
|
|
||||||
<endif>
|
|
||||||
retval.tree = (<ASTLabelType>)(ADAPTOR->rulePostProcessing(ADAPTOR, root_0));
|
|
||||||
ADAPTOR->setTokenBoundaries(ADAPTOR, retval.tree, retval.start, retval.stop);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{stream_<it>->free(stream_<it>);}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{stream_<it>->free(stream_<it>);}; separator="\n">
|
|
||||||
>>
|
|
@ -1,309 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during tree parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* Each combination has its own template except that label/no label
|
|
||||||
* is combined into tokenRef, ruleRef, ...
|
|
||||||
*/
|
|
||||||
group ASTTreeParser;
|
|
||||||
|
|
||||||
/** Add a variable to track last element matched */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> _last;<\n>
|
|
||||||
<ASTLabelType> _first_0;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track last element matched */
|
|
||||||
ruleInitializations() ::= <<
|
|
||||||
<super.ruleInitializations()>
|
|
||||||
_last = NULL;<\n>
|
|
||||||
_first_0 = NULL;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What to emit when there is no rewrite rule. For auto build
|
|
||||||
* mode, does nothing.
|
|
||||||
*/
|
|
||||||
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
|
|
||||||
<if(backtracking)>if ( BACKTRACKING ==0 ) {<endif>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
retval.tree = (<ASTLabelType>)_first_0;
|
|
||||||
if ( ADAPTOR->getParent(ADAPTOR, retval.tree) != NULL && ADAPTOR->isNilNode(ADAPTOR, ADAPTOR->getParent(ADAPTOR, retval.tree) ) )
|
|
||||||
{
|
|
||||||
retval.tree = (<ASTLabelType>)ADAPTOR->getParent(ADAPTOR, retval.tree);
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser; override here to
|
|
||||||
* add tree construction actions.
|
|
||||||
*/
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
{
|
|
||||||
<ASTLabelType> _save_last_<treeLevel>;
|
|
||||||
<ASTLabelType> _first_last_<treeLevel>;
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<ASTLabelType> root_<treeLevel>;
|
|
||||||
<endif>
|
|
||||||
_save_last_<treeLevel> = _last;
|
|
||||||
_first_last_<treeLevel> = NULL;
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->nilNode(ADAPTOR));
|
|
||||||
<endif>
|
|
||||||
<root:element()>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING ==0 ) {<endif>
|
|
||||||
<if(root.el.rule)>
|
|
||||||
if ( _first_<enclosingTreeLevel> == NULL ) _first_<enclosingTreeLevel> = <root.el.label>.tree;
|
|
||||||
<else>
|
|
||||||
if ( _first_<enclosingTreeLevel> == NULL ) _first_<enclosingTreeLevel> = <root.el.label>;
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
<actionsAfterRoot:element()>
|
|
||||||
<if(nullableChildList)>
|
|
||||||
if ( LA(1)==ANTLR3_TOKEN_DOWN ) {
|
|
||||||
MATCHT(ANTLR3_TOKEN_DOWN, NULL);
|
|
||||||
<children:element()>
|
|
||||||
MATCHT(ANTLR3_TOKEN_UP, NULL);
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
MATCHT(ANTLR3_TOKEN_DOWN, NULL);
|
|
||||||
<children:element()>
|
|
||||||
MATCHT(ANTLR3_TOKEN_UP, NULL);
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
_last = _save_last_<treeLevel>;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) 'cept add
|
|
||||||
* setting of _last
|
|
||||||
*/
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID auto construct */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING ==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = <hetero>New(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)ADAPTOR->dupNode(ADAPTOR, <label>);
|
|
||||||
<endif>
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<else>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING ==0 ) {<endif>
|
|
||||||
if ( _first_<treeLevel> == NULL ) _first_<treeLevel> = <label>;
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN auto construct */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) auto construct */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING == 0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = <hetero>New(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)ADAPTOR->dupNode(ADAPTOR, <label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)ADAPTOR->becomeRoot(ADAPTOR, <label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) auto construct */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING == 0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = <hetero>New(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)ADAPTOR->dupNode(ADAPTOR, <label>);
|
|
||||||
<endif><\n>
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
<noRewrite()> <! set return tree !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING == 0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = <hetero>New(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)ADAPTOR->dupNode(ADAPTOR, <label>);
|
|
||||||
<endif>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)ADAPTOR->becomeRoot(ADAPTOR, <label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule auto construct */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
ADAPTOR->addChild(ADAPTOR, root_<treeLevel>, <label>.tree);
|
|
||||||
<else>
|
|
||||||
if ( _first_<treeLevel> == NULL ) _first_<treeLevel> = <label>.tree;
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule auto construct */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<super.listLabelAST(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) auto construct */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( BACKTRACKING == 0 ) <endif>root_<treeLevel> = (<ASTLabelType>)(ADAPTOR->becomeRoot(ADAPTOR, <label>.tree, root_<treeLevel>));
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) auto construct */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<super.listLabelAST(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.ruleRefTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.ruleRefTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.ruleRefRootTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)LT(1);
|
|
||||||
<super.ruleRefRuleRootTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
/** Streams for token refs are tree nodes now; override to
|
|
||||||
* change nextToken to nextNode.
|
|
||||||
*/
|
|
||||||
createRewriteNodeFromElement(token,hetero,scope) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<hetero>New(stream_<token>->nextNode(stream_<token>))
|
|
||||||
<else>
|
|
||||||
stream_<token>->nextNode(stream_<token>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( BACKTRACKING==0 ) {<\n>
|
|
||||||
<endif>
|
|
||||||
<if(!ruleDescriptor.isSynPred)>
|
|
||||||
retval.stop = LT(-1);<\n>
|
|
||||||
<endif>
|
|
||||||
retval.tree = ADAPTOR->rulePostProcessing(ADAPTOR, root_0);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{stream_<it>->free(stream_<it>);}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{stream_<it>->free(stream_<it>);}; separator="\n">
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,250 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template overrides to add debugging to normal C output;
|
|
||||||
* If ASTs are built, then you'll also get ASTDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group Dbg;
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
const char *
|
|
||||||
ruleNames[] =
|
|
||||||
{
|
|
||||||
"invalidRule", <grammar.allImportedRules:{rST | "<rST.name>"}; wrap="\n ", separator=", ">
|
|
||||||
};<\n>
|
|
||||||
<endif>
|
|
||||||
<if(grammar.grammarIsRoot)> <! grammar imports other grammar(s) !>
|
|
||||||
static ANTLR3_UINT32 ruleLevel = 0;
|
|
||||||
static ANTLR3_UINT32 getRuleLevel()
|
|
||||||
{
|
|
||||||
return ruleLevel;
|
|
||||||
}
|
|
||||||
static void incRuleLevel()
|
|
||||||
{
|
|
||||||
ruleLevel++;
|
|
||||||
}
|
|
||||||
static void decRuleLevel()
|
|
||||||
{
|
|
||||||
ruleLevel--;
|
|
||||||
}
|
|
||||||
<else> <! imported grammar !>
|
|
||||||
static ANTLR3_UINT32
|
|
||||||
getRuleLevel()
|
|
||||||
{
|
|
||||||
return <grammar.delegators:{g| <g:delegateName()>}>->getRuleLevel();
|
|
||||||
}
|
|
||||||
static void incRuleLevel()
|
|
||||||
{
|
|
||||||
<grammar.delegators:{g| <g:delegateName()>}>->incRuleLevel();
|
|
||||||
}
|
|
||||||
static void
|
|
||||||
decRuleLevel()
|
|
||||||
{
|
|
||||||
<grammar.delegators:{g| <g:delegateName()>}>.decRuleLevel();
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<if(profile)>
|
|
||||||
// Profiling not yet implemented for C target
|
|
||||||
//
|
|
||||||
<endif>
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
<ctorForPredefinedListener()>
|
|
||||||
<else>
|
|
||||||
<ctorForDelegateGrammar()>
|
|
||||||
<endif>
|
|
||||||
|
|
||||||
static ANTLR3_BOOLEAN
|
|
||||||
evalPredicate(p<name> ctx, ANTLR3_BOOLEAN result, const char * predicate)
|
|
||||||
{
|
|
||||||
DBG->semanticPredicate(DBG, result, predicate);
|
|
||||||
return result;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.debugStuff() ::= <<
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
<createListenerAndHandshake()>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForProfilingRootGrammar() ::= <<
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Basically we don't want to set any dbg listeners as root will have it. */
|
|
||||||
ctorForDelegateGrammar() ::= <<
|
|
||||||
//public <name>(<inputStreamType> input, DebugEventListener dbg, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) {
|
|
||||||
// super(input, dbg, state);
|
|
||||||
//parserCtorBody()
|
|
||||||
// <grammar.directDelegates:
|
|
||||||
{g|<g:delegateName()> = new <g.recognizerName>(input, this, state<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
//}
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForPredefinedListener() ::= <<
|
|
||||||
//public <name>(<inputStreamType> input, DebugEventListener dbg) {
|
|
||||||
// super(input, dbg, new RecognizerSharedState());
|
|
||||||
//<if(profile)>
|
|
||||||
// Profiler p = (Profiler)dbg;
|
|
||||||
// p.setParser(this);
|
|
||||||
//<endif>
|
|
||||||
// //parserCtorBody()
|
|
||||||
// <grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
//}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createListenerAndHandshake() ::= <<
|
|
||||||
{
|
|
||||||
// DEBUG MODE code
|
|
||||||
//
|
|
||||||
pANTLR3_DEBUG_EVENT_LISTENER proxy;
|
|
||||||
proxy = antlr3DebugListenerNew();
|
|
||||||
proxy->grammarFileName = INPUT->tokenSource->strFactory->newStr8(INPUT->tokenSource->strFactory, (pANTLR3_UINT8)ctx->getGrammarFileName());
|
|
||||||
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
proxy->adaptor = ADAPTOR;
|
|
||||||
<endif>
|
|
||||||
PARSER->setDebugListener(PARSER, proxy);
|
|
||||||
|
|
||||||
// Try to connect to the debugger (waits forever for a connection)
|
|
||||||
//
|
|
||||||
proxy->handshake(proxy);
|
|
||||||
|
|
||||||
// End DEBUG MODE code
|
|
||||||
//
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
@rule.preamble() ::= <<
|
|
||||||
DBG->enterRule(DBG, getGrammarFileName(), (const char *)"<ruleName>");
|
|
||||||
if ( getRuleLevel()==0 )
|
|
||||||
{
|
|
||||||
DBG->commence(DBG);
|
|
||||||
}
|
|
||||||
incRuleLevel();
|
|
||||||
DBG->location(DBG, <ruleDescriptor.tree.line>, <ruleDescriptor.tree.column>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@rule.postamble() ::= <<
|
|
||||||
DBG->location(DBG, <ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.column>);<\n>
|
|
||||||
DBG->exitRule(DBG, getGrammarFileName(), (const char *)"<ruleName>");
|
|
||||||
decRuleLevel();
|
|
||||||
if ( getRuleLevel()==0 )
|
|
||||||
{
|
|
||||||
DBG->terminate(DBG);
|
|
||||||
}
|
|
||||||
<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@synpred.start() ::= "DBG->beginBacktrack(DBG, BACKTRACKING);"
|
|
||||||
|
|
||||||
@synpred.stop() ::= "DBG->endBacktrack(DBG, BACKTRACKING, success);"
|
|
||||||
|
|
||||||
// Common debug event triggers used by region overrides below
|
|
||||||
|
|
||||||
enterSubRule() ::=
|
|
||||||
"DBG->enterSubRule(DBG, <decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
exitSubRule() ::=
|
|
||||||
"DBG->exitSubRule(DBG, <decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
enterDecision() ::=
|
|
||||||
"DBG->enterDecision(DBG, <decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
exitDecision() ::=
|
|
||||||
"DBG->exitDecision(DBG, <decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
enterAlt(n) ::= "DBG->enterAlt(DBG, <n>);<\n>"
|
|
||||||
|
|
||||||
// Region overrides that tell various constructs to add debugging triggers
|
|
||||||
|
|
||||||
@block.predecision() ::= "<enterSubRule()><enterDecision()>"
|
|
||||||
|
|
||||||
@block.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@block.postbranch() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@ruleBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@ruleBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@ruleBlockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@blockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.earlyExitException() ::=
|
|
||||||
"DBG->recognitionException(DBG, EXCEPTION);<\n>"
|
|
||||||
|
|
||||||
@closureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@closureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@altSwitchCase.prealt() ::= "<enterAlt(n=i)>"
|
|
||||||
|
|
||||||
@element.prematch() ::=
|
|
||||||
"DBG->location(DBG, <it.line>, <it.pos>);"
|
|
||||||
|
|
||||||
@matchSet.mismatchedSetException() ::=
|
|
||||||
"DBG->recognitionException(DBG, EXCEPTION);"
|
|
||||||
|
|
||||||
@newNVException.noViableAltException() ::= "DBG->recognitionException(DBG, EXCEPTION);"
|
|
||||||
|
|
||||||
dfaDecision(decisionNumber,description) ::= <<
|
|
||||||
alt<decisionNumber> = cdfa<decisionNumber>.predict(ctx, RECOGNIZER, ISTREAM, &cdfa<decisionNumber>);
|
|
||||||
if (HASEXCEPTION())
|
|
||||||
{
|
|
||||||
DBG->recognitionException(DBG, EXCEPTION);
|
|
||||||
goto rule<ruleDescriptor.name>Ex;
|
|
||||||
}
|
|
||||||
<checkRuleBacktrackFailure()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.errorMethod() ::= <<
|
|
||||||
//static void
|
|
||||||
//dfaError(p<name> ctx)
|
|
||||||
//{
|
|
||||||
// DBG->recognitionException(DBG, EXCEPTION);
|
|
||||||
//}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Force predicate validation to trigger an event */
|
|
||||||
evalPredicate(pred,description) ::= <<
|
|
||||||
evalPredicate(ctx, <pred>, (const char *)"<description>")
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,403 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
group AST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
<if(!TREE_PARSER)><! tree parser would already have imported !>
|
|
||||||
using Antlr.Runtime.Tree;<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
<parserMembers()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add an adaptor property that knows how to build trees */
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected ITreeAdaptor adaptor = new CommonTreeAdaptor();<\n>
|
|
||||||
public ITreeAdaptor TreeAdaptor
|
|
||||||
{
|
|
||||||
get { return this.adaptor; }
|
|
||||||
set {
|
|
||||||
this.adaptor = value;
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()>.TreeAdaptor = this.adaptor;}>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
private <ASTLabelType> tree;
|
|
||||||
override public object Tree
|
|
||||||
{
|
|
||||||
get { return tree; }
|
|
||||||
set { tree = (<ASTLabelType>) value; }
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track rule's return AST */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> root_0 = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelDefs() ::= <<
|
|
||||||
<super.ruleLabelDefs()>
|
|
||||||
<ruleDescriptor.tokenLabels:{<ASTLabelType> <it.label.text>_tree=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{<ASTLabelType> <it.label.text>_tree=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it> = new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>");}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it> = new RewriteRuleSubtreeStream(adaptor,"rule <it>");}; separator="\n">
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** When doing auto AST construction, we must define some variables;
|
|
||||||
* These should be turned off if doing rewrites. This must be a "mode"
|
|
||||||
* as a rule could have both rewrite and AST within the same alternative
|
|
||||||
* block.
|
|
||||||
*/
|
|
||||||
@alt.declarations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.GetNilNode();<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// T r a c k i n g R u l e E l e m e n t s
|
|
||||||
|
|
||||||
/** ID and track it for use in a rewrite rule */
|
|
||||||
tokenRefTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)> <! Track implies no auto AST construction!>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<token>.Add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
|
|
||||||
* to the tracking list stream_ID for use in the rewrite.
|
|
||||||
*/
|
|
||||||
tokenRefTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<token>.Add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardTrack(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<rule.name>.Add(<label>.Tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefTrack(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<rule>.Add(<label>.Tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// R e w r i t e
|
|
||||||
|
|
||||||
rewriteCode(
|
|
||||||
alts, description,
|
|
||||||
referencedElementsDeep, // ALL referenced elements to right of ->
|
|
||||||
referencedTokenLabels,
|
|
||||||
referencedTokenListLabels,
|
|
||||||
referencedRuleLabels,
|
|
||||||
referencedRuleListLabels,
|
|
||||||
rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::=
|
|
||||||
<<
|
|
||||||
|
|
||||||
// AST REWRITE
|
|
||||||
// elements: <referencedElementsDeep; separator=", ">
|
|
||||||
// token labels: <referencedTokenLabels; separator=", ">
|
|
||||||
// rule labels: <referencedRuleLabels; separator=", ">
|
|
||||||
// token list labels: <referencedTokenListLabels; separator=", ">
|
|
||||||
// rule list labels: <referencedRuleListLabels; separator=", ">
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 ) {<\n>
|
|
||||||
<endif>
|
|
||||||
<prevRuleRootRef()>.Tree = root_0;
|
|
||||||
<rewriteCodeLabels()>
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.GetNilNode();
|
|
||||||
<alts:rewriteAlt(); separator="else ">
|
|
||||||
<! if tree parser and rewrite=true !>
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.Tree = (<ASTLabelType>)adaptor.rulePostProcessing(root_0);
|
|
||||||
input.ReplaceChildren(adaptor.GetParent(retval.Start),
|
|
||||||
adaptor.GetChildIndex(retval.Start),
|
|
||||||
adaptor.GetChildIndex(_last),
|
|
||||||
retval.Tree);
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<! if parser or rewrite!=true, we need to set result !>
|
|
||||||
<if(!TREE_PARSER)>
|
|
||||||
<prevRuleRootRef()>.Tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.Tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabels() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it> = new RewriteRule<rewriteElementType>Stream(adaptor, "token <it>", <it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it> = new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>", list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it> = new RewriteRuleSubtreeStream(adaptor, "token <it>", (<it>!=null ? <it>.Tree : null));};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it> = new RewriteRuleSubtreeStream(adaptor, "token <it>", list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Generate code for an optional rewrite block; note it uses the deep ref'd element
|
|
||||||
* list rather shallow like other blocks.
|
|
||||||
*/
|
|
||||||
rewriteOptionalBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
if ( <referencedElementsDeep:{el | stream_<el>.HasNext()}; separator=" || "> )
|
|
||||||
{
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElementsDeep:{el | stream_<el>.Reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
while ( <referencedElements:{el | stream_<el>.HasNext()}; separator=" || "> )
|
|
||||||
{
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.Reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewritePositiveClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
if ( !(<referencedElements:{el | stream_<el>.HasNext()}; separator=" || ">) ) {
|
|
||||||
throw new RewriteEarlyExitException();
|
|
||||||
}
|
|
||||||
while ( <referencedElements:{el | stream_<el>.HasNext()}; separator=" || "> )
|
|
||||||
{
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.Reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteAlt(a) ::= <<
|
|
||||||
// <a.description>
|
|
||||||
<if(a.pred)>
|
|
||||||
if (<a.pred>)
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** For empty rewrites: "r : ... -> ;" */
|
|
||||||
rewriteEmptyAlt() ::= "root_0 = null;"
|
|
||||||
|
|
||||||
rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)adaptor.GetNilNode();
|
|
||||||
<root:rewriteElement()>
|
|
||||||
<children:rewriteElement()>
|
|
||||||
adaptor.AddChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteElementList(elements) ::= "<elements:rewriteElement()>"
|
|
||||||
|
|
||||||
rewriteElement(e) ::= <<
|
|
||||||
<@pregen()>
|
|
||||||
<e.el>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ID or ID[args] */
|
|
||||||
rewriteTokenRef(token,elementIndex,hetero,args) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label=ID */
|
|
||||||
rewriteTokenLabelRef(label,elementIndex) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<label>.NextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label+=ID */
|
|
||||||
rewriteTokenListLabelRef(label,elementIndex) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<label>.NextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) */
|
|
||||||
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) where label+=... */
|
|
||||||
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
|
|
||||||
|
|
||||||
/** Gen ^(ID ...) or ^(ID[args] ...) */
|
|
||||||
rewriteTokenRefRoot(token,elementIndex,hetero,args) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<createRewriteNodeFromElement(...)>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRef(args,token,hetero,elementIndex) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRefRoot(args,token,hetero,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
root_0 = <action>;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What is the name of the previous value of this rule's root tree? This
|
|
||||||
* let's us refer to $rule to mean previous value. I am reusing the
|
|
||||||
* variable 'tree' sitting in retval struct to hold the value of root_0 right
|
|
||||||
* before I set it during rewrites. The assign will be to retval.Tree.
|
|
||||||
*/
|
|
||||||
prevRuleRootRef() ::= "retval"
|
|
||||||
|
|
||||||
rewriteRuleRef(rule) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<rule>.NextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteRuleRefRoot(rule) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<rule>.NextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeAction(action) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <action>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeActionRoot(action) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<action>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRef(label) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<label>.NextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRef(label) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<label>.NextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createImaginaryNode(tokenType,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<! new MethodNode(IDLabel, args) !>
|
|
||||||
new <hetero>(<tokenType><if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)adaptor.Create(<tokenType>, <args; separator=", "><if(!args)>"<tokenType>"<endif>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createRewriteNodeFromElement(token,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.NextToken()<if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)> <! must create new node from old !>
|
|
||||||
adaptor.Create(<token>, <args; separator=", ">)
|
|
||||||
<else>
|
|
||||||
stream_<token>.NextNode()
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Template overrides to add debugging to AST stuff. Dynamic inheritance
|
|
||||||
* hierarchy is set up as ASTDbg : AST : Dbg : C# by code generator.
|
|
||||||
*/
|
|
||||||
group ASTDbg;
|
|
||||||
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected DebugTreeAdaptor adaptor;
|
|
||||||
public ITreeAdaptor TreeAdaptor
|
|
||||||
{
|
|
||||||
get {
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
return this.adaptor;
|
|
||||||
<else>
|
|
||||||
this.adaptor = (DebugTreeAdaptor)adaptor; // delegator sends dbg adaptor
|
|
||||||
<endif><\n>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()>.TreeAdaptor = this.adaptor;}>
|
|
||||||
}
|
|
||||||
set { this.adaptor = new DebugTreeAdaptor(dbg, value); }
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
parserCtorBody() ::= <<
|
|
||||||
<super.parserCtorBody()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createListenerAndHandshake() ::= <<
|
|
||||||
DebugEventSocketProxy proxy = new DebugEventSocketProxy(this, port, adaptor);
|
|
||||||
DebugListener = proxy;
|
|
||||||
<!
|
|
||||||
Original line follows, replaced by the next two ifs:
|
|
||||||
set<inputStreamType>(new Debug<inputStreamType>(input,proxy));
|
|
||||||
!>
|
|
||||||
<if(PARSER)>
|
|
||||||
TokenStream = new DebugTokenStream(input,proxy);<\n>
|
|
||||||
<endif>
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
TokenStream = new DebugTreeNodeStream(input,proxy);<\n>
|
|
||||||
<endif>
|
|
||||||
try {
|
|
||||||
proxy.Handshake();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
ReportError(ioe);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForRootGrammar.finally() ::= <<
|
|
||||||
ITreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
TreeAdaptor = adap;
|
|
||||||
proxy.TreeAdaptor = adap;
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForProfilingRootGrammar.finally() ::=<<
|
|
||||||
ITreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
TreeAdaptor = adap;
|
|
||||||
proxy.TreeAdaptor = adap;
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForPredefinedListener.superClassRef() ::= "base(input, dbg)"
|
|
||||||
|
|
||||||
@ctorForPredefinedListener.finally() ::=<<
|
|
||||||
<if(grammar.grammarIsRoot)> <! don't create new adaptor for delegates !>
|
|
||||||
ITreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
TreeAdaptor = adap;<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@rewriteElement.pregen() ::= "dbg.Location(<e.line>,<e.pos>);"
|
|
@ -1,220 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during normal parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* The situation is not too bad as rewrite (->) usage makes ^ and !
|
|
||||||
* invalid. There is no huge explosion of combinations.
|
|
||||||
*/
|
|
||||||
group ASTParser;
|
|
||||||
|
|
||||||
@rule.setErrorReturnValue() ::= <<
|
|
||||||
// Conversion of the second argument necessary, but harmless
|
|
||||||
retval.Tree = (<ASTLabelType>)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re);
|
|
||||||
<! System.Console.WriteLine("<ruleName> returns " + ((CommonTree)retval.Tree).ToStringTree()); !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID and output=AST */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
adaptor.AddChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) */
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>"
|
|
||||||
|
|
||||||
/** ID^ and output=AST */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID! and output=AST */
|
|
||||||
tokenRefBangAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN when output=AST but not rewrite alt */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match label+=TOKEN^ when output=AST but not rewrite alt */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
// the match set stuff is interesting in that it uses an argument list
|
|
||||||
// to pass code to the default matchSet; another possible way to alter
|
|
||||||
// inherited code. I don't use the region stuff because I need to pass
|
|
||||||
// different chunks depending on the operator. I don't like making
|
|
||||||
// the template name have the operator as the number of templates gets
|
|
||||||
// large but this is the most flexible--this is as opposed to having
|
|
||||||
// the code generator call matchSet then add root code or ruleroot code
|
|
||||||
// plus list label plus ... The combinations might require complicated
|
|
||||||
// rather than just added on code. Investigate that refactoring when
|
|
||||||
// I have more time.
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( state.backtracking == 0 ) <endif>adaptor.AddChild(root_0, <createNodeFromToken(...)>);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= "<super.matchSet(...)>"
|
|
||||||
|
|
||||||
// note there is no matchSetTrack because -> rewrites force sets to be
|
|
||||||
// plain old blocks of alts: (A|B|...|C)
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<if(label)>
|
|
||||||
<label>=(<labelType>)input.LT(1);<\n>
|
|
||||||
<endif>
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( state.backtracking == 0 ) <endif>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<createNodeFromToken(...)>, root_0);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule when output=AST */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking == 0 ) <endif>adaptor.AddChild(root_0, <label>.Tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule! is same as normal rule ref */
|
|
||||||
ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
|
|
||||||
|
|
||||||
/** rule^ */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking == 0 ) <endif>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>.Tree, root_0);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule! when output=AST is a rule ref with list addition */
|
|
||||||
ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefBang(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule^ */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// WILDCARD AST
|
|
||||||
|
|
||||||
wildcard(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.Create(<label>);
|
|
||||||
adaptor.AddChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>"
|
|
||||||
|
|
||||||
wildcardRuleRoot(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.Create(<label>);
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createNodeFromToken(label,hetero) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(<label>) <! new MethodNode(IDLabel) !>
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)adaptor.Create(<label>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
retval.Tree = (<ASTLabelType>)adaptor.RulePostProcessing(root_0);
|
|
||||||
<if(!TREE_PARSER)>
|
|
||||||
adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,299 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during tree parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* Each combination has its own template except that label/no label
|
|
||||||
* is combined into tokenRef, ruleRef, ...
|
|
||||||
*/
|
|
||||||
group ASTTreeParser;
|
|
||||||
|
|
||||||
/** Add a variable to track last element matched */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> _first_0 = null;
|
|
||||||
<ASTLabelType> _last = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What to emit when there is no rewrite rule. For auto build
|
|
||||||
* mode, does nothing.
|
|
||||||
*/
|
|
||||||
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
retval.Tree = (<ASTLabelType>)_first_0;
|
|
||||||
if ( adaptor.GetParent(retval.Tree)!=null && adaptor.IsNil( adaptor.GetParent(retval.Tree) ) )
|
|
||||||
retval.Tree = (<ASTLabelType>)adaptor.GetParent(retval.Tree);
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser; override here to
|
|
||||||
* add tree construction actions.
|
|
||||||
*/
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
{
|
|
||||||
<ASTLabelType> _save_last_<treeLevel> = _last;
|
|
||||||
<ASTLabelType> _first_<treeLevel> = null;
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)adaptor.GetNilNode();
|
|
||||||
<endif>
|
|
||||||
<root:element()>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 )<endif>
|
|
||||||
<if(root.el.rule)>
|
|
||||||
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>.Tree;
|
|
||||||
<else>
|
|
||||||
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>;
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<actionsAfterRoot:element()>
|
|
||||||
<if(nullableChildList)>
|
|
||||||
if ( input.LA(1) == Token.DOWN )
|
|
||||||
{
|
|
||||||
Match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
Match(input, Token.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
Match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
Match(input, Token.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
adaptor.AddChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
_last = _save_last_<treeLevel>;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) 'cept add
|
|
||||||
* setting of _last
|
|
||||||
*/
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID auto construct */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.DupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 )<endif>
|
|
||||||
if ( _first_<treeLevel>==null ) _first_<treeLevel> = <label>;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN auto construct */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) auto construct */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.DupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) auto construct */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.DupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
<noRewrite()> <! set return tree !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.DupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule auto construct */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <label>.Tree);
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
if ( _first_<treeLevel>==null ) _first_<treeLevel> = <label>.Tree;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule auto construct */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) auto construct */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking == 0 ) <endif>root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<label>.Tree, root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) auto construct */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefRootTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefRuleRootTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Streams for token refs are tree nodes now; override to
|
|
||||||
* change nextToken to nextNode.
|
|
||||||
*/
|
|
||||||
createRewriteNodeFromElement(token,hetero,scope) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.NextNode())
|
|
||||||
<else>
|
|
||||||
stream_<token>.NextNode()
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
retval.Tree = (<ASTLabelType>)adaptor.RulePostProcessing(root_0);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,288 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template overrides to add debugging to normal Java output;
|
|
||||||
* If ASTs are built, then you'll also get ASTDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group Dbg;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
using Antlr.Runtime.Debug;
|
|
||||||
using IOException = System.IO.IOException;
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
public static readonly string[] ruleNames = new string[] {
|
|
||||||
"invalidRule", <grammar.allImportedRules:{rST | "<rST.name>"}; wrap="\n ", separator=", ">
|
|
||||||
};<\n>
|
|
||||||
<endif>
|
|
||||||
<if(grammar.grammarIsRoot)> <! grammar imports other grammar(s) !>
|
|
||||||
private int ruleLevel = 0;
|
|
||||||
public int RuleLevel {
|
|
||||||
get { return ruleLevel; }
|
|
||||||
}
|
|
||||||
public void IncRuleLevel() { ruleLevel++; }
|
|
||||||
public void DecRuleLevel() { ruleLevel--; }
|
|
||||||
<if(profile)>
|
|
||||||
<ctorForProfilingRootGrammar()>
|
|
||||||
<else>
|
|
||||||
<ctorForRootGrammar()>
|
|
||||||
<endif>
|
|
||||||
<ctorForPredefinedListener()>
|
|
||||||
<else> <! imported grammar !>
|
|
||||||
public int RuleLevel {
|
|
||||||
get { return <grammar.delegators:{g| <g:delegateName()>}>.RuleLevel; }
|
|
||||||
}
|
|
||||||
public void IncRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.IncRuleLevel(); }
|
|
||||||
public void DecRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.DecRuleLevel(); }
|
|
||||||
<ctorForDelegateGrammar()>
|
|
||||||
<endif>
|
|
||||||
<if(profile)>
|
|
||||||
override public bool AlreadyParsedRule(IIntStream input, int ruleIndex)
|
|
||||||
{
|
|
||||||
((Profiler)dbg).ExamineRuleMemoization(input, ruleIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
|
|
||||||
return base.AlreadyParsedRule(input, ruleIndex);
|
|
||||||
}<\n>
|
|
||||||
override public void Memoize(IIntStream input,
|
|
||||||
int ruleIndex,
|
|
||||||
int ruleStartIndex)
|
|
||||||
{
|
|
||||||
((Profiler)dbg).Memoize(input, ruleIndex, ruleStartIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
|
|
||||||
base.Memoize(input, ruleIndex, ruleStartIndex);
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
protected bool EvalPredicate(bool result, string predicate)
|
|
||||||
{
|
|
||||||
dbg.SemanticPredicate(result, predicate);
|
|
||||||
return result;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForRootGrammar() ::= <<
|
|
||||||
<! bug: can't use <@super.members()> cut-n-paste instead !>
|
|
||||||
<! Same except we add port number and profile stuff if root grammar !>
|
|
||||||
public <name>(<inputStreamType> input)
|
|
||||||
: this(input, DebugEventSocketProxy.DEFAULT_DEBUGGER_PORT, new RecognizerSharedState()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public <name>(<inputStreamType> input, int port, RecognizerSharedState state)
|
|
||||||
: base(input, state) {
|
|
||||||
<parserCtorBody()>
|
|
||||||
<createListenerAndHandshake()>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForProfilingRootGrammar() ::= <<
|
|
||||||
<! bug: can't use <@super.members()> cut-n-paste instead !>
|
|
||||||
public <name>(<inputStreamType> input) {
|
|
||||||
this(input, new Profiler(null), new RecognizerSharedState());
|
|
||||||
}
|
|
||||||
|
|
||||||
public <name>(<inputStreamType> input, IDebugEventListener dbg, RecognizerSharedState state)
|
|
||||||
: base(input, dbg, state) {
|
|
||||||
Profiler p = (Profiler)dbg;
|
|
||||||
p.setParser(this);
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:
|
|
||||||
{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}
|
|
||||||
<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
/** Basically we don't want to set any dbg listeners are root will have it. */
|
|
||||||
ctorForDelegateGrammar() ::= <<
|
|
||||||
public <name>(<inputStreamType> input, IDebugEventListener dbg, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>)
|
|
||||||
: base(input, dbg, state) {
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:
|
|
||||||
{g|<g:delegateName()> = new <g.recognizerName>(input, this, this.state<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForPredefinedListener() ::= <<
|
|
||||||
public <name>(<inputStreamType> input, IDebugEventListener dbg)
|
|
||||||
: <@superClassRef>base(input, dbg, new RecognizerSharedState())<@end> {
|
|
||||||
<if(profile)>
|
|
||||||
Profiler p = (Profiler)dbg;
|
|
||||||
p.setParser(this);
|
|
||||||
<endif>
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createListenerAndHandshake() ::= <<
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
DebugEventSocketProxy proxy = new DebugEventSocketProxy(this, port, input.TreeAdaptor);
|
|
||||||
<else>
|
|
||||||
DebugEventSocketProxy proxy = new DebugEventSocketProxy(this, port, null);
|
|
||||||
<endif>
|
|
||||||
DebugListener = proxy;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
proxy.Handshake();
|
|
||||||
}
|
|
||||||
catch (IOException ioe)
|
|
||||||
{
|
|
||||||
ReportError(ioe);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.superClassName() ::= "Debug<@super.superClassName()>"
|
|
||||||
|
|
||||||
@rule.preamble() ::= <<
|
|
||||||
try {
|
|
||||||
dbg.EnterRule(GrammarFileName, "<ruleName>");
|
|
||||||
if ( RuleLevel==0 ) {dbg.Commence();}
|
|
||||||
IncRuleLevel();
|
|
||||||
dbg.Location(<ruleDescriptor.tree.line>, <ruleDescriptor.tree.column>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@lexer.debugAddition() ::= ", dbg"
|
|
||||||
|
|
||||||
@rule.postamble() ::= <<
|
|
||||||
dbg.Location(<ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.column>);<\n>
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
dbg.ExitRule(GrammarFileName, "<ruleName>");
|
|
||||||
DecRuleLevel();
|
|
||||||
if ( RuleLevel==0 ) {dbg.Terminate();}
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@synpred.start() ::= "dbg.BeginBacktrack(state.backtracking);"
|
|
||||||
|
|
||||||
@synpred.stop() ::= "dbg.EndBacktrack(state.backtracking, success);"
|
|
||||||
|
|
||||||
// Common debug event triggers used by region overrides below
|
|
||||||
|
|
||||||
enterSubRule() ::=
|
|
||||||
"try { dbg.EnterSubRule(<decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
exitSubRule() ::=
|
|
||||||
"} finally { dbg.ExitSubRule(<decisionNumber>); }<\n>"
|
|
||||||
|
|
||||||
enterDecision() ::=
|
|
||||||
"try { dbg.EnterDecision(<decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
exitDecision() ::=
|
|
||||||
"} finally { dbg.ExitDecision(<decisionNumber>); }<\n>"
|
|
||||||
|
|
||||||
enterAlt(n) ::= "dbg.EnterAlt(<n>);<\n>"
|
|
||||||
|
|
||||||
// Region overrides that tell various constructs to add debugging triggers
|
|
||||||
|
|
||||||
@block.predecision() ::= "<enterSubRule()><enterDecision()>"
|
|
||||||
|
|
||||||
@block.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@block.postbranch() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@ruleBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@ruleBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@ruleBlockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@blockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.earlyExitException() ::=
|
|
||||||
"dbg.RecognitionException(eee);<\n>"
|
|
||||||
|
|
||||||
@closureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@closureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@altSwitchCase.prealt() ::= "<enterAlt(n=i)>"
|
|
||||||
|
|
||||||
@element.prematch() ::=
|
|
||||||
"dbg.Location(<it.line>,<it.pos>);"
|
|
||||||
|
|
||||||
@matchSet.mismatchedSetException() ::=
|
|
||||||
"dbg.RecognitionException(mse);"
|
|
||||||
|
|
||||||
@dfaState.noViableAltException() ::= "dbg.RecognitionException(nvae_d<decisionNumber>s<stateNumber>);"
|
|
||||||
|
|
||||||
@dfaStateSwitch.noViableAltException() ::= "dbg.RecognitionException(nvae_d<decisionNumber>s<stateNumber>);"
|
|
||||||
|
|
||||||
dfaDecision(decisionNumber,description) ::= <<
|
|
||||||
try
|
|
||||||
{
|
|
||||||
isCyclicDecision = true;
|
|
||||||
<super.dfaDecision(...)>
|
|
||||||
}
|
|
||||||
catch (NoViableAltException nvae)
|
|
||||||
{
|
|
||||||
dbg.RecognitionException(nvae);
|
|
||||||
throw nvae;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.dbgCtor() ::= <<
|
|
||||||
public DFA<dfa.decisionNumber>(BaseRecognizer recognizer, IDebugEventListener dbg) : this(recognizer)
|
|
||||||
{
|
|
||||||
this.dbg = dbg;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.debugMember() ::= <<
|
|
||||||
IDebugEventListener dbg;
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.errorMethod() ::= <<
|
|
||||||
public override void Error(NoViableAltException nvae)
|
|
||||||
{
|
|
||||||
dbg.RecognitionException(nvae);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Force predicate validation to trigger an event */
|
|
||||||
evalPredicate(pred,description) ::= <<
|
|
||||||
EvalPredicate(<pred>,"<description>")
|
|
||||||
>>
|
|
@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template subgroup to add template rewrite output
|
|
||||||
* If debugging, then you'll also get STDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group ST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
using Antlr.StringTemplate;
|
|
||||||
using Antlr.StringTemplate.Language;
|
|
||||||
<if(!backtracking)>
|
|
||||||
using Hashtable = System.Collections.Hashtable;
|
|
||||||
<endif>
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add this to each rule's return value struct */
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
private StringTemplate st;
|
|
||||||
public StringTemplate ST { get { return st; } set { st = value; } }
|
|
||||||
public override object Template { get { return st; } }
|
|
||||||
public override string ToString() { return (st == null) ? null : st.ToString(); }
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
protected StringTemplateGroup templateLib =
|
|
||||||
new StringTemplateGroup("<name>Templates", typeof(AngleBracketTemplateLexer));
|
|
||||||
|
|
||||||
public StringTemplateGroup TemplateLib
|
|
||||||
{
|
|
||||||
get { return this.templateLib; }
|
|
||||||
set { this.templateLib = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \<summary> Allows convenient multi-value initialization:
|
|
||||||
/// "new STAttrMap().Add(...).Add(...)"
|
|
||||||
/// \</summary>
|
|
||||||
protected class STAttrMap : Hashtable
|
|
||||||
{
|
|
||||||
public STAttrMap Add(string attrName, object value)
|
|
||||||
{
|
|
||||||
base.Add(attrName, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public STAttrMap Add(string attrName, int value)
|
|
||||||
{
|
|
||||||
base.Add(attrName, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=template */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".Template",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplate(alts) ::= <<
|
|
||||||
|
|
||||||
// TEMPLATE REWRITE
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 )
|
|
||||||
{
|
|
||||||
<alts:rewriteTemplateAlt(); separator="else ">
|
|
||||||
<if(rewriteMode)><replaceTextInLine()><endif>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
<alts:rewriteTemplateAlt(); separator="else ">
|
|
||||||
<if(rewriteMode)><replaceTextInLine()><endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
replaceTextInLine() ::= <<
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
((TokenRewriteStream)input.TokenStream).Replace(
|
|
||||||
input.TreeAdaptor.GetTokenStartIndex(retval.Start),
|
|
||||||
input.TreeAdaptor.GetTokenStopIndex(retval.Start),
|
|
||||||
retval.ST);
|
|
||||||
<else>
|
|
||||||
((TokenRewriteStream)input).Replace(
|
|
||||||
((IToken)retval.Start).TokenIndex,
|
|
||||||
input.LT(-1).TokenIndex,
|
|
||||||
retval.ST);
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplateAlt() ::= <<
|
|
||||||
// <it.description>
|
|
||||||
<if(it.pred)>
|
|
||||||
if (<it.pred>) {
|
|
||||||
retval.ST = <it.alt>;
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
retval.ST = <it.alt>;
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteEmptyTemplate(alts) ::= <<
|
|
||||||
null;
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Invoke a template with a set of attribute name/value pairs.
|
|
||||||
* Set the value of the rule's template *after* having set
|
|
||||||
* the attributes because the rule's template might be used as
|
|
||||||
* an attribute to build a bigger template; you get a self-embedded
|
|
||||||
* template.
|
|
||||||
*/
|
|
||||||
rewriteExternalTemplate(name,args) ::= <<
|
|
||||||
templateLib.GetInstanceOf("<name>"<if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .Add("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** expr is a string expression that says what template to load */
|
|
||||||
rewriteIndirectTemplate(expr,args) ::= <<
|
|
||||||
templateLib.GetInstanceOf(<expr><if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .Add("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Invoke an inline template with a set of attribute name/value pairs */
|
|
||||||
rewriteInlineTemplate(args, template) ::= <<
|
|
||||||
new StringTemplate(templateLib, "<template>"<if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .Add("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
<action>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** An action has %st.attrName=expr; or %{st}.attrName=expr; */
|
|
||||||
actionSetAttribute(st,attrName,expr) ::= <<
|
|
||||||
(<st>).SetAttribute("<attrName>",<expr>);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Translate %{stringExpr} */
|
|
||||||
actionStringConstructor(stringExpr) ::= <<
|
|
||||||
new StringTemplate(templateLib,<stringExpr>)
|
|
||||||
>>
|
|
@ -1,403 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
group AST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
<if(!TREE_PARSER)><! tree parser would already have imported !>
|
|
||||||
using Antlr.Runtime.Tree;<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
<parserMembers()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add an adaptor property that knows how to build trees */
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected ITreeAdaptor adaptor = new CommonTreeAdaptor();<\n>
|
|
||||||
public ITreeAdaptor TreeAdaptor
|
|
||||||
{
|
|
||||||
get { return this.adaptor; }
|
|
||||||
set {
|
|
||||||
this.adaptor = value;
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()>.TreeAdaptor = this.adaptor;}>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
private <ASTLabelType> tree;
|
|
||||||
override public object Tree
|
|
||||||
{
|
|
||||||
get { return tree; }
|
|
||||||
set { tree = (<ASTLabelType>) value; }
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track rule's return AST */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> root_0 = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelDefs() ::= <<
|
|
||||||
<super.ruleLabelDefs()>
|
|
||||||
<ruleDescriptor.tokenLabels:{<ASTLabelType> <it.label.text>_tree=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{<ASTLabelType> <it.label.text>_tree=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it> = new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>");}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it> = new RewriteRuleSubtreeStream(adaptor,"rule <it>");}; separator="\n">
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** When doing auto AST construction, we must define some variables;
|
|
||||||
* These should be turned off if doing rewrites. This must be a "mode"
|
|
||||||
* as a rule could have both rewrite and AST within the same alternative
|
|
||||||
* block.
|
|
||||||
*/
|
|
||||||
@alt.declarations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.GetNilNode();<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// T r a c k i n g R u l e E l e m e n t s
|
|
||||||
|
|
||||||
/** ID and track it for use in a rewrite rule */
|
|
||||||
tokenRefTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)> <! Track implies no auto AST construction!>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<token>.Add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
|
|
||||||
* to the tracking list stream_ID for use in the rewrite.
|
|
||||||
*/
|
|
||||||
tokenRefTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<token>.Add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardTrack(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<rule.name>.Add(<label>.Tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefTrack(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<rule>.Add(<label>.Tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// R e w r i t e
|
|
||||||
|
|
||||||
rewriteCode(
|
|
||||||
alts, description,
|
|
||||||
referencedElementsDeep, // ALL referenced elements to right of ->
|
|
||||||
referencedTokenLabels,
|
|
||||||
referencedTokenListLabels,
|
|
||||||
referencedRuleLabels,
|
|
||||||
referencedRuleListLabels,
|
|
||||||
rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::=
|
|
||||||
<<
|
|
||||||
|
|
||||||
// AST REWRITE
|
|
||||||
// elements: <referencedElementsDeep; separator=", ">
|
|
||||||
// token labels: <referencedTokenLabels; separator=", ">
|
|
||||||
// rule labels: <referencedRuleLabels; separator=", ">
|
|
||||||
// token list labels: <referencedTokenListLabels; separator=", ">
|
|
||||||
// rule list labels: <referencedRuleListLabels; separator=", ">
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 ) {<\n>
|
|
||||||
<endif>
|
|
||||||
<prevRuleRootRef()>.Tree = root_0;
|
|
||||||
<rewriteCodeLabels()>
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.GetNilNode();
|
|
||||||
<alts:rewriteAlt(); separator="else ">
|
|
||||||
<! if tree parser and rewrite=true !>
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.Tree = (<ASTLabelType>)adaptor.rulePostProcessing(root_0);
|
|
||||||
input.ReplaceChildren(adaptor.GetParent(retval.Start),
|
|
||||||
adaptor.GetChildIndex(retval.Start),
|
|
||||||
adaptor.GetChildIndex(_last),
|
|
||||||
retval.Tree);
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<! if parser or rewrite!=true, we need to set result !>
|
|
||||||
<if(!TREE_PARSER)>
|
|
||||||
<prevRuleRootRef()>.Tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.Tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabels() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it> = new RewriteRule<rewriteElementType>Stream(adaptor, "token <it>", <it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it> = new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>", list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it> = new RewriteRuleSubtreeStream(adaptor, "token <it>", (<it>!=null ? <it>.Tree : null));};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it> = new RewriteRuleSubtreeStream(adaptor, "token <it>", list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Generate code for an optional rewrite block; note it uses the deep ref'd element
|
|
||||||
* list rather shallow like other blocks.
|
|
||||||
*/
|
|
||||||
rewriteOptionalBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
if ( <referencedElementsDeep:{el | stream_<el>.HasNext()}; separator=" || "> )
|
|
||||||
{
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElementsDeep:{el | stream_<el>.Reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
while ( <referencedElements:{el | stream_<el>.HasNext()}; separator=" || "> )
|
|
||||||
{
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.Reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewritePositiveClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
if ( !(<referencedElements:{el | stream_<el>.HasNext()}; separator=" || ">) ) {
|
|
||||||
throw new RewriteEarlyExitException();
|
|
||||||
}
|
|
||||||
while ( <referencedElements:{el | stream_<el>.HasNext()}; separator=" || "> )
|
|
||||||
{
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.Reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteAlt(a) ::= <<
|
|
||||||
// <a.description>
|
|
||||||
<if(a.pred)>
|
|
||||||
if (<a.pred>)
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** For empty rewrites: "r : ... -> ;" */
|
|
||||||
rewriteEmptyAlt() ::= "root_0 = null;"
|
|
||||||
|
|
||||||
rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)adaptor.GetNilNode();
|
|
||||||
<root:rewriteElement()>
|
|
||||||
<children:rewriteElement()>
|
|
||||||
adaptor.AddChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteElementList(elements) ::= "<elements:rewriteElement()>"
|
|
||||||
|
|
||||||
rewriteElement(e) ::= <<
|
|
||||||
<@pregen()>
|
|
||||||
<e.el>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ID or ID[args] */
|
|
||||||
rewriteTokenRef(token,elementIndex,hetero,args) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label=ID */
|
|
||||||
rewriteTokenLabelRef(label,elementIndex) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<label>.NextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label+=ID */
|
|
||||||
rewriteTokenListLabelRef(label,elementIndex) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<label>.NextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) */
|
|
||||||
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) where label+=... */
|
|
||||||
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
|
|
||||||
|
|
||||||
/** Gen ^(ID ...) or ^(ID[args] ...) */
|
|
||||||
rewriteTokenRefRoot(token,elementIndex,hetero,args) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<createRewriteNodeFromElement(...)>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRef(args,token,hetero,elementIndex) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRefRoot(args,token,hetero,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
root_0 = <action>;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What is the name of the previous value of this rule's root tree? This
|
|
||||||
* let's us refer to $rule to mean previous value. I am reusing the
|
|
||||||
* variable 'tree' sitting in retval struct to hold the value of root_0 right
|
|
||||||
* before I set it during rewrites. The assign will be to retval.Tree.
|
|
||||||
*/
|
|
||||||
prevRuleRootRef() ::= "retval"
|
|
||||||
|
|
||||||
rewriteRuleRef(rule) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<rule>.NextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteRuleRefRoot(rule) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<rule>.NextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeAction(action) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <action>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeActionRoot(action) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<action>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRef(label) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<label>.NextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRef(label) ::= <<
|
|
||||||
adaptor.AddChild(root_<treeLevel>, stream_<label>.NextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(stream_<label>.NextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createImaginaryNode(tokenType,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<! new MethodNode(IDLabel, args) !>
|
|
||||||
new <hetero>(<tokenType><if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)adaptor.Create(<tokenType>, <args; separator=", "><if(!args)>"<tokenType>"<endif>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createRewriteNodeFromElement(token,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.NextToken()<if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)> <! must create new node from old !>
|
|
||||||
adaptor.Create(<token>, <args; separator=", ">)
|
|
||||||
<else>
|
|
||||||
stream_<token>.NextNode()
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,97 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Template overrides to add debugging to AST stuff. Dynamic inheritance
|
|
||||||
* hierarchy is set up as ASTDbg : AST : Dbg : C# by code generator.
|
|
||||||
*/
|
|
||||||
group ASTDbg;
|
|
||||||
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected DebugTreeAdaptor adaptor;
|
|
||||||
public ITreeAdaptor TreeAdaptor
|
|
||||||
{
|
|
||||||
get {
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
return this.adaptor;
|
|
||||||
<else>
|
|
||||||
this.adaptor = (DebugTreeAdaptor)adaptor; // delegator sends dbg adaptor
|
|
||||||
<endif><\n>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()>.TreeAdaptor = this.adaptor;}>
|
|
||||||
}
|
|
||||||
set { this.adaptor = new DebugTreeAdaptor(dbg, value); }
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
parserCtorBody() ::= <<
|
|
||||||
<super.parserCtorBody()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createListenerAndHandshake() ::= <<
|
|
||||||
DebugEventSocketProxy proxy = new DebugEventSocketProxy(this, port, adaptor);
|
|
||||||
DebugListener = proxy;
|
|
||||||
<!
|
|
||||||
Original line follows, replaced by the next two ifs:
|
|
||||||
set<inputStreamType>(new Debug<inputStreamType>(input,proxy));
|
|
||||||
!>
|
|
||||||
<if(PARSER)>
|
|
||||||
TokenStream = new DebugTokenStream(input,proxy);<\n>
|
|
||||||
<endif>
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
TokenStream = new DebugTreeNodeStream(input,proxy);<\n>
|
|
||||||
<endif>
|
|
||||||
try {
|
|
||||||
proxy.Handshake();
|
|
||||||
} catch (IOException ioe) {
|
|
||||||
ReportError(ioe);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForRootGrammar.finally() ::= <<
|
|
||||||
ITreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
TreeAdaptor = adap;
|
|
||||||
proxy.TreeAdaptor = adap;
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForProfilingRootGrammar.finally() ::=<<
|
|
||||||
ITreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
TreeAdaptor = adap;
|
|
||||||
proxy.TreeAdaptor = adap;
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForPredefinedListener.superClassRef() ::= "base(input, dbg)"
|
|
||||||
|
|
||||||
@ctorForPredefinedListener.finally() ::=<<
|
|
||||||
<if(grammar.grammarIsRoot)> <! don't create new adaptor for delegates !>
|
|
||||||
ITreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
TreeAdaptor = adap;<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@rewriteElement.pregen() ::= "dbg.Location(<e.line>,<e.pos>);"
|
|
@ -1,220 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during normal parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* The situation is not too bad as rewrite (->) usage makes ^ and !
|
|
||||||
* invalid. There is no huge explosion of combinations.
|
|
||||||
*/
|
|
||||||
group ASTParser;
|
|
||||||
|
|
||||||
@rule.setErrorReturnValue() ::= <<
|
|
||||||
// Conversion of the second argument necessary, but harmless
|
|
||||||
retval.Tree = (<ASTLabelType>)adaptor.ErrorNode(input, (IToken) retval.Start, input.LT(-1), re);
|
|
||||||
<! System.Console.WriteLine("<ruleName> returns " + ((CommonTree)retval.Tree).ToStringTree()); !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID and output=AST */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
adaptor.AddChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) */
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>"
|
|
||||||
|
|
||||||
/** ID^ and output=AST */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID! and output=AST */
|
|
||||||
tokenRefBangAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN when output=AST but not rewrite alt */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match label+=TOKEN^ when output=AST but not rewrite alt */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
// the match set stuff is interesting in that it uses an argument list
|
|
||||||
// to pass code to the default matchSet; another possible way to alter
|
|
||||||
// inherited code. I don't use the region stuff because I need to pass
|
|
||||||
// different chunks depending on the operator. I don't like making
|
|
||||||
// the template name have the operator as the number of templates gets
|
|
||||||
// large but this is the most flexible--this is as opposed to having
|
|
||||||
// the code generator call matchSet then add root code or ruleroot code
|
|
||||||
// plus list label plus ... The combinations might require complicated
|
|
||||||
// rather than just added on code. Investigate that refactoring when
|
|
||||||
// I have more time.
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( state.backtracking == 0 ) <endif>adaptor.AddChild(root_0, <createNodeFromToken(...)>);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= "<super.matchSet(...)>"
|
|
||||||
|
|
||||||
// note there is no matchSetTrack because -> rewrites force sets to be
|
|
||||||
// plain old blocks of alts: (A|B|...|C)
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<if(label)>
|
|
||||||
<label>=(<labelType>)input.LT(1);<\n>
|
|
||||||
<endif>
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( state.backtracking == 0 ) <endif>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<createNodeFromToken(...)>, root_0);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule when output=AST */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking == 0 ) <endif>adaptor.AddChild(root_0, <label>.Tree);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule! is same as normal rule ref */
|
|
||||||
ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
|
|
||||||
|
|
||||||
/** rule^ */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking == 0 ) <endif>root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>.Tree, root_0);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule! when output=AST is a rule ref with list addition */
|
|
||||||
ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefBang(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule^ */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// WILDCARD AST
|
|
||||||
|
|
||||||
wildcard(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.Create(<label>);
|
|
||||||
adaptor.AddChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>"
|
|
||||||
|
|
||||||
wildcardRuleRoot(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.Create(<label>);
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_0);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createNodeFromToken(label,hetero) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(<label>) <! new MethodNode(IDLabel) !>
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)adaptor.Create(<label>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
retval.Tree = (<ASTLabelType>)adaptor.RulePostProcessing(root_0);
|
|
||||||
<if(!TREE_PARSER)>
|
|
||||||
adaptor.SetTokenBoundaries(retval.Tree, (IToken) retval.Start, (IToken) retval.Stop);
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,299 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during tree parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* Each combination has its own template except that label/no label
|
|
||||||
* is combined into tokenRef, ruleRef, ...
|
|
||||||
*/
|
|
||||||
group ASTTreeParser;
|
|
||||||
|
|
||||||
/** Add a variable to track last element matched */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> _first_0 = null;
|
|
||||||
<ASTLabelType> _last = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What to emit when there is no rewrite rule. For auto build
|
|
||||||
* mode, does nothing.
|
|
||||||
*/
|
|
||||||
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
retval.Tree = (<ASTLabelType>)_first_0;
|
|
||||||
if ( adaptor.GetParent(retval.Tree)!=null && adaptor.IsNil( adaptor.GetParent(retval.Tree) ) )
|
|
||||||
retval.Tree = (<ASTLabelType>)adaptor.GetParent(retval.Tree);
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser; override here to
|
|
||||||
* add tree construction actions.
|
|
||||||
*/
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
{
|
|
||||||
<ASTLabelType> _save_last_<treeLevel> = _last;
|
|
||||||
<ASTLabelType> _first_<treeLevel> = null;
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)adaptor.GetNilNode();
|
|
||||||
<endif>
|
|
||||||
<root:element()>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 )<endif>
|
|
||||||
<if(root.el.rule)>
|
|
||||||
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>.Tree;
|
|
||||||
<else>
|
|
||||||
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>;
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<actionsAfterRoot:element()>
|
|
||||||
<if(nullableChildList)>
|
|
||||||
if ( input.LA(1) == Token.DOWN )
|
|
||||||
{
|
|
||||||
Match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
Match(input, Token.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
Match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
Match(input, Token.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
adaptor.AddChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
_last = _save_last_<treeLevel>;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) 'cept add
|
|
||||||
* setting of _last
|
|
||||||
*/
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID auto construct */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.DupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 )<endif>
|
|
||||||
if ( _first_<treeLevel>==null ) _first_<treeLevel> = <label>;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN auto construct */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) auto construct */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking == 0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.DupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) auto construct */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.DupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
<noRewrite()> <! set return tree !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.DupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule auto construct */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
adaptor.AddChild(root_<treeLevel>, <label>.Tree);
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
if ( _first_<treeLevel>==null ) _first_<treeLevel> = <label>.Tree;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule auto construct */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) auto construct */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking == 0 ) <endif>root_<treeLevel> = (<ASTLabelType>)adaptor.BecomeRoot(<label>.Tree, root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) auto construct */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".Tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefRootTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefRuleRootTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Streams for token refs are tree nodes now; override to
|
|
||||||
* change nextToken to nextNode.
|
|
||||||
*/
|
|
||||||
createRewriteNodeFromElement(token,hetero,scope) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.NextNode())
|
|
||||||
<else>
|
|
||||||
stream_<token>.NextNode()
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 )
|
|
||||||
{
|
|
||||||
<endif>
|
|
||||||
retval.Tree = (<ASTLabelType>)adaptor.RulePostProcessing(root_0);
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,288 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template overrides to add debugging to normal Java output;
|
|
||||||
* If ASTs are built, then you'll also get ASTDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group Dbg;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
using Antlr.Runtime.Debug;
|
|
||||||
using IOException = System.IO.IOException;
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
public static readonly string[] ruleNames = new string[] {
|
|
||||||
"invalidRule", <grammar.allImportedRules:{rST | "<rST.name>"}; wrap="\n ", separator=", ">
|
|
||||||
};<\n>
|
|
||||||
<endif>
|
|
||||||
<if(grammar.grammarIsRoot)> <! grammar imports other grammar(s) !>
|
|
||||||
private int ruleLevel = 0;
|
|
||||||
public int RuleLevel {
|
|
||||||
get { return ruleLevel; }
|
|
||||||
}
|
|
||||||
public void IncRuleLevel() { ruleLevel++; }
|
|
||||||
public void DecRuleLevel() { ruleLevel--; }
|
|
||||||
<if(profile)>
|
|
||||||
<ctorForProfilingRootGrammar()>
|
|
||||||
<else>
|
|
||||||
<ctorForRootGrammar()>
|
|
||||||
<endif>
|
|
||||||
<ctorForPredefinedListener()>
|
|
||||||
<else> <! imported grammar !>
|
|
||||||
public int RuleLevel {
|
|
||||||
get { return <grammar.delegators:{g| <g:delegateName()>}>.RuleLevel; }
|
|
||||||
}
|
|
||||||
public void IncRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.IncRuleLevel(); }
|
|
||||||
public void DecRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.DecRuleLevel(); }
|
|
||||||
<ctorForDelegateGrammar()>
|
|
||||||
<endif>
|
|
||||||
<if(profile)>
|
|
||||||
override public bool AlreadyParsedRule(IIntStream input, int ruleIndex)
|
|
||||||
{
|
|
||||||
((Profiler)dbg).ExamineRuleMemoization(input, ruleIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
|
|
||||||
return base.AlreadyParsedRule(input, ruleIndex);
|
|
||||||
}<\n>
|
|
||||||
override public void Memoize(IIntStream input,
|
|
||||||
int ruleIndex,
|
|
||||||
int ruleStartIndex)
|
|
||||||
{
|
|
||||||
((Profiler)dbg).Memoize(input, ruleIndex, ruleStartIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
|
|
||||||
base.Memoize(input, ruleIndex, ruleStartIndex);
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
protected bool EvalPredicate(bool result, string predicate)
|
|
||||||
{
|
|
||||||
dbg.SemanticPredicate(result, predicate);
|
|
||||||
return result;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForRootGrammar() ::= <<
|
|
||||||
<! bug: can't use <@super.members()> cut-n-paste instead !>
|
|
||||||
<! Same except we add port number and profile stuff if root grammar !>
|
|
||||||
public <name>(<inputStreamType> input)
|
|
||||||
: this(input, DebugEventSocketProxy.DEFAULT_DEBUGGER_PORT, new RecognizerSharedState()) {
|
|
||||||
}
|
|
||||||
|
|
||||||
public <name>(<inputStreamType> input, int port, RecognizerSharedState state)
|
|
||||||
: base(input, state) {
|
|
||||||
<parserCtorBody()>
|
|
||||||
<createListenerAndHandshake()>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForProfilingRootGrammar() ::= <<
|
|
||||||
<! bug: can't use <@super.members()> cut-n-paste instead !>
|
|
||||||
public <name>(<inputStreamType> input) {
|
|
||||||
this(input, new Profiler(null), new RecognizerSharedState());
|
|
||||||
}
|
|
||||||
|
|
||||||
public <name>(<inputStreamType> input, IDebugEventListener dbg, RecognizerSharedState state)
|
|
||||||
: base(input, dbg, state) {
|
|
||||||
Profiler p = (Profiler)dbg;
|
|
||||||
p.setParser(this);
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:
|
|
||||||
{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}
|
|
||||||
<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
/** Basically we don't want to set any dbg listeners are root will have it. */
|
|
||||||
ctorForDelegateGrammar() ::= <<
|
|
||||||
public <name>(<inputStreamType> input, IDebugEventListener dbg, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>)
|
|
||||||
: base(input, dbg, state) {
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:
|
|
||||||
{g|<g:delegateName()> = new <g.recognizerName>(input, this, this.state<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForPredefinedListener() ::= <<
|
|
||||||
public <name>(<inputStreamType> input, IDebugEventListener dbg)
|
|
||||||
: <@superClassRef>base(input, dbg, new RecognizerSharedState())<@end> {
|
|
||||||
<if(profile)>
|
|
||||||
Profiler p = (Profiler)dbg;
|
|
||||||
p.setParser(this);
|
|
||||||
<endif>
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createListenerAndHandshake() ::= <<
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
DebugEventSocketProxy proxy = new DebugEventSocketProxy(this, port, input.TreeAdaptor);
|
|
||||||
<else>
|
|
||||||
DebugEventSocketProxy proxy = new DebugEventSocketProxy(this, port, null);
|
|
||||||
<endif>
|
|
||||||
DebugListener = proxy;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
proxy.Handshake();
|
|
||||||
}
|
|
||||||
catch (IOException ioe)
|
|
||||||
{
|
|
||||||
ReportError(ioe);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.superClassName() ::= "Debug<@super.superClassName()>"
|
|
||||||
|
|
||||||
@rule.preamble() ::= <<
|
|
||||||
try {
|
|
||||||
dbg.EnterRule(GrammarFileName, "<ruleName>");
|
|
||||||
if ( RuleLevel==0 ) {dbg.Commence();}
|
|
||||||
IncRuleLevel();
|
|
||||||
dbg.Location(<ruleDescriptor.tree.line>, <ruleDescriptor.tree.column>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@lexer.debugAddition() ::= ", dbg"
|
|
||||||
|
|
||||||
@rule.postamble() ::= <<
|
|
||||||
dbg.Location(<ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.column>);<\n>
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
dbg.ExitRule(GrammarFileName, "<ruleName>");
|
|
||||||
DecRuleLevel();
|
|
||||||
if ( RuleLevel==0 ) {dbg.Terminate();}
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@synpred.start() ::= "dbg.BeginBacktrack(state.backtracking);"
|
|
||||||
|
|
||||||
@synpred.stop() ::= "dbg.EndBacktrack(state.backtracking, success);"
|
|
||||||
|
|
||||||
// Common debug event triggers used by region overrides below
|
|
||||||
|
|
||||||
enterSubRule() ::=
|
|
||||||
"try { dbg.EnterSubRule(<decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
exitSubRule() ::=
|
|
||||||
"} finally { dbg.ExitSubRule(<decisionNumber>); }<\n>"
|
|
||||||
|
|
||||||
enterDecision() ::=
|
|
||||||
"try { dbg.EnterDecision(<decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
exitDecision() ::=
|
|
||||||
"} finally { dbg.ExitDecision(<decisionNumber>); }<\n>"
|
|
||||||
|
|
||||||
enterAlt(n) ::= "dbg.EnterAlt(<n>);<\n>"
|
|
||||||
|
|
||||||
// Region overrides that tell various constructs to add debugging triggers
|
|
||||||
|
|
||||||
@block.predecision() ::= "<enterSubRule()><enterDecision()>"
|
|
||||||
|
|
||||||
@block.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@block.postbranch() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@ruleBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@ruleBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@ruleBlockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@blockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.earlyExitException() ::=
|
|
||||||
"dbg.RecognitionException(eee);<\n>"
|
|
||||||
|
|
||||||
@closureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@closureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@altSwitchCase.prealt() ::= "<enterAlt(n=i)>"
|
|
||||||
|
|
||||||
@element.prematch() ::=
|
|
||||||
"dbg.Location(<it.line>,<it.pos>);"
|
|
||||||
|
|
||||||
@matchSet.mismatchedSetException() ::=
|
|
||||||
"dbg.RecognitionException(mse);"
|
|
||||||
|
|
||||||
@dfaState.noViableAltException() ::= "dbg.RecognitionException(nvae_d<decisionNumber>s<stateNumber>);"
|
|
||||||
|
|
||||||
@dfaStateSwitch.noViableAltException() ::= "dbg.RecognitionException(nvae_d<decisionNumber>s<stateNumber>);"
|
|
||||||
|
|
||||||
dfaDecision(decisionNumber,description) ::= <<
|
|
||||||
try
|
|
||||||
{
|
|
||||||
isCyclicDecision = true;
|
|
||||||
<super.dfaDecision(...)>
|
|
||||||
}
|
|
||||||
catch (NoViableAltException nvae)
|
|
||||||
{
|
|
||||||
dbg.RecognitionException(nvae);
|
|
||||||
throw nvae;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.dbgCtor() ::= <<
|
|
||||||
public DFA<dfa.decisionNumber>(BaseRecognizer recognizer, IDebugEventListener dbg) : this(recognizer)
|
|
||||||
{
|
|
||||||
this.dbg = dbg;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.debugMember() ::= <<
|
|
||||||
IDebugEventListener dbg;
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.errorMethod() ::= <<
|
|
||||||
public override void Error(NoViableAltException nvae)
|
|
||||||
{
|
|
||||||
dbg.RecognitionException(nvae);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Force predicate validation to trigger an event */
|
|
||||||
evalPredicate(pred,description) ::= <<
|
|
||||||
EvalPredicate(<pred>,"<description>")
|
|
||||||
>>
|
|
@ -1,173 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007-2008 Johannes Luber
|
|
||||||
Copyright (c) 2005-2007 Kunle Odutola
|
|
||||||
Copyright (c) 2005 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template subgroup to add template rewrite output
|
|
||||||
* If debugging, then you'll also get STDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group ST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
using Antlr.StringTemplate;
|
|
||||||
using Antlr.StringTemplate.Language;
|
|
||||||
<if(!backtracking)>
|
|
||||||
using Hashtable = System.Collections.Hashtable;
|
|
||||||
<endif>
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add this to each rule's return value struct */
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
private StringTemplate st;
|
|
||||||
public StringTemplate ST { get { return st; } set { st = value; } }
|
|
||||||
public override object Template { get { return st; } }
|
|
||||||
public override string ToString() { return (st == null) ? null : st.ToString(); }
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
protected StringTemplateGroup templateLib =
|
|
||||||
new StringTemplateGroup("<name>Templates", typeof(AngleBracketTemplateLexer));
|
|
||||||
|
|
||||||
public StringTemplateGroup TemplateLib
|
|
||||||
{
|
|
||||||
get { return this.templateLib; }
|
|
||||||
set { this.templateLib = value; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// \<summary> Allows convenient multi-value initialization:
|
|
||||||
/// "new STAttrMap().Add(...).Add(...)"
|
|
||||||
/// \</summary>
|
|
||||||
protected class STAttrMap : Hashtable
|
|
||||||
{
|
|
||||||
public STAttrMap Add(string attrName, object value)
|
|
||||||
{
|
|
||||||
base.Add(attrName, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public STAttrMap Add(string attrName, int value)
|
|
||||||
{
|
|
||||||
base.Add(attrName, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=template */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".Template",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplate(alts) ::= <<
|
|
||||||
|
|
||||||
// TEMPLATE REWRITE
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 )
|
|
||||||
{
|
|
||||||
<alts:rewriteTemplateAlt(); separator="else ">
|
|
||||||
<if(rewriteMode)><replaceTextInLine()><endif>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
<alts:rewriteTemplateAlt(); separator="else ">
|
|
||||||
<if(rewriteMode)><replaceTextInLine()><endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
replaceTextInLine() ::= <<
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
((TokenRewriteStream)input.TokenStream).Replace(
|
|
||||||
input.TreeAdaptor.GetTokenStartIndex(retval.Start),
|
|
||||||
input.TreeAdaptor.GetTokenStopIndex(retval.Start),
|
|
||||||
retval.ST);
|
|
||||||
<else>
|
|
||||||
((TokenRewriteStream)input).Replace(
|
|
||||||
((IToken)retval.Start).TokenIndex,
|
|
||||||
input.LT(-1).TokenIndex,
|
|
||||||
retval.ST);
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplateAlt() ::= <<
|
|
||||||
// <it.description>
|
|
||||||
<if(it.pred)>
|
|
||||||
if (<it.pred>) {
|
|
||||||
retval.ST = <it.alt>;
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
retval.ST = <it.alt>;
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteEmptyTemplate(alts) ::= <<
|
|
||||||
null;
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Invoke a template with a set of attribute name/value pairs.
|
|
||||||
* Set the value of the rule's template *after* having set
|
|
||||||
* the attributes because the rule's template might be used as
|
|
||||||
* an attribute to build a bigger template; you get a self-embedded
|
|
||||||
* template.
|
|
||||||
*/
|
|
||||||
rewriteExternalTemplate(name,args) ::= <<
|
|
||||||
templateLib.GetInstanceOf("<name>"<if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .Add("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** expr is a string expression that says what template to load */
|
|
||||||
rewriteIndirectTemplate(expr,args) ::= <<
|
|
||||||
templateLib.GetInstanceOf(<expr><if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .Add("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Invoke an inline template with a set of attribute name/value pairs */
|
|
||||||
rewriteInlineTemplate(args, template) ::= <<
|
|
||||||
new StringTemplate(templateLib, "<template>"<if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .Add("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
<action>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** An action has %st.attrName=expr; or %{st}.attrName=expr; */
|
|
||||||
actionSetAttribute(st,attrName,expr) ::= <<
|
|
||||||
(<st>).SetAttribute("<attrName>",<expr>);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Translate %{stringExpr} */
|
|
||||||
actionStringConstructor(stringExpr) ::= <<
|
|
||||||
new StringTemplate(templateLib,<stringExpr>)
|
|
||||||
>>
|
|
@ -1,393 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
group AST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
<if(!TREE_PARSER)><! tree parser would already have imported !>
|
|
||||||
import org.antlr.runtime.tree.*;<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
<parserMembers()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add an adaptor property that knows how to build trees */
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected TreeAdaptor adaptor = new CommonTreeAdaptor();<\n>
|
|
||||||
public void setTreeAdaptor(TreeAdaptor adaptor) {
|
|
||||||
this.adaptor = adaptor;
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()>.setTreeAdaptor(this.adaptor);}>
|
|
||||||
}
|
|
||||||
public TreeAdaptor getTreeAdaptor() {
|
|
||||||
return adaptor;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
<ASTLabelType> tree;
|
|
||||||
public Object getTree() { return tree; }
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track rule's return AST */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> root_0 = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelDefs() ::= <<
|
|
||||||
<super.ruleLabelDefs()>
|
|
||||||
<ruleDescriptor.tokenLabels:{<ASTLabelType> <it.label.text>_tree=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{<ASTLabelType> <it.label.text>_tree=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it>=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>");}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it>=new RewriteRuleSubtreeStream(adaptor,"rule <it>");}; separator="\n">
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** When doing auto AST construction, we must define some variables;
|
|
||||||
* These should be turned off if doing rewrites. This must be a "mode"
|
|
||||||
* as a rule could have both rewrite and AST within the same alternative
|
|
||||||
* block.
|
|
||||||
*/
|
|
||||||
@alt.declarations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.nil();<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// T r a c k i n g R u l e E l e m e n t s
|
|
||||||
|
|
||||||
/** ID and track it for use in a rewrite rule */
|
|
||||||
tokenRefTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)> <! Track implies no auto AST construction!>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<token>.add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
|
|
||||||
* to the tracking list stream_ID for use in the rewrite.
|
|
||||||
*/
|
|
||||||
tokenRefTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<token>.add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardTrack(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<rule.name>.add(<label>.getTree());
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefTrack(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>stream_<rule>.add(<label>.getTree());
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// R e w r i t e
|
|
||||||
|
|
||||||
rewriteCode(
|
|
||||||
alts, description,
|
|
||||||
referencedElementsDeep, // ALL referenced elements to right of ->
|
|
||||||
referencedTokenLabels,
|
|
||||||
referencedTokenListLabels,
|
|
||||||
referencedRuleLabels,
|
|
||||||
referencedRuleListLabels,
|
|
||||||
rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::=
|
|
||||||
<<
|
|
||||||
|
|
||||||
// AST REWRITE
|
|
||||||
// elements: <referencedElementsDeep; separator=", ">
|
|
||||||
// token labels: <referencedTokenLabels; separator=", ">
|
|
||||||
// rule labels: <referencedRuleLabels; separator=", ">
|
|
||||||
// token list labels: <referencedTokenListLabels; separator=", ">
|
|
||||||
// rule list labels: <referencedRuleListLabels; separator=", ">
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 ) {<\n>
|
|
||||||
<endif>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<rewriteCodeLabels()>
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.nil();
|
|
||||||
<alts:rewriteAlt(); separator="else ">
|
|
||||||
<! if tree parser and rewrite=true !>
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = (<ASTLabelType>)adaptor.rulePostProcessing(root_0);
|
|
||||||
input.replaceChildren(adaptor.getParent(retval.start),
|
|
||||||
adaptor.getChildIndex(retval.start),
|
|
||||||
adaptor.getChildIndex(_last),
|
|
||||||
retval.tree);
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<! if parser or tree-parser && rewrite!=true, we need to set result !>
|
|
||||||
<if(!TREE_PARSER)>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<else>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabels() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it>=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>",<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{RewriteRule<rewriteElementType>Stream stream_<it>=new RewriteRule<rewriteElementType>Stream(adaptor,"token <it>", list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it>=new RewriteRuleSubtreeStream(adaptor,"token <it>",<it>!=null?<it>.tree:null);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{RewriteRuleSubtreeStream stream_<it>=new RewriteRuleSubtreeStream(adaptor,"token <it>",list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Generate code for an optional rewrite block; note it uses the deep ref'd element
|
|
||||||
* list rather shallow like other blocks.
|
|
||||||
*/
|
|
||||||
rewriteOptionalBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
if ( <referencedElementsDeep:{el | stream_<el>.hasNext()}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElementsDeep:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
while ( <referencedElements:{el | stream_<el>.hasNext()}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewritePositiveClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
if ( !(<referencedElements:{el | stream_<el>.hasNext()}; separator="||">) ) {
|
|
||||||
throw new RewriteEarlyExitException();
|
|
||||||
}
|
|
||||||
while ( <referencedElements:{el | stream_<el>.hasNext()}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteAlt(a) ::= <<
|
|
||||||
// <a.description>
|
|
||||||
<if(a.pred)>
|
|
||||||
if (<a.pred>) {
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** For empty rewrites: "r : ... -> ;" */
|
|
||||||
rewriteEmptyAlt() ::= "root_0 = null;"
|
|
||||||
|
|
||||||
rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)adaptor.nil();
|
|
||||||
<root:rewriteElement()>
|
|
||||||
<children:rewriteElement()>
|
|
||||||
adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteElementList(elements) ::= "<elements:rewriteElement()>"
|
|
||||||
|
|
||||||
rewriteElement(e) ::= <<
|
|
||||||
<@pregen()>
|
|
||||||
<e.el>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ID or ID[args] */
|
|
||||||
rewriteTokenRef(token,elementIndex,hetero,args) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label=ID */
|
|
||||||
rewriteTokenLabelRef(label,elementIndex) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label+=ID */
|
|
||||||
rewriteTokenListLabelRef(label,elementIndex) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) */
|
|
||||||
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) where label+=... */
|
|
||||||
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
|
|
||||||
|
|
||||||
/** Gen ^(ID ...) or ^(ID[args] ...) */
|
|
||||||
rewriteTokenRefRoot(token,elementIndex,hetero,args) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<createRewriteNodeFromElement(...)>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRef(args,token,hetero,elementIndex) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRefRoot(args,token,hetero,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
root_0 = <action>;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What is the name of the previous value of this rule's root tree? This
|
|
||||||
* let's us refer to $rule to mean previous value. I am reusing the
|
|
||||||
* variable 'tree' sitting in retval struct to hold the value of root_0 right
|
|
||||||
* before I set it during rewrites. The assign will be to retval.tree.
|
|
||||||
*/
|
|
||||||
prevRuleRootRef() ::= "retval"
|
|
||||||
|
|
||||||
rewriteRuleRef(rule) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<rule>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteRuleRefRoot(rule) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(stream_<rule>.nextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeAction(action) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, <action>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeActionRoot(action) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<action>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRef(label) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRef(label) ::= <<
|
|
||||||
adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createImaginaryNode(tokenType,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<! new MethodNode(IDLabel, args) !>
|
|
||||||
new <hetero>(<tokenType><if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)adaptor.create(<tokenType>, <args; separator=", "><if(!args)>"<tokenType>"<endif>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createRewriteNodeFromElement(token,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.nextToken()<if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)> <! must create new node from old !>
|
|
||||||
adaptor.create(<token>, <args; separator=", ">)
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,87 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Template overrides to add debugging to AST stuff. Dynamic inheritance
|
|
||||||
* hierarchy is set up as ASTDbg : AST : Dbg : Java by code generator.
|
|
||||||
*/
|
|
||||||
group ASTDbg;
|
|
||||||
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected DebugTreeAdaptor adaptor;
|
|
||||||
public void setTreeAdaptor(TreeAdaptor adaptor) {
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
this.adaptor = new DebugTreeAdaptor(dbg,adaptor);
|
|
||||||
<else>
|
|
||||||
this.adaptor = (DebugTreeAdaptor)adaptor; // delegator sends dbg adaptor
|
|
||||||
<endif><\n>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()>.setTreeAdaptor(this.adaptor);}>
|
|
||||||
}
|
|
||||||
public TreeAdaptor getTreeAdaptor() {
|
|
||||||
return adaptor;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
parserCtorBody() ::= <<
|
|
||||||
<super.parserCtorBody()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createListenerAndHandshake() ::= <<
|
|
||||||
DebugEventSocketProxy proxy =
|
|
||||||
new DebugEventSocketProxy(this,port,<if(TREE_PARSER)>input.getTreeAdaptor()<else>adaptor<endif>);
|
|
||||||
setDebugListener(proxy);
|
|
||||||
set<inputStreamType>(new Debug<inputStreamType>(input,proxy));
|
|
||||||
try {
|
|
||||||
proxy.handshake();
|
|
||||||
}
|
|
||||||
catch (IOException ioe) {
|
|
||||||
reportError(ioe);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForRootGrammar.finally() ::= <<
|
|
||||||
TreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
setTreeAdaptor(adap);
|
|
||||||
proxy.setTreeAdaptor(adap);
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForProfilingRootGrammar.finally() ::=<<
|
|
||||||
TreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
setTreeAdaptor(adap);
|
|
||||||
proxy.setTreeAdaptor(adap);
|
|
||||||
>>
|
|
||||||
|
|
||||||
@ctorForPredefinedListener.superClassRef() ::= "super(input, dbg);"
|
|
||||||
|
|
||||||
@ctorForPredefinedListener.finally() ::=<<
|
|
||||||
<if(grammar.grammarIsRoot)> <! don't create new adaptor for delegates !>
|
|
||||||
TreeAdaptor adap = new CommonTreeAdaptor();
|
|
||||||
setTreeAdaptor(adap);<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@rewriteElement.pregen() ::= "dbg.location(<e.line>,<e.pos>);"
|
|
@ -1,190 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during normal parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* The situation is not too bad as rewrite (->) usage makes ^ and !
|
|
||||||
* invalid. There is no huge explosion of combinations.
|
|
||||||
*/
|
|
||||||
group ASTParser;
|
|
||||||
|
|
||||||
@rule.setErrorReturnValue() ::= <<
|
|
||||||
retval.tree = (<ASTLabelType>)adaptor.errorNode(input, retval.start, input.LT(-1), re);
|
|
||||||
<! System.out.println("<ruleName> returns "+((CommonTree)retval.tree).toStringTree()); !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID and output=AST */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
adaptor.addChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) */
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>"
|
|
||||||
|
|
||||||
/** ID^ and output=AST */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.becomeRoot(<label>_tree, root_0);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID! and output=AST */
|
|
||||||
tokenRefBangAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN when output=AST but not rewrite alt */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match label+=TOKEN^ when output=AST but not rewrite alt */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
// the match set stuff is interesting in that it uses an argument list
|
|
||||||
// to pass code to the default matchSet; another possible way to alter
|
|
||||||
// inherited code. I don't use the region stuff because I need to pass
|
|
||||||
// different chunks depending on the operator. I don't like making
|
|
||||||
// the template name have the operator as the number of templates gets
|
|
||||||
// large but this is the most flexible--this is as opposed to having
|
|
||||||
// the code generator call matchSet then add root code or ruleroot code
|
|
||||||
// plus list label plus ... The combinations might require complicated
|
|
||||||
// rather than just added on code. Investigate that refactoring when
|
|
||||||
// I have more time.
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( state.backtracking==0 ) <endif>adaptor.addChild(root_0, <createNodeFromToken(...)>);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= "<super.matchSet(...)>"
|
|
||||||
|
|
||||||
// note there is no matchSetTrack because -> rewrites force sets to be
|
|
||||||
// plain old blocks of alts: (A|B|...|C)
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<if(label)>
|
|
||||||
<label>=(<labelType>)input.LT(1);<\n>
|
|
||||||
<endif>
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( state.backtracking==0 ) <endif>root_0 = (<ASTLabelType>)adaptor.becomeRoot(<createNodeFromToken(...)>, root_0);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule when output=AST */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>adaptor.addChild(root_0, <label>.getTree());
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule! is same as normal rule ref */
|
|
||||||
ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
|
|
||||||
|
|
||||||
/** rule^ */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>root_0 = (<ASTLabelType>)adaptor.becomeRoot(<label>.getTree(), root_0);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule! when output=AST is a rule ref with list addition */
|
|
||||||
ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefBang(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule^ */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// WILDCARD AST
|
|
||||||
|
|
||||||
wildcard(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.create(<label>);
|
|
||||||
adaptor.addChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>"
|
|
||||||
|
|
||||||
wildcardRuleRoot(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.create(<label>);
|
|
||||||
root_0 = (<ASTLabelType>)adaptor.becomeRoot(<label>_tree, root_0);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createNodeFromToken(label,hetero) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(<label>) <! new MethodNode(IDLabel) !>
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)adaptor.create(<label>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<\n><endif>
|
|
||||||
retval.tree = (<ASTLabelType>)adaptor.rulePostProcessing(root_0);
|
|
||||||
adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
@ -1,281 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during tree parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* Each combination has its own template except that label/no label
|
|
||||||
* is combined into tokenRef, ruleRef, ...
|
|
||||||
*/
|
|
||||||
group ASTTreeParser;
|
|
||||||
|
|
||||||
/** Add a variable to track last element matched */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> _first_0 = null;
|
|
||||||
<ASTLabelType> _last = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What to emit when there is no rewrite rule. For auto build
|
|
||||||
* mode, does nothing.
|
|
||||||
*/
|
|
||||||
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
retval.tree = (<ASTLabelType>)_first_0;
|
|
||||||
if ( adaptor.getParent(retval.tree)!=null && adaptor.isNil( adaptor.getParent(retval.tree) ) )
|
|
||||||
retval.tree = (<ASTLabelType>)adaptor.getParent(retval.tree);
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser; override here to
|
|
||||||
* add tree construction actions.
|
|
||||||
*/
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
{
|
|
||||||
<ASTLabelType> _save_last_<treeLevel> = _last;
|
|
||||||
<ASTLabelType> _first_<treeLevel> = null;
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)adaptor.nil();
|
|
||||||
<endif>
|
|
||||||
<root:element()>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 )<endif>
|
|
||||||
<if(root.el.rule)>
|
|
||||||
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>.tree;
|
|
||||||
<else>
|
|
||||||
if ( _first_<enclosingTreeLevel>==null ) _first_<enclosingTreeLevel> = <root.el.label>;
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<actionsAfterRoot:element()>
|
|
||||||
<if(nullableChildList)>
|
|
||||||
if ( input.LA(1)==Token.DOWN ) {
|
|
||||||
match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
match(input, Token.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
match(input, Token.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
match(input, Token.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
_last = _save_last_<treeLevel>;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) 'cept add
|
|
||||||
* setting of _last
|
|
||||||
*/
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID auto construct */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.dupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
adaptor.addChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 )<endif>
|
|
||||||
if ( _first_<treeLevel>==null ) _first_<treeLevel> = <label>;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN auto construct */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) auto construct */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.dupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) auto construct */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.dupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
adaptor.addChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
<noRewrite()> <! set return tree !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.dupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule auto construct */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
adaptor.addChild(root_<treeLevel>, <label>.getTree());
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
if ( _first_<treeLevel>==null ) _first_<treeLevel> = <label>.tree;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule auto construct */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) auto construct */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<label>.getTree(), root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) auto construct */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefRootTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = (<ASTLabelType>)input.LT(1);
|
|
||||||
<super.ruleRefRuleRootTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Streams for token refs are tree nodes now; override to
|
|
||||||
* change nextToken to nextNode.
|
|
||||||
*/
|
|
||||||
createRewriteNodeFromElement(token,hetero,scope) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.nextNode())
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<\n><endif>
|
|
||||||
retval.tree = (<ASTLabelType>)adaptor.rulePostProcessing(root_0);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,259 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template overrides to add debugging to normal Java output;
|
|
||||||
* If ASTs are built, then you'll also get ASTDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group Dbg;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
import org.antlr.runtime.debug.*;
|
|
||||||
import java.io.IOException;
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<if(grammar.grammarIsRoot)>
|
|
||||||
public static final String[] ruleNames = new String[] {
|
|
||||||
"invalidRule", <grammar.allImportedRules:{rST | "<rST.name>"}; wrap="\n ", separator=", ">
|
|
||||||
};<\n>
|
|
||||||
<endif>
|
|
||||||
<if(grammar.grammarIsRoot)> <! grammar imports other grammar(s) !>
|
|
||||||
public int ruleLevel = 0;
|
|
||||||
public int getRuleLevel() { return ruleLevel; }
|
|
||||||
public void incRuleLevel() { ruleLevel++; }
|
|
||||||
public void decRuleLevel() { ruleLevel--; }
|
|
||||||
<if(profile)>
|
|
||||||
<ctorForProfilingRootGrammar()>
|
|
||||||
<else>
|
|
||||||
<ctorForRootGrammar()>
|
|
||||||
<endif>
|
|
||||||
<ctorForPredefinedListener()>
|
|
||||||
<else> <! imported grammar !>
|
|
||||||
public int getRuleLevel() { return <grammar.delegators:{g| <g:delegateName()>}>.getRuleLevel(); }
|
|
||||||
public void incRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.incRuleLevel(); }
|
|
||||||
public void decRuleLevel() { <grammar.delegators:{g| <g:delegateName()>}>.decRuleLevel(); }
|
|
||||||
<ctorForDelegateGrammar()>
|
|
||||||
<endif>
|
|
||||||
<if(profile)>
|
|
||||||
public boolean alreadyParsedRule(IntStream input, int ruleIndex) {
|
|
||||||
((Profiler)dbg).examineRuleMemoization(input, ruleIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
|
|
||||||
return super.alreadyParsedRule(input, ruleIndex);
|
|
||||||
}<\n>
|
|
||||||
public void memoize(IntStream input,
|
|
||||||
int ruleIndex,
|
|
||||||
int ruleStartIndex)
|
|
||||||
{
|
|
||||||
((Profiler)dbg).memoize(input, ruleIndex, ruleStartIndex, <grammar.composite.rootGrammar.recognizerName>.ruleNames[ruleIndex]);
|
|
||||||
super.memoize(input, ruleIndex, ruleStartIndex);
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
protected boolean evalPredicate(boolean result, String predicate) {
|
|
||||||
dbg.semanticPredicate(result, predicate);
|
|
||||||
return result;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForRootGrammar() ::= <<
|
|
||||||
<! bug: can't use <@super.members()> cut-n-paste instead !>
|
|
||||||
<! Same except we add port number and profile stuff if root grammar !>
|
|
||||||
public <name>(<inputStreamType> input) {
|
|
||||||
this(input, DebugEventSocketProxy.DEFAULT_DEBUGGER_PORT, new RecognizerSharedState());
|
|
||||||
}
|
|
||||||
public <name>(<inputStreamType> input, int port, RecognizerSharedState state) {
|
|
||||||
super(input, state);
|
|
||||||
<parserCtorBody()>
|
|
||||||
<createListenerAndHandshake()>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForProfilingRootGrammar() ::= <<
|
|
||||||
<! bug: can't use <@super.members()> cut-n-paste instead !>
|
|
||||||
public <name>(<inputStreamType> input) {
|
|
||||||
this(input, new Profiler(null), new RecognizerSharedState());
|
|
||||||
}
|
|
||||||
public <name>(<inputStreamType> input, DebugEventListener dbg, RecognizerSharedState state) {
|
|
||||||
super(input, dbg, state);
|
|
||||||
Profiler p = (Profiler)dbg;
|
|
||||||
p.setParser(this);
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:
|
|
||||||
{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}
|
|
||||||
<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Basically we don't want to set any dbg listeners are root will have it. */
|
|
||||||
ctorForDelegateGrammar() ::= <<
|
|
||||||
public <name>(<inputStreamType> input, DebugEventListener dbg, RecognizerSharedState state<grammar.delegators:{g|, <g.recognizerName> <g:delegateName()>}>) {
|
|
||||||
super(input, dbg, state);
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:
|
|
||||||
{g|<g:delegateName()> = new <g.recognizerName>(input, this, this.state<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ctorForPredefinedListener() ::= <<
|
|
||||||
public <name>(<inputStreamType> input, DebugEventListener dbg) {
|
|
||||||
<@superClassRef>super(input, dbg, new RecognizerSharedState());<@end>
|
|
||||||
<if(profile)>
|
|
||||||
Profiler p = (Profiler)dbg;
|
|
||||||
p.setParser(this);
|
|
||||||
<endif>
|
|
||||||
<parserCtorBody()>
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()> = new <g.recognizerName>(input, dbg, this.state, this<grammar.delegators:{g|, <g:delegateName()>}>);}; separator="\n">
|
|
||||||
<@finally()>
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createListenerAndHandshake() ::= <<
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
DebugEventSocketProxy proxy =
|
|
||||||
new DebugEventSocketProxy(this, port, input.getTreeAdaptor());<\n>
|
|
||||||
<else>
|
|
||||||
DebugEventSocketProxy proxy =
|
|
||||||
new DebugEventSocketProxy(this, port, null);<\n>
|
|
||||||
<endif>
|
|
||||||
setDebugListener(proxy);
|
|
||||||
try {
|
|
||||||
proxy.handshake();
|
|
||||||
}
|
|
||||||
catch (IOException ioe) {
|
|
||||||
reportError(ioe);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.superClassName() ::= "Debug<@super.superClassName()>"
|
|
||||||
|
|
||||||
@rule.preamble() ::= <<
|
|
||||||
try { dbg.enterRule(getGrammarFileName(), "<ruleName>");
|
|
||||||
if ( getRuleLevel()==0 ) {dbg.commence();}
|
|
||||||
incRuleLevel();
|
|
||||||
dbg.location(<ruleDescriptor.tree.line>, <ruleDescriptor.tree.column>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@rule.postamble() ::= <<
|
|
||||||
dbg.location(<ruleDescriptor.EORNode.line>, <ruleDescriptor.EORNode.column>);<\n>
|
|
||||||
}
|
|
||||||
finally {
|
|
||||||
dbg.exitRule(getGrammarFileName(), "<ruleName>");
|
|
||||||
decRuleLevel();
|
|
||||||
if ( getRuleLevel()==0 ) {dbg.terminate();}
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@synpred.start() ::= "dbg.beginBacktrack(state.backtracking);"
|
|
||||||
|
|
||||||
@synpred.stop() ::= "dbg.endBacktrack(state.backtracking, success);"
|
|
||||||
|
|
||||||
// Common debug event triggers used by region overrides below
|
|
||||||
|
|
||||||
enterSubRule() ::=
|
|
||||||
"try { dbg.enterSubRule(<decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
exitSubRule() ::=
|
|
||||||
"} finally {dbg.exitSubRule(<decisionNumber>);}<\n>"
|
|
||||||
|
|
||||||
enterDecision() ::=
|
|
||||||
"try { dbg.enterDecision(<decisionNumber>);<\n>"
|
|
||||||
|
|
||||||
exitDecision() ::=
|
|
||||||
"} finally {dbg.exitDecision(<decisionNumber>);}<\n>"
|
|
||||||
|
|
||||||
enterAlt(n) ::= "dbg.enterAlt(<n>);<\n>"
|
|
||||||
|
|
||||||
// Region overrides that tell various constructs to add debugging triggers
|
|
||||||
|
|
||||||
@block.predecision() ::= "<enterSubRule()><enterDecision()>"
|
|
||||||
|
|
||||||
@block.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@block.postbranch() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@ruleBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@ruleBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@ruleBlockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@blockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.earlyExitException() ::=
|
|
||||||
"dbg.recognitionException(eee);<\n>"
|
|
||||||
|
|
||||||
@closureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@closureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@altSwitchCase.prealt() ::= "<enterAlt(n=i)>"
|
|
||||||
|
|
||||||
@element.prematch() ::=
|
|
||||||
"dbg.location(<it.line>,<it.pos>);"
|
|
||||||
|
|
||||||
@matchSet.mismatchedSetException() ::=
|
|
||||||
"dbg.recognitionException(mse);"
|
|
||||||
|
|
||||||
@dfaState.noViableAltException() ::= "dbg.recognitionException(nvae);"
|
|
||||||
|
|
||||||
@dfaStateSwitch.noViableAltException() ::= "dbg.recognitionException(nvae);"
|
|
||||||
|
|
||||||
dfaDecision(decisionNumber,description) ::= <<
|
|
||||||
try {
|
|
||||||
isCyclicDecision = true;
|
|
||||||
<super.dfaDecision(...)>
|
|
||||||
}
|
|
||||||
catch (NoViableAltException nvae) {
|
|
||||||
dbg.recognitionException(nvae);
|
|
||||||
throw nvae;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.errorMethod() ::= <<
|
|
||||||
public void error(NoViableAltException nvae) {
|
|
||||||
dbg.recognitionException(nvae);
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Force predicate validation to trigger an event */
|
|
||||||
evalPredicate(pred,description) ::= <<
|
|
||||||
evalPredicate(<pred>,"<description>")
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,163 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template subgroup to add template rewrite output
|
|
||||||
* If debugging, then you'll also get STDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group ST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
import org.antlr.stringtemplate.*;
|
|
||||||
import org.antlr.stringtemplate.language.*;
|
|
||||||
import java.util.HashMap;
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add this to each rule's return value struct */
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
public StringTemplate st;
|
|
||||||
public Object getTemplate() { return st; }
|
|
||||||
public String toString() { return st==null?null:st.toString(); }
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
protected StringTemplateGroup templateLib =
|
|
||||||
new StringTemplateGroup("<name>Templates", AngleBracketTemplateLexer.class);
|
|
||||||
|
|
||||||
public void setTemplateLib(StringTemplateGroup templateLib) {
|
|
||||||
this.templateLib = templateLib;
|
|
||||||
}
|
|
||||||
public StringTemplateGroup getTemplateLib() {
|
|
||||||
return templateLib;
|
|
||||||
}
|
|
||||||
/** allows convenient multi-value initialization:
|
|
||||||
* "new STAttrMap().put(...).put(...)"
|
|
||||||
*/
|
|
||||||
public static class STAttrMap extends HashMap {
|
|
||||||
public STAttrMap put(String attrName, Object value) {
|
|
||||||
super.put(attrName, value);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
public STAttrMap put(String attrName, int value) {
|
|
||||||
super.put(attrName, new Integer(value));
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=template */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".getTemplate()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplate(alts) ::= <<
|
|
||||||
|
|
||||||
// TEMPLATE REWRITE
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( state.backtracking==0 ) {
|
|
||||||
<alts:rewriteTemplateAlt(); separator="else ">
|
|
||||||
<if(rewriteMode)><replaceTextInLine()><endif>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
<alts:rewriteTemplateAlt(); separator="else ">
|
|
||||||
<if(rewriteMode)><replaceTextInLine()><endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
replaceTextInLine() ::= <<
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
((TokenRewriteStream)input.getTokenStream()).replace(
|
|
||||||
input.getTreeAdaptor().getTokenStartIndex(retval.start),
|
|
||||||
input.getTreeAdaptor().getTokenStopIndex(retval.start),
|
|
||||||
retval.st);
|
|
||||||
<else>
|
|
||||||
((TokenRewriteStream)input).replace(
|
|
||||||
((Token)retval.start).getTokenIndex(),
|
|
||||||
input.LT(-1).getTokenIndex(),
|
|
||||||
retval.st);
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplateAlt() ::= <<
|
|
||||||
// <it.description>
|
|
||||||
<if(it.pred)>
|
|
||||||
if (<it.pred>) {
|
|
||||||
retval.st = <it.alt>;
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
retval.st = <it.alt>;
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteEmptyTemplate(alts) ::= <<
|
|
||||||
null;
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Invoke a template with a set of attribute name/value pairs.
|
|
||||||
* Set the value of the rule's template *after* having set
|
|
||||||
* the attributes because the rule's template might be used as
|
|
||||||
* an attribute to build a bigger template; you get a self-embedded
|
|
||||||
* template.
|
|
||||||
*/
|
|
||||||
rewriteExternalTemplate(name,args) ::= <<
|
|
||||||
templateLib.getInstanceOf("<name>"<if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .put("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** expr is a string expression that says what template to load */
|
|
||||||
rewriteIndirectTemplate(expr,args) ::= <<
|
|
||||||
templateLib.getInstanceOf(<expr><if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .put("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Invoke an inline template with a set of attribute name/value pairs */
|
|
||||||
rewriteInlineTemplate(args, template) ::= <<
|
|
||||||
new StringTemplate(templateLib, "<template>"<if(args)>,
|
|
||||||
new STAttrMap()<args:{a | .put("<a.name>", <a.value>)}>
|
|
||||||
<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
<action>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** An action has %st.attrName=expr; or %{st}.attrName=expr; */
|
|
||||||
actionSetAttribute(st,attrName,expr) ::= <<
|
|
||||||
(<st>).setAttribute("<attrName>",<expr>);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Translate %{stringExpr} */
|
|
||||||
actionStringConstructor(stringExpr) ::= <<
|
|
||||||
new StringTemplate(templateLib,<stringExpr>)
|
|
||||||
>>
|
|
@ -1,387 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
group AST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
<parserMembers()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add an adaptor property that knows how to build trees */
|
|
||||||
parserMembers() ::= <<
|
|
||||||
<!protected TreeAdaptor adaptor = new CommonTreeAdaptor();<\n>!>
|
|
||||||
setTreeAdaptor: function(adaptor) {
|
|
||||||
this.adaptor = adaptor;
|
|
||||||
},
|
|
||||||
getTreeAdaptor: function() {
|
|
||||||
return this.adaptor;
|
|
||||||
},
|
|
||||||
>>
|
|
||||||
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
getTree: function() { return this.tree; }
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track rule's return AST */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
var root_0 = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelDefs() ::= <<
|
|
||||||
<super.ruleLabelDefs()>
|
|
||||||
<ruleDescriptor.tokenLabels:{var <it.label.text>_tree=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{var <it.label.text>_tree=null;}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{var stream_<it>=new org.antlr.runtime.tree.RewriteRuleTokenStream(this.adaptor,"token <it>");}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{var stream_<it>=new org.antlr.runtime.tree.RewriteRuleSubtreeStream(this.adaptor,"rule <it>");}; separator="\n">
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** When doing auto AST construction, we must define some variables;
|
|
||||||
* These should be turned off if doing rewrites. This must be a "mode"
|
|
||||||
* as a rule could have both rewrite and AST within the same alternative
|
|
||||||
* block.
|
|
||||||
*/
|
|
||||||
@alt.declarations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_0 = this.adaptor.nil();<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// T r a c k i n g R u l e E l e m e n t s
|
|
||||||
|
|
||||||
/** ID and track it for use in a rewrite rule */
|
|
||||||
tokenRefTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)> <! Track implies no auto AST construction!>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) <endif>stream_<token>.add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
|
|
||||||
* to the tracking list stream_ID for use in the rewrite.
|
|
||||||
*/
|
|
||||||
tokenRefTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) <endif>stream_<token>.add(<label>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardTrack(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) <endif>stream_<rule.name>.add(<label>.getTree());
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefTrack(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) <endif>stream_<rule>.add(<label>.getTree());
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// R e w r i t e
|
|
||||||
|
|
||||||
rewriteCode(
|
|
||||||
alts, description,
|
|
||||||
referencedElementsDeep, // ALL referenced elements to right of ->
|
|
||||||
referencedTokenLabels,
|
|
||||||
referencedTokenListLabels,
|
|
||||||
referencedRuleLabels,
|
|
||||||
referencedRuleListLabels,
|
|
||||||
rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::=
|
|
||||||
<<
|
|
||||||
|
|
||||||
// AST REWRITE
|
|
||||||
// elements: <referencedElementsDeep; separator=", ">
|
|
||||||
// token labels: <referencedTokenLabels; separator=", ">
|
|
||||||
// rule labels: <referencedRuleLabels; separator=", ">
|
|
||||||
// token list labels: <referencedTokenListLabels; separator=", ">
|
|
||||||
// rule list labels: <referencedRuleListLabels; separator=", ">
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( this.state.backtracking===0 ) {<\n>
|
|
||||||
<endif>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<rewriteCodeLabels()>
|
|
||||||
root_0 = this.adaptor.nil();
|
|
||||||
<alts:rewriteAlt(); separator="else ">
|
|
||||||
<! if tree parser and rewrite=true !>
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = this.adaptor.rulePostProcessing(root_0);
|
|
||||||
this.input.replaceChildren(this.adaptor.getParent(retval.start),
|
|
||||||
this.adaptor.getChildIndex(retval.start),
|
|
||||||
this.adaptor.getChildIndex(_last),
|
|
||||||
retval.tree);
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<! if parser or rewrite!=true, we need to set result !>
|
|
||||||
<if(!TREE_PARSER)>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = root_0;
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabels() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{var stream_<it>=new org.antlr.runtime.tree.RewriteRule<rewriteElementType>Stream(this.adaptor,"token <it>",<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{var stream_<it>=new org.antlr.runtime.tree.RewriteRule<rewriteElementType>Stream(this.adaptor,"token <it>", list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{var stream_<it>=new org.antlr.runtime.tree.RewriteRuleSubtreeStream(this.adaptor,"token <it>",<it>!=null?<it>.tree:null);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{var stream_<it>=new org.antlr.runtime.tree.RewriteRuleSubtreeStream(this.adaptor,"token <it>",list_<it>);};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Generate code for an optional rewrite block; note it uses the deep ref'd element
|
|
||||||
* list rather shallow like other blocks.
|
|
||||||
*/
|
|
||||||
rewriteOptionalBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
if ( <referencedElementsDeep:{el | stream_<el>.hasNext()}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElementsDeep:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
while ( <referencedElements:{el | stream_<el>.hasNext()}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewritePositiveClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
if ( !(<referencedElements:{el | stream_<el>.hasNext()}; separator="||">) ) {
|
|
||||||
throw new org.antlr.runtime.tree.RewriteEarlyExitException();
|
|
||||||
}
|
|
||||||
while ( <referencedElements:{el | stream_<el>.hasNext()}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteAlt(a) ::= <<
|
|
||||||
// <a.description>
|
|
||||||
<if(a.pred)>
|
|
||||||
if (<a.pred>) {
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** For empty rewrites: "r : ... -> ;" */
|
|
||||||
rewriteEmptyAlt() ::= "root_0 = null;"
|
|
||||||
|
|
||||||
rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
var root_<treeLevel> = this.adaptor.nil();
|
|
||||||
<root:rewriteElement()>
|
|
||||||
<children:rewriteElement()>
|
|
||||||
this.adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteElementList(elements) ::= "<elements:rewriteElement()>"
|
|
||||||
|
|
||||||
rewriteElement(e) ::= <<
|
|
||||||
<@pregen()>
|
|
||||||
<e.el>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ID or ID[args] */
|
|
||||||
rewriteTokenRef(token,elementIndex,hetero,args) ::= <<
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, <createRewriteNodeFromElement(...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label=ID */
|
|
||||||
rewriteTokenLabelRef(label,elementIndex) ::= <<
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label+=ID */
|
|
||||||
rewriteTokenListLabelRef(label,elementIndex) ::= <<
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) */
|
|
||||||
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) where label+=... */
|
|
||||||
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
|
|
||||||
|
|
||||||
/** Gen ^(ID ...) or ^(ID[args] ...) */
|
|
||||||
rewriteTokenRefRoot(token,elementIndex,hetero,args) ::= <<
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(<createRewriteNodeFromElement(...)>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRef(args,token,hetero,elementIndex) ::= <<
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRefRoot(args,token,hetero,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(<createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
root_0 = <action>;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What is the name of the previous value of this rule's root tree? This
|
|
||||||
* let's us refer to $rule to mean previous value. I am reusing the
|
|
||||||
* variable 'tree' sitting in retval struct to hold the value of root_0 right
|
|
||||||
* before I set it during rewrites. The assign will be to retval.tree.
|
|
||||||
*/
|
|
||||||
prevRuleRootRef() ::= "retval"
|
|
||||||
|
|
||||||
rewriteRuleRef(rule) ::= <<
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, stream_<rule>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteRuleRefRoot(rule) ::= <<
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(stream_<rule>.nextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeAction(action) ::= <<
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, <action>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeActionRoot(action) ::= <<
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(<action>, root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRef(label) ::= <<
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRef(label) ::= <<
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree());<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>);<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createImaginaryNode(tokenType,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<! new MethodNode(IDLabel, args) !>
|
|
||||||
new <hetero>(<tokenType><if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
this.adaptor.create(<tokenType>, <args; separator=", "><if(!args)>"<tokenType>"<endif>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createRewriteNodeFromElement(token,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.nextToken()<if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)> <! must create new node from old !>
|
|
||||||
this.adaptor.create(<token>, <args; separator=", ">)
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,161 +0,0 @@
|
|||||||
/** Templates for building ASTs during normal parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* The situation is not too bad as rewrite (->) usage makes ^ and !
|
|
||||||
* invalid. There is no huge explosion of combinations.
|
|
||||||
*/
|
|
||||||
group ASTParser;
|
|
||||||
|
|
||||||
@rule.setErrorReturnValue() ::= <<
|
|
||||||
retval.tree = this.adaptor.errorNode(this.input, retval.start, this.input.LT(-1), re);
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID and output=AST */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
this.adaptor.addChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) */
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>"
|
|
||||||
|
|
||||||
/** ID^ and output=AST */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<label>_tree = <createNodeFromToken(...)>;
|
|
||||||
root_0 = this.adaptor.becomeRoot(<label>_tree, root_0);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID! and output=AST */
|
|
||||||
tokenRefBangAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN when output=AST but not rewrite alt */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match label+=TOKEN^ when output=AST but not rewrite alt */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
// the match set stuff is interesting in that it uses an argument list
|
|
||||||
// to pass code to the default matchSet; another possible way to alter
|
|
||||||
// inherited code. I don't use the region stuff because I need to pass
|
|
||||||
// different chunks depending on the operator. I don't like making
|
|
||||||
// the template name have the operator as the number of templates gets
|
|
||||||
// large but this is the most flexible--this is as opposed to having
|
|
||||||
// the code generator call matchSet then add root code or ruleroot code
|
|
||||||
// plus list label plus ... The combinations might require complicated
|
|
||||||
// rather than just added on code. Investigate that refactoring when
|
|
||||||
// I have more time.
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( this.state.backtracking===0 ) <endif>this.adaptor.addChild(root_0, <createNodeFromToken(...)>);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= "<super.matchSet(...)>"
|
|
||||||
|
|
||||||
// note there is no matchSetTrack because -> rewrites force sets to be
|
|
||||||
// plain old blocks of alts: (A|B|...|C)
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<if(label)>
|
|
||||||
<label>=input.LT(1);<\n>
|
|
||||||
<endif>
|
|
||||||
<super.matchSet(..., postmatchCode={<if(backtracking)>if ( this.state.backtracking===0 ) <endif>root_0 = this.adaptor.becomeRoot(<createNodeFromToken(...)>, root_0);})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule when output=AST */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) <endif>this.adaptor.addChild(root_0, <label>.getTree());
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule! is same as normal rule ref */
|
|
||||||
ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
|
|
||||||
|
|
||||||
/** rule^ */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) <endif>root_0 = this.adaptor.becomeRoot(<label>.getTree(), root_0);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule! when output=AST is a rule ref with list addition */
|
|
||||||
ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefBang(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule^ */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// WILDCARD AST
|
|
||||||
|
|
||||||
wildcard(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<label>_tree = this.adaptor.create(<label>);
|
|
||||||
this.adaptor.addChild(root_0, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>"
|
|
||||||
|
|
||||||
wildcardRuleRoot(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<label>_tree = this.adaptor.create(<label>);
|
|
||||||
root_0 = this.adaptor.becomeRoot(<label>_tree, root_0);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createNodeFromToken(label,hetero) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(<label>) <! new MethodNode(IDLabel) !>
|
|
||||||
<else>
|
|
||||||
this.adaptor.create(<label>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<\n><endif>
|
|
||||||
retval.tree = this.adaptor.rulePostProcessing(root_0);
|
|
||||||
this.adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
@ -1,229 +0,0 @@
|
|||||||
/** Templates for building ASTs during tree parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* Each combination has its own template except that label/no label
|
|
||||||
* is combined into tokenRef, ruleRef, ...
|
|
||||||
*/
|
|
||||||
group ASTTreeParser;
|
|
||||||
|
|
||||||
/** Add a variable to track last element matched */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
var _first_0 = null;
|
|
||||||
var _last = null;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What to emit when there is no rewrite rule. For auto build
|
|
||||||
* mode, does nothing.
|
|
||||||
*/
|
|
||||||
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
retval.tree = _first_0;
|
|
||||||
if ( this.adaptor.getParent(retval.tree) && this.adaptor.isNil( this.adaptor.getParent(retval.tree) ) )
|
|
||||||
retval.tree = this.adaptor.getParent(retval.tree);
|
|
||||||
<endif>
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser; override here to
|
|
||||||
* add tree construction actions.
|
|
||||||
*/
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel) ::= <<
|
|
||||||
_last = this.input.LT(1);
|
|
||||||
{
|
|
||||||
var _save_last_<treeLevel> = _last;
|
|
||||||
var _first_<treeLevel> = null;
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
var root_<treeLevel> = this.adaptor.nil();
|
|
||||||
<endif>
|
|
||||||
<root:element()>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 )<endif>
|
|
||||||
<if(root.el.rule)>
|
|
||||||
if ( !_first_<enclosingTreeLevel> ) _first_<enclosingTreeLevel> = <root.el.label>.tree;
|
|
||||||
<else>
|
|
||||||
if ( !_first_<enclosingTreeLevel> ) _first_<enclosingTreeLevel> = <root.el.label>;
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<actionsAfterRoot:element()>
|
|
||||||
<if(nullableChildList)>
|
|
||||||
if ( this.input.LA(1)==org.antlr.runtime.Token.DOWN ) {
|
|
||||||
this.match(this.input, org.antlr.runtime.Token.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
this.match(this.input, org.antlr.runtime.Token.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
this.match(this.input, org.antlr.runtime.Token.DOWN, null); <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
this.match(this.input, org.antlr.runtime.Token.UP, null); <checkRuleBacktrackFailure()>
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
this.adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
_last = _save_last_<treeLevel>;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) 'cept add
|
|
||||||
* setting of _last
|
|
||||||
*/
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= <<
|
|
||||||
_last = this.input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID auto construct */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = this.input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = this.adaptor.dupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 )<endif>
|
|
||||||
if ( !_first_<treeLevel> ) _first_<treeLevel> = <label>;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN auto construct */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) auto construct */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = this.input.LT(1);
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = this.adaptor.dupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) auto construct */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = this.input.LT(1);
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = this.adaptor.dupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
<noRewrite()> <! set return tree !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = this.input.LT(1);
|
|
||||||
<super.matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<endif>
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = new <hetero>(<label>);
|
|
||||||
<else>
|
|
||||||
<label>_tree = this.adaptor.dupNode(<label>);
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = this.adaptor.becomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
}
|
|
||||||
)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule auto construct */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = this.input.LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) <endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
this.adaptor.addChild(root_<treeLevel>, <label>.getTree());
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
if ( !_first_<treeLevel> ) _first_<treeLevel> = <label>.tree;
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule auto construct */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) auto construct */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = this.input.LT(1);
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) <endif>root_<treeLevel> = this.adaptor.becomeRoot(<label>.getTree(), root_<treeLevel>);
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) auto construct */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Streams for token refs are tree nodes now; override to
|
|
||||||
* change nextToken to nextNode.
|
|
||||||
*/
|
|
||||||
createRewriteNodeFromElement(token,hetero,scope) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.nextNode())
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<if(backtracking)>if ( this.state.backtracking===0 ) {<\n><endif>
|
|
||||||
retval.tree = this.adaptor.rulePostProcessing(root_0);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,513 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2006, 2007 Kay Roepke
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
group AST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
<if(!TREE_PARSER)><! tree parser would already have imported !>
|
|
||||||
#import \<ANTLR/ANTLR.h><\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@parserHeaderFile.ivars() ::= <<
|
|
||||||
<@super.ivars()>
|
|
||||||
<parserIVars()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@parserHeaderFile.methodsdecl() ::= <<
|
|
||||||
<@super.methodsdecl()>
|
|
||||||
<parserMethodsDecl()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.methods() ::= <<
|
|
||||||
<@super.methods()>
|
|
||||||
<parserMethods()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** additional init code for tree support */
|
|
||||||
@genericParser.init() ::= <<
|
|
||||||
<@super.init()>
|
|
||||||
[self setTreeAdaptor:[[[ANTLRCommonTreeAdaptor alloc] init] autorelease]];
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
@genericParser.dealloc() ::= <<
|
|
||||||
[self setTreeAdaptor:nil];
|
|
||||||
<@super.dealloc()>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add an adaptor property that knows how to build trees */
|
|
||||||
parserIVars() ::= <<
|
|
||||||
id\<ANTLRTreeAdaptor> treeAdaptor;
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Declaration of additional tree support methods - go in interface of parserHeaderFile() */
|
|
||||||
parserMethodsDecl() ::= <<
|
|
||||||
- (id\<ANTLRTreeAdaptor>) treeAdaptor;
|
|
||||||
- (void) setTreeAdaptor:(id\<ANTLRTreeAdaptor>)theTreeAdaptor;
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Definition of addition tree support methods - go in implementation of genericParser() */
|
|
||||||
parserMethods() ::= <<
|
|
||||||
- (id\<ANTLRTreeAdaptor>) treeAdaptor
|
|
||||||
{
|
|
||||||
return treeAdaptor;
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) setTreeAdaptor:(id\<ANTLRTreeAdaptor>)aTreeAdaptor
|
|
||||||
{
|
|
||||||
if (aTreeAdaptor != treeAdaptor) {
|
|
||||||
[aTreeAdaptor retain];
|
|
||||||
[treeAdaptor release];
|
|
||||||
treeAdaptor = aTreeAdaptor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** addition ivars for returnscopes */
|
|
||||||
@returnScopeInterface.ivars() ::= <<
|
|
||||||
<recognizer.ASTLabelType; null="id"> tree;
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** the interface of returnScope methods */
|
|
||||||
@returnScopeInterface.methods() ::= <<
|
|
||||||
- (<recognizer.ASTLabelType; null="id">) tree;
|
|
||||||
- (void) setTree:(<recognizer.ASTLabelType; null="id">)aTree;
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** the implementation of returnScope methods */
|
|
||||||
@returnScope.methods() ::= <<
|
|
||||||
- (<ASTLabelType>) tree
|
|
||||||
{
|
|
||||||
return tree;
|
|
||||||
}
|
|
||||||
- (void) setTree:(<ASTLabelType>)aTree
|
|
||||||
{
|
|
||||||
if (tree != aTree) {
|
|
||||||
[aTree retain];
|
|
||||||
[tree release];
|
|
||||||
tree = aTree;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
- (void) dealloc
|
|
||||||
{
|
|
||||||
[self setTree:nil];
|
|
||||||
[super dealloc];
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track rule's return AST */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
<ASTLabelType> root_0 = nil;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelDefs() ::= <<
|
|
||||||
<super.ruleLabelDefs()>
|
|
||||||
<ruleDescriptor.tokenLabels:{<ASTLabelType> _<it.label.text>_tree = nil;}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{<ASTLabelType> _<it.label.text>_tree = nil;}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{ANTLRRewriteRuleTokenStream *_stream_<it>=[[ANTLRRewriteRuleTokenStream alloc] initWithTreeAdaptor:treeAdaptor description:@"token <it>"];}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{ANTLRRewriteRuleSubtreeStream *_stream_<it>=[[ANTLRRewriteRuleSubtreeStream alloc] initWithTreeAdaptor:treeAdaptor description:@"rule <it>"];}; separator="\n">
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<[ruleDescriptor.allTokenRefsInAltsWithRewrites,ruleDescriptor.allRuleRefsInAltsWithRewrites]
|
|
||||||
:{[_stream_<it> release];}; separator="\n">
|
|
||||||
<if(ruleDescriptor.hasMultipleReturnValues)>
|
|
||||||
<if(backtracking)>
|
|
||||||
if ( ![_state isBacktracking] ) {<\n>
|
|
||||||
<endif>
|
|
||||||
[_<prevRuleRootRef()> setTree:(<ASTLabelType>)[treeAdaptor postProcessTree:root_0]];
|
|
||||||
[treeAdaptor setBoundariesForTree:[_<prevRuleRootRef()> tree] fromToken:[_<prevRuleRootRef()> start] toToken:[_<prevRuleRootRef()> stop]];
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
[root_0 release];
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabelsCleanUp() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{[_stream_<it> release];};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{[_stream_<it> release];};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{[_stream_<it> release];};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{[_stream_<it> release];};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** When doing auto AST construction, we must define some variables;
|
|
||||||
* These should be turned off if doing rewrites. This must be a "mode"
|
|
||||||
* as a rule could have both rewrite and AST within the same alternative
|
|
||||||
* block.
|
|
||||||
*/
|
|
||||||
@alt.declarations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
root_0 = (<ASTLabelType>)[treeAdaptor newEmptyTree];<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// T r a c k i n g R u l e E l e m e n t s
|
|
||||||
|
|
||||||
/** ID and track it for use in a rewrite rule */
|
|
||||||
tokenRefTrack(token,label,elementIndex) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( ![_state isBacktracking] ) <endif>[_stream_<token> addElement:_<label>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
|
|
||||||
* to the tracking list stream_ID for use in the rewrite.
|
|
||||||
*/
|
|
||||||
tokenRefTrackAndListLabel(token,label,elementIndex) ::= <<
|
|
||||||
<tokenRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrack(token,label,elementIndex) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( ![_state isBacktracking] ) <endif>[_stream_<token> addElement:_<label>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( ![_state isBacktracking] ) <endif>[_stream_<rule.name> addElement:[_<label> tree]];
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRefRuleRoot(...)>
|
|
||||||
<if(backtracking)>if ( ![_state isBacktracking] ) <endif>[_stream_<rule.name> addElement:[_<label> tree]];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem="["+label+" tree]",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// R e w r i t e
|
|
||||||
|
|
||||||
rewriteCode(
|
|
||||||
alts, description,
|
|
||||||
referencedElementsDeep, // ALL referenced elements to right of ->
|
|
||||||
referencedTokenLabels,
|
|
||||||
referencedTokenListLabels,
|
|
||||||
referencedRuleLabels,
|
|
||||||
referencedRuleListLabels,
|
|
||||||
rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::=
|
|
||||||
<<
|
|
||||||
|
|
||||||
// AST REWRITE
|
|
||||||
// elements: <referencedElementsDeep; separator=", ">
|
|
||||||
// token labels: <referencedTokenLabels; separator=", ">
|
|
||||||
// rule labels: <referencedRuleLabels; separator=", ">
|
|
||||||
// token list labels: <referencedTokenListLabels; separator=", ">
|
|
||||||
// rule list labels: <referencedRuleListLabels; separator=", ">
|
|
||||||
<if(backtracking)>
|
|
||||||
if (![_state isBacktracking]) {<\n>
|
|
||||||
<endif>
|
|
||||||
int i_0 = 0;
|
|
||||||
root_0 = (<ASTLabelType>)[treeAdaptor newEmptyTree];
|
|
||||||
[_<prevRuleRootRef()> setTree:root_0];
|
|
||||||
<rewriteCodeLabels()>
|
|
||||||
<alts:rewriteAlt(); separator="else ">
|
|
||||||
<rewriteCodeLabelsCleanUp()>
|
|
||||||
<if(backtracking)>
|
|
||||||
}
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabels() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{ANTLRRewriteRuleTokenStream *_stream_<it>=[[ANTLRRewriteRuleTokenStream alloc] initWithTreeAdaptor:treeAdaptor description:@"token <it>" element:_<it>];};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{ANTLRRewriteRuleTokenStream *_stream_<it>=[[ANTLRRewriteRuleTokenStream alloc] initWithTreeAdaptor:treeAdaptor description:@"token <it>" elements:_<it>_list];};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{ANTLRRewriteRuleSubtreeStream *_stream_<it>=[[ANTLRRewriteRuleSubtreeStream alloc] initWithTreeAdaptor:treeAdaptor description:@"token <it>" element:_<it>!=nil?[_<it> tree]:nil];};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{ANTLRRewriteRuleSubtreeStream *_stream_<it>=[[ANTLRRewriteRuleSubtreeStream alloc] initWithTreeAdaptor:treeAdaptor description:@"token <it>" elements:_list_<it>];};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Generate code for an optional rewrite block; note it uses the deep ref'd element
|
|
||||||
* list rather shallow like other blocks.
|
|
||||||
*/
|
|
||||||
rewriteOptionalBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
if ( <referencedElementsDeep:{el | [_stream_<el> hasNext]}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElementsDeep:{el | [_stream_<el> reset];<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
while ( <referencedElements:{el | [_stream_<el> hasNext]}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | [_stream_<el> reset];<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewritePositiveClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
if ( !(<referencedElements:{el | [_stream_<el> hasNext]}; separator="||">) ) {
|
|
||||||
@throw [NSException exceptionWithName:@"RewriteEarlyExitException" reason:nil userInfo:nil];
|
|
||||||
}
|
|
||||||
while ( <referencedElements:{el | [_stream_<el> hasNext]}; separator="||"> ) {
|
|
||||||
<alt>
|
|
||||||
}
|
|
||||||
<referencedElements:{el | [_stream_<el> reset];<\n>}>
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
rewriteAlt(a) ::= <<
|
|
||||||
// <a.description>
|
|
||||||
<if(a.pred)>
|
|
||||||
if (<a.pred>) {
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<else>
|
|
||||||
{
|
|
||||||
<a.alt>
|
|
||||||
}<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** For empty rewrites: "r : ... -> ;" */
|
|
||||||
rewriteEmptyAlt() ::= "root_0 = nil;"
|
|
||||||
|
|
||||||
rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
|
|
||||||
// <fileName>:<description>
|
|
||||||
{
|
|
||||||
<ASTLabelType> root_<treeLevel> = (<ASTLabelType>)[treeAdaptor newEmptyTree];
|
|
||||||
<root:rewriteElement()>
|
|
||||||
<children:rewriteElement()>
|
|
||||||
[treeAdaptor addChild:root_<treeLevel> toTree:root_<enclosingTreeLevel>];
|
|
||||||
[root_<treeLevel> release];
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteElementList(elements) ::= "<elements:rewriteElement()>"
|
|
||||||
|
|
||||||
rewriteElement(e) ::= <<
|
|
||||||
<@pregen()>
|
|
||||||
<e.el>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ID or ID[args] */
|
|
||||||
rewriteTokenRef(token,elementIndex,hetero,args) ::= <<
|
|
||||||
<if(args)>
|
|
||||||
id\<ANTLRTree> _<token>_tree = [treeAdaptor newTreeWithToken:_<token>]; // TODO: args: <args; separator=", ">
|
|
||||||
<endif>
|
|
||||||
[treeAdaptor addChild:<if(args)>_<token>_tree<else>[_stream_<token> next]<endif> toTree:root_<treeLevel>];
|
|
||||||
<if(args)>
|
|
||||||
[_<token>_tree release];<\n>
|
|
||||||
<endif>
|
|
||||||
<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label=ID */
|
|
||||||
rewriteTokenLabelRef(label,elementIndex) ::= <<
|
|
||||||
[treeAdaptor addChild:[_stream_<label> next] toTree:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label+=ID */
|
|
||||||
rewriteTokenListLabelRef(label,elementIndex) ::= <<
|
|
||||||
[treeAdaptor addChild:[_stream_<label> next] toTree:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) */
|
|
||||||
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:[_stream_<label> next] parentOf:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) where label+=... */
|
|
||||||
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
|
|
||||||
|
|
||||||
/** Gen ^(ID ...) or ^(ID[args] ...) */
|
|
||||||
rewriteTokenRefRoot(token,elementIndex,hetero,args) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:[_stream_<token> next] parentOf:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRef(args,token,hetero,elementIndex) ::= <<
|
|
||||||
<if(first(rest(args)))><! got two arguments - means create from token with custom text!>
|
|
||||||
id\<ANTLRTree> _<token>_tree = [treeAdaptor newTreeWithToken:<first(args)> tokenType:<token> text:@<first(rest(args))>];
|
|
||||||
[treeAdaptor addChild:_<token>_tree toTree:root_<treeLevel>];
|
|
||||||
[_<token>_tree release];<\n>
|
|
||||||
<else><! at most one argument !>
|
|
||||||
<if(first(args))>
|
|
||||||
id\<ANTLRTree> _<token>_tree = [treeAdaptor newTreeWithToken:<first(args)> tokenType:<token>];
|
|
||||||
[treeAdaptor addChild:_<token>_tree toTree:root_<treeLevel>];
|
|
||||||
[_<token>_tree release];<\n>
|
|
||||||
<else><! no argument at all !>
|
|
||||||
id\<ANTLRTree> _<token>_tree = [treeAdaptor newTreeWithTokenType:<token> text:[tokenNames objectAtIndex:<token>]];
|
|
||||||
[treeAdaptor addChild:_<token>_tree toTree:root_<treeLevel>];
|
|
||||||
[_<token>_tree release];<\n>
|
|
||||||
<endif><! one arg !>
|
|
||||||
<endif><! two args !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRefRoot(args,token,hetero,elementIndex) ::= <<
|
|
||||||
<if(first(rest(args)))><! got two arguments - means create from token with custom text!>
|
|
||||||
id\<ANTLRTree> _<token>_tree = [treeAdaptor newTreeWithToken:<first(args)> tokenType:<token> text:@<first(rest(args))>];
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:_<token>_tree parentOf:root_<treeLevel>];
|
|
||||||
[_<token>_tree release];<\n>
|
|
||||||
<else><! at most one argument !>
|
|
||||||
<if(first(args))>
|
|
||||||
id\<ANTLRTree> _<token>_tree = [treeAdaptor newTreeWithToken:<first(args)> tokenType:<token>];
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:_<token>_tree parentOf:root_<treeLevel>];
|
|
||||||
[_<token>_tree release];<\n>
|
|
||||||
<else><! no argument at all !>id\<ANTLRTree> _<token>_tree = [treeAdaptor newTreeWithTokenType:<token> text:[tokenNames objectAtIndex:<token>]];
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:_<token>_tree parentOf:root_<treeLevel>];
|
|
||||||
[_<token>_tree release];<\n>
|
|
||||||
<endif><! one arg !>
|
|
||||||
<endif><! two args !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
root_0 = <action>;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What is the name of the previous value of this rule's root tree? This
|
|
||||||
* let's us refer to $rule to mean previous value. I am reusing the
|
|
||||||
* variable 'tree' sitting in retval struct to hold the value of root_0 right
|
|
||||||
* before I set it during rewrites. The assign will be to retval.tree.
|
|
||||||
*/
|
|
||||||
prevRuleRootRef() ::= "retval"
|
|
||||||
|
|
||||||
rewriteRuleRef(rule) ::= <<
|
|
||||||
[treeAdaptor addChild:[_stream_<rule> next] toTree:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteRuleRefRoot(rule) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:(id\<ANTLRTree>)[_stream_<rule> next] parentOf:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeAction(action) ::= <<
|
|
||||||
[treeAdaptor addChild:<action> toTree:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeActionRoot(action) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:<action> parentOf:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRef(label) ::= <<
|
|
||||||
[treeAdaptor addChild:[_<label> tree] toTree:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRef(label) ::= <<
|
|
||||||
[treeAdaptor addChild:[(ANTLR<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope *)[_stream_<label> next] tree] toTree:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:[_<label> tree] parentOf:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)[treeAdaptor makeNode:[(ANTLR<if(TREE_PARSER)>Tree<else>Parser<endif>RuleReturnScope *)[_stream_<label> next] tree] parentOf:root_<treeLevel>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createImaginaryNode(tokenType,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<! new MethodNode(IDLabel, args) !>
|
|
||||||
new <hetero>(<tokenType><if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)adaptor.create(<tokenType>, <args; separator=", "><if(!args)>"<tokenType>"<endif>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createRewriteNodeFromElement(token,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.nextToken()<if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)> <! must create new node from old !>
|
|
||||||
adaptor.create(<token>, <args; separator=", ">)
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2006 Kay Roepke
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
group ASTDbg;
|
|
||||||
|
|
||||||
/*
|
|
||||||
parserMembers() ::= <<
|
|
||||||
protected TreeAdaptor adaptor =
|
|
||||||
new DebugTreeAdaptor(dbg,new CommonTreeAdaptor());
|
|
||||||
public void setTreeAdaptor(TreeAdaptor adaptor) {
|
|
||||||
this.adaptor = new DebugTreeAdaptor(dbg,adaptor);
|
|
||||||
}
|
|
||||||
public TreeAdaptor getTreeAdaptor() {
|
|
||||||
return adaptor;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
*/
|
|
||||||
|
|
||||||
@treeParserHeaderFile.superClassName ::= "ANTLRDebugTreeParser"
|
|
||||||
|
|
||||||
@rewriteElement.pregen() ::= "[debugListener locationLine:<e.line> column:<e.pos>];"
|
|
@ -1,189 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007 Kay Roepke
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during normal parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* The situation is not too bad as rewrite (->) usage makes ^ and !
|
|
||||||
* invalid. There is no huge explosion of combinations.
|
|
||||||
*/
|
|
||||||
group ASTParser;
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID and output=AST */
|
|
||||||
tokenRef(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( backtracking == 0 ) {<endif>
|
|
||||||
_<label>_tree = (<ASTLabelType>)[treeAdaptor newTreeWithToken:_<label>];
|
|
||||||
[treeAdaptor addChild:_<label>_tree toTree:root_0];
|
|
||||||
[_<label>_tree release];
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) */
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>"
|
|
||||||
|
|
||||||
/** ID^ and output=AST */
|
|
||||||
tokenRefRuleRoot(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( backtracking == 0 ) {<endif>
|
|
||||||
_<label>_tree = (<ASTLabelType>)[treeAdaptor newTreeWithToken:_<label>];
|
|
||||||
root_0 = (<ASTLabelType>)[treeAdaptor makeNode:_<label>_tree parentOf:root_0];
|
|
||||||
[_<label>_tree release];
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID! and output=AST */
|
|
||||||
tokenRefBangAndListLabel(token,label,elementIndex) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN when output=AST but not rewrite alt */
|
|
||||||
tokenRefAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match label+=TOKEN^ when output=AST but not rewrite alt */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
// the match set stuff is interesting in that it uses an argument list
|
|
||||||
// to pass code to the default matchSet; another possible way to alter
|
|
||||||
// inherited code. I don't use the region stuff because I need to pass
|
|
||||||
// different chunks depending on the operator. I don't like making
|
|
||||||
// the template name have the operator as the number of templates gets
|
|
||||||
// large but this is the most flexible--this is as opposed to having
|
|
||||||
// the code generator call matchSet then add root code or ruleroot code
|
|
||||||
// plus list label plus ... The combinations might require complicated
|
|
||||||
// rather than just added on code. Investigate that refactoring when
|
|
||||||
// I have more time.
|
|
||||||
|
|
||||||
// TODO: add support for heterogeneous trees
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(backtracking)>if (backtracking == 0) {<endif>
|
|
||||||
_<label>_tree = (<ASTLabelType>)[treeAdaptor newTreeWithToken:_<label>];
|
|
||||||
[treeAdaptor addChild:_<label>_tree toTree:root_0];
|
|
||||||
[_<label>_tree release];
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= "<super.matchSet(...)>"
|
|
||||||
|
|
||||||
// note there is no matchSetTrack because -> rewrites force sets to be
|
|
||||||
// plain old blocks of alts: (A|B|...|C)
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(backtracking)>if (backtracking == 0) {<endif>
|
|
||||||
_<label>_tree = (<ASTLabelType>)[treeAdaptor newTreeWithToken:_<label>];
|
|
||||||
root_0 = (<ASTLabelType>)[treeAdaptor makeNode:_<label>_tree parentOf:root_0];
|
|
||||||
[_<label>_tree release];
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule when output=AST */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if (backtracking == 0) <endif>[treeAdaptor addChild:[_<label> tree] toTree:root_0];
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule! is same as normal rule ref */
|
|
||||||
ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
|
|
||||||
|
|
||||||
/** rule^ */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if (backtracking == 0) <endif>root_0 = (<ASTLabelType>)[treeAdaptor makeNode:[_<label> tree] parentOf:root_0];
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem="["+label+" tree]",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule! when output=AST is a rule ref with list addition */
|
|
||||||
ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefBang(...)>
|
|
||||||
<listLabel(elem="["+label+" tree]",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule^ */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem="["+label+" tree]",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// WILDCARD AST
|
|
||||||
|
|
||||||
wildcard(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if (backtracking == 0) {<endif>
|
|
||||||
_<label>_tree = (<ASTLabelType>)[treeAdaptor newTreeWithToken:_<label>];
|
|
||||||
[treeAdaptor addChild:_<label>_tree toTree:root_0];
|
|
||||||
[_<label>_tree release];
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>"
|
|
||||||
|
|
||||||
wildcardRuleRoot(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<if(backtracking)>if (backtracking == 0) {<endif>
|
|
||||||
_<label>_tree = (<ASTLabelType>)[treeAdaptor newTreeWithToken:_<label>];
|
|
||||||
root_0 = (<ASTLabelType>)[treeAdaptor makeNode:_<label>_tree parentOf:root_0];
|
|
||||||
[_<label>_tree release];
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
createNodeFromToken(label,hetero) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(<label>) <! new MethodNode(IDLabel) !>
|
|
||||||
<else>
|
|
||||||
(<ASTLabelType>)adaptor.create(<label>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,129 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2007 Kay Roepke
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
group ASTTreeParser;
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser; override here to
|
|
||||||
* add tree construction actions.
|
|
||||||
*/
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel) ::= <<
|
|
||||||
{
|
|
||||||
<ASTLabelType> root_<treeLevel> = [treeAdapator newEmptyTree];
|
|
||||||
<root:element()>
|
|
||||||
<actionsAfterRoot:element()>
|
|
||||||
<if(nullableChildList)>
|
|
||||||
if ( [input LA:1] == ANTLRTokenTypeDOWN ) {
|
|
||||||
[self match:input tokenType:ANTLRTokenTypeDOWN follow:nil]; <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
[self match:input tokenType:ANTLRTokenTypeUP follow:nil]; <checkRuleBacktrackFailure()>
|
|
||||||
}
|
|
||||||
<else>
|
|
||||||
[self match:input tokenType:ANTLRTokenTypeDOWN follow:nil]; <checkRuleBacktrackFailure()>
|
|
||||||
<children:element()>
|
|
||||||
[self match:input tokenType:ANTLRTokenTypeUP follow:nil]; <checkRuleBacktrackFailure()>
|
|
||||||
<endif>
|
|
||||||
[root_<treeLevel> release];
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What to emit when there is no rewrite. For auto build
|
|
||||||
* mode, does nothing.
|
|
||||||
*/
|
|
||||||
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
|
|
||||||
<if(rewriteMode)>retval.tree = (<ASTLabelType>)retval.start;<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID auto construct */
|
|
||||||
tokenRef(token,label,elementIndex) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.dupNode(<label>);
|
|
||||||
adaptor.addChild(root_<treeLevel>, <label>_tree);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN auto construct */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) auto construct */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) {<endif>
|
|
||||||
<label>_tree = (<ASTLabelType>)adaptor.dupNode(<label>);
|
|
||||||
root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<label>_tree, root_<treeLevel>);
|
|
||||||
<if(backtracking)>}<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) auto construct */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule auto construct */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>adaptor.addChild(root_<treeLevel>, <label>.getTree());
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule auto construct */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) auto construct */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(backtracking)>if ( state.backtracking==0 ) <endif>root_<treeLevel> = (<ASTLabelType>)adaptor.becomeRoot(<label>.getTree(), root_<treeLevel>);
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) auto construct */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".getTree()",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Streams for token refs are tree nodes now; override to
|
|
||||||
* change nextToken to nextNode.
|
|
||||||
*/
|
|
||||||
createRewriteNodeFromElement(token,hetero,scope) ::= <<
|
|
||||||
#error Heterogeneous tree support not implemented.
|
|
||||||
<if(hetero)>
|
|
||||||
new <hetero>(stream_<token>.nextNode())
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,178 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2006 Kay Roepke
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template overrides to add debugging to normal Objective-C output;
|
|
||||||
* If ASTs are built, then you'll also get ASTDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group Dbg;
|
|
||||||
|
|
||||||
@headerFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
#import \<ANTLR/ANTLRDebug.h>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@parserHeaderFile.ivars() ::= <<
|
|
||||||
int ruleLevel;
|
|
||||||
NSArray *ruleNames;
|
|
||||||
>>
|
|
||||||
|
|
||||||
@parserHeaderFile.methodsdecl() ::= <<
|
|
||||||
-(BOOL) evalPredicate:(NSString *)predicate matched:(BOOL)result;<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.init() ::= <<
|
|
||||||
ruleNames = [[NSArray alloc] initWithObjects:<rules:{rST | @"<rST.ruleName>"}; separator=", ", wrap="\n ">, nil];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.dealloc() ::= <<
|
|
||||||
[ruleNames release];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.methods() ::= <<
|
|
||||||
-(BOOL) evalPredicate:(NSString *)predicate matched:(BOOL)result
|
|
||||||
{
|
|
||||||
[debugListener semanticPredicate:predicate matched:result];
|
|
||||||
return result;
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/* bug: can't use @super.superClassName()> */
|
|
||||||
@parserHeaderFile.superClassName() ::= "ANTLRDebug<if(TREE_PARSER)>Tree<endif>Parser"
|
|
||||||
|
|
||||||
@rule.preamble() ::= <<
|
|
||||||
@try { [debugListener enterRule:@"<ruleName>"];
|
|
||||||
if ( ruleLevel==0 ) [debugListener commence];
|
|
||||||
ruleLevel++;
|
|
||||||
[debugListener locationLine:<ruleDescriptor.tree.line> column:<ruleDescriptor.tree.column>];<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@rule.postamble() ::= <<
|
|
||||||
[debugListener locationLine:<ruleDescriptor.EORNode.line> column:<ruleDescriptor.EORNode.column>];<\n>
|
|
||||||
}
|
|
||||||
@finally {
|
|
||||||
[debugListener exitRule:@"<ruleName>"];
|
|
||||||
ruleLevel--;
|
|
||||||
if ( ruleLevel==0 ) [debugListener terminate];
|
|
||||||
}<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/* these are handled in the runtime for now.
|
|
||||||
* stinks, but that's the easiest way to avoid having to generate two
|
|
||||||
* methods for each synpred
|
|
||||||
|
|
||||||
@synpred.start() ::= "[debugListener beginBacktrack:backtracking];"
|
|
||||||
|
|
||||||
@synpred.stop() ::= "[debugListener endBacktrack:backtracking wasSuccessful:success];"
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Common debug event triggers used by region overrides below
|
|
||||||
|
|
||||||
enterSubRule() ::=
|
|
||||||
"@try { [debugListener enterSubRule:<decisionNumber>];<\n>"
|
|
||||||
|
|
||||||
exitSubRule() ::=
|
|
||||||
"} @finally { [debugListener exitSubRule:<decisionNumber>]; }<\n>"
|
|
||||||
|
|
||||||
enterDecision() ::=
|
|
||||||
"@try { [debugListener enterDecision:<decisionNumber>];<\n>"
|
|
||||||
|
|
||||||
exitDecision() ::=
|
|
||||||
"} @finally { [debugListener exitDecision:<decisionNumber>]; }<\n>"
|
|
||||||
|
|
||||||
enterAlt(n) ::= "[debugListener enterAlt:<n>];<\n>"
|
|
||||||
|
|
||||||
// Region overrides that tell various constructs to add debugging triggers
|
|
||||||
|
|
||||||
@block.predecision() ::= "<enterSubRule()><enterDecision()>"
|
|
||||||
|
|
||||||
@block.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@block.postbranch() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@ruleBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@ruleBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@ruleBlockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@blockSingleAlt.prealt() ::= "<enterAlt(n=\"1\")>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@positiveClosureBlock.earlyExitException() ::=
|
|
||||||
"[debugListener recognitionException:eee];<\n>"
|
|
||||||
|
|
||||||
@closureBlock.preloop() ::= "<enterSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.postloop() ::= "<exitSubRule()>"
|
|
||||||
|
|
||||||
@closureBlock.predecision() ::= "<enterDecision()>"
|
|
||||||
|
|
||||||
@closureBlock.postdecision() ::= "<exitDecision()>"
|
|
||||||
|
|
||||||
@altSwitchCase.prealt() ::= "<enterAlt(n=i)>"
|
|
||||||
|
|
||||||
@element.prematch() ::=
|
|
||||||
"[debugListener locationLine:<it.line> column:<it.pos>];"
|
|
||||||
|
|
||||||
@matchSet.mismatchedSetException() ::=
|
|
||||||
"[debugListener recognitionException:mse];"
|
|
||||||
|
|
||||||
@dfaState.noViableAltException() ::= "[debugListener recognitionException:nvae];"
|
|
||||||
|
|
||||||
@dfaStateSwitch.noViableAltException() ::= "[debugListener recognitionException:nvae];"
|
|
||||||
|
|
||||||
dfaDecision(decisionNumber,description) ::= <<
|
|
||||||
@try {
|
|
||||||
// isCyclicDecision is only necessary for the Profiler. Which I didn't do, yet.
|
|
||||||
// isCyclicDecision = YES;
|
|
||||||
<super.dfaDecision(...)>
|
|
||||||
}
|
|
||||||
@catch (ANTLRNoViableAltException *nvae) {
|
|
||||||
[debugListener recognitionException:nvae];
|
|
||||||
@throw nvae;
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
@cyclicDFA.errorMethod() ::= <<
|
|
||||||
-(void) error:(ANTLRNoViableAltException *)nvae
|
|
||||||
{
|
|
||||||
[[recognizer debugListener] recognitionException:nvae];
|
|
||||||
}
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Force predicate validation to trigger an event */
|
|
||||||
evalPredicate(pred,description) ::= <<
|
|
||||||
[self evalPredicate:@"<description>" result:<pred>];
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,440 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* in sync with Java/AST.stg revision 36 */
|
|
||||||
|
|
||||||
group AST;
|
|
||||||
|
|
||||||
finishedBacktracking(block) ::= <<
|
|
||||||
<if(backtracking)>
|
|
||||||
if self._state.backtracking == 0:
|
|
||||||
<block>
|
|
||||||
<else>
|
|
||||||
<block>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
<if(!TREE_PARSER)><! tree parser would already have imported !>
|
|
||||||
from antlr3.tree import *<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add an adaptor property that knows how to build trees */
|
|
||||||
@genericParser.init() ::= <<
|
|
||||||
<@super.init()>
|
|
||||||
self._adaptor = CommonTreeAdaptor()
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
def getTreeAdaptor(self):
|
|
||||||
return self._adaptor
|
|
||||||
|
|
||||||
def setTreeAdaptor(self, adaptor):
|
|
||||||
self._adaptor = adaptor
|
|
||||||
<grammar.directDelegates:{g|<g:delegateName()>.adaptor = adaptor}; separator="\n">
|
|
||||||
|
|
||||||
adaptor = property(getTreeAdaptor, setTreeAdaptor)
|
|
||||||
>>
|
|
||||||
|
|
||||||
@returnScope.ruleReturnInit() ::= <<
|
|
||||||
self.tree = None
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
/** Add a variable to track rule's return AST */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
root_0 = None<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleLabelDefs() ::= <<
|
|
||||||
<super.ruleLabelDefs()>
|
|
||||||
<ruleDescriptor.tokenLabels:{<it.label.text>_tree = None}; separator="\n">
|
|
||||||
<ruleDescriptor.tokenListLabels:{<it.label.text>_tree = None}; separator="\n">
|
|
||||||
<ruleDescriptor.allTokenRefsInAltsWithRewrites
|
|
||||||
:{stream_<it> = RewriteRule<rewriteElementType>Stream(self._adaptor, "token <it>")}; separator="\n">
|
|
||||||
<ruleDescriptor.allRuleRefsInAltsWithRewrites
|
|
||||||
:{stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "rule <it>")}; separator="\n">
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** When doing auto AST construction, we must define some variables;
|
|
||||||
* These should be turned off if doing rewrites. This must be a "mode"
|
|
||||||
* as a rule could have both rewrite and AST within the same alternative
|
|
||||||
* block.
|
|
||||||
*/
|
|
||||||
@alt.declarations() ::= <<
|
|
||||||
<if(autoAST)>
|
|
||||||
<if(outerAlt)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_0 = self._adaptor.nil()<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
|
|
||||||
// // T r a c k i n g R u l e E l e m e n t s
|
|
||||||
|
|
||||||
/** ID and track it for use in a rewrite rule */
|
|
||||||
tokenRefTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)> <! Track implies no auto AST construction!>
|
|
||||||
<finishedBacktracking({stream_<token>.add(<label>)})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID and track it for use in a rewrite rule; adds to ids *and*
|
|
||||||
* to the tracking list stream_ID for use in the rewrite.
|
|
||||||
*/
|
|
||||||
tokenRefTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrack(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<finishedBacktracking({stream_<token>.add(<label>)})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) track for rewrite */
|
|
||||||
tokenRefRuleRootTrackAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardTrack(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<finishedBacktracking({stream_<rule.name>.add(<label>.tree)})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefTrack(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<finishedBacktracking({stream_<rule.name>.add(<label>.tree)})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRootTrack(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// R e w r i t e
|
|
||||||
|
|
||||||
rewriteCode(
|
|
||||||
alts, description,
|
|
||||||
referencedElementsDeep, // ALL referenced elements to right of ->
|
|
||||||
referencedTokenLabels,
|
|
||||||
referencedTokenListLabels,
|
|
||||||
referencedRuleLabels,
|
|
||||||
referencedRuleListLabels,
|
|
||||||
rewriteBlockLevel, enclosingTreeLevel, treeLevel) ::=
|
|
||||||
<<
|
|
||||||
# AST Rewrite
|
|
||||||
# elements: <referencedElementsDeep; separator=", ">
|
|
||||||
# token labels: <referencedTokenLabels; separator=", ">
|
|
||||||
# rule labels: <referencedRuleLabels; separator=", ">
|
|
||||||
# token list labels: <referencedTokenListLabels; separator=", ">
|
|
||||||
# rule list labels: <referencedRuleListLabels; separator=", ">
|
|
||||||
<finishedBacktracking({
|
|
||||||
<prevRuleRootRef()>.tree = root_0
|
|
||||||
<rewriteCodeLabels()>
|
|
||||||
root_0 = self._adaptor.nil()
|
|
||||||
<first(alts):rewriteAltFirst(); anchor>
|
|
||||||
|
|
||||||
<rest(alts):{a | el<rewriteAltRest(a)>}; anchor, separator="\n\n">
|
|
||||||
|
|
||||||
<! if tree parser and rewrite=true !>
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = self._adaptor.rulePostProcessing(root_0)
|
|
||||||
self.input.replaceChildren(
|
|
||||||
self._adaptor.getParent(retval.start),
|
|
||||||
self._adaptor.getChildIndex(retval.start),
|
|
||||||
self._adaptor.getChildIndex(_last),
|
|
||||||
retval.tree
|
|
||||||
)<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
|
|
||||||
<! if parser or tree-parser and rewrite!=true, we need to set result !>
|
|
||||||
<if(!TREE_PARSER)>
|
|
||||||
<prevRuleRootRef()>.tree = root_0<\n>
|
|
||||||
<else>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<prevRuleRootRef()>.tree = root_0<\n>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteCodeLabels() ::= <<
|
|
||||||
<referencedTokenLabels
|
|
||||||
:{stream_<it> = RewriteRule<rewriteElementType>Stream(self._adaptor, "token <it>", <it>)};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedTokenListLabels
|
|
||||||
:{stream_<it> = RewriteRule<rewriteElementType>Stream(self._adaptor, "token <it>", list_<it>)};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleLabels
|
|
||||||
:{
|
|
||||||
if <it> is not None:
|
|
||||||
stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "token <it>", <it>.tree)
|
|
||||||
else:
|
|
||||||
stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "token <it>", None)
|
|
||||||
};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
<referencedRuleListLabels
|
|
||||||
:{stream_<it> = RewriteRuleSubtreeStream(self._adaptor, "token <it>", list_<it>)};
|
|
||||||
separator="\n"
|
|
||||||
>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Generate code for an optional rewrite block; note it uses the deep ref'd element
|
|
||||||
* list rather shallow like other blocks.
|
|
||||||
*/
|
|
||||||
rewriteOptionalBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
# <fileName>:<description>
|
|
||||||
if <referencedElementsDeep:{el | stream_<el>.hasNext()}; separator=" or ">:
|
|
||||||
<alt>
|
|
||||||
|
|
||||||
<referencedElementsDeep:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
# <fileName>:<description>
|
|
||||||
while <referencedElements:{el | stream_<el>.hasNext()}; separator=" or ">:
|
|
||||||
<alt>
|
|
||||||
|
|
||||||
<referencedElements:{el | stream_<el>.reset();<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewritePositiveClosureBlock(
|
|
||||||
alt,rewriteBlockLevel,
|
|
||||||
referencedElementsDeep, // all nested refs
|
|
||||||
referencedElements, // elements in immediately block; no nested blocks
|
|
||||||
description) ::=
|
|
||||||
<<
|
|
||||||
# <fileName>:<description>
|
|
||||||
if not (<referencedElements:{el | stream_<el>.hasNext()}; separator=" or ">):
|
|
||||||
raise RewriteEarlyExitException()
|
|
||||||
|
|
||||||
while <referencedElements:{el | stream_<el>.hasNext()}; separator=" or ">:
|
|
||||||
<alt>
|
|
||||||
|
|
||||||
<referencedElements:{el | stream_<el>.reset()<\n>}>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteAltRest(a) ::= <<
|
|
||||||
<if(a.pred)>
|
|
||||||
if <a.pred>:
|
|
||||||
# <a.description>
|
|
||||||
<a.alt>
|
|
||||||
<else>
|
|
||||||
se: <! little hack to get if .. elif .. else block right !>
|
|
||||||
# <a.description>
|
|
||||||
<a.alt>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteAltFirst(a) ::= <<
|
|
||||||
<if(a.pred)>
|
|
||||||
if <a.pred>:
|
|
||||||
# <a.description>
|
|
||||||
<a.alt>
|
|
||||||
<else>
|
|
||||||
# <a.description>
|
|
||||||
<a.alt>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** For empty rewrites: "r : ... -> ;" */
|
|
||||||
rewriteEmptyAlt() ::= "root_0 = None"
|
|
||||||
|
|
||||||
rewriteTree(root,children,description,enclosingTreeLevel,treeLevel) ::= <<
|
|
||||||
# <fileName>:<description>
|
|
||||||
root_<treeLevel> = self._adaptor.nil()
|
|
||||||
<root:rewriteElement()>
|
|
||||||
<children:rewriteElement()>
|
|
||||||
self._adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteElementList(elements) ::= "<elements:rewriteElement()>"
|
|
||||||
|
|
||||||
rewriteElement(e) ::= <<
|
|
||||||
<@pregen()>
|
|
||||||
<e.el>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ID or ID[args] */
|
|
||||||
rewriteTokenRef(token,elementIndex,hetero,args) ::= <<
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, <createRewriteNodeFromElement(...)>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label=ID */
|
|
||||||
rewriteTokenLabelRef(label,elementIndex) ::= <<
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode())<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $label ... where defined via label+=ID */
|
|
||||||
rewriteTokenListLabelRef(label,elementIndex) ::= <<
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextNode())<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) */
|
|
||||||
rewriteTokenLabelRefRoot(label,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($label ...) where label+=... */
|
|
||||||
rewriteTokenListLabelRefRoot ::= rewriteTokenLabelRefRoot
|
|
||||||
|
|
||||||
/** Gen ^(ID ...) or ^(ID[args] ...) */
|
|
||||||
rewriteTokenRefRoot(token,elementIndex,hetero,args) ::= <<
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(<createRewriteNodeFromElement(...)>, root_<treeLevel>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRef(args,token,hetero,elementIndex) ::= <<
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, <createImaginaryNode(tokenType=token, ...)>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteImaginaryTokenRefRoot(args,token,hetero,elementIndex) ::= <<
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(<createImaginaryNode(tokenType=token, ...)>, root_<treeLevel>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
<!FIXME(96,untested)!>
|
|
||||||
root_0 = <action><\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What is the name of the previous value of this rule's root tree? This
|
|
||||||
* let's us refer to $rule to mean previous value. I am reusing the
|
|
||||||
* variable 'tree' sitting in retval struct to hold the value of root_0 right
|
|
||||||
* before I set it during rewrites. The assign will be to retval.tree.
|
|
||||||
*/
|
|
||||||
prevRuleRootRef() ::= "retval"
|
|
||||||
|
|
||||||
rewriteRuleRef(rule) ::= <<
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, stream_<rule>.nextTree())<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteRuleRefRoot(rule) ::= <<
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(stream_<rule>.nextNode(), root_<treeLevel>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeAction(action) ::= <<
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, <action>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteNodeActionRoot(action) ::= <<
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(<action>, root_<treeLevel>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRef(label) ::= <<
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree())<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen $ruleLabel ... where defined via ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRef(label) ::= <<
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, stream_<label>.nextTree())<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel=rule */
|
|
||||||
rewriteRuleLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Gen ^($ruleLabel ...) where ruleLabel+=rule */
|
|
||||||
rewriteRuleListLabelRefRoot(label) ::= <<
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(stream_<label>.nextNode(), root_<treeLevel>)<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createImaginaryNode(tokenType,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<! new MethodNode(IDLabel, args) !>
|
|
||||||
<hetero>(<tokenType><if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if (!args)>self._adaptor.createFromType(<tokenType>, "<tokenType>")
|
|
||||||
<else>self._adaptor.create(<tokenType>, <args; separator=", ">)
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
//<! need to call different adaptor.create*() methods depending of argument count !>
|
|
||||||
//<if (!args)>self._adaptor.createFromType(<tokenType>, "<tokenType>")
|
|
||||||
//<else><if (!rest(args))>self._adaptor.createFromType(<tokenType>, <first(args)>)
|
|
||||||
//<else><if (!rest(rest(args)))>self._adaptor.createFromToken(<tokenType>, <first(args)>, <first(rest(args))>)
|
|
||||||
//<endif>
|
|
||||||
//<endif>
|
|
||||||
//<endif>
|
|
||||||
|
|
||||||
|
|
||||||
createRewriteNodeFromElement(token,hetero,args) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<hetero>(stream_<token>.nextToken()<if(args)>, <args; separator=", "><endif>)
|
|
||||||
<else>
|
|
||||||
<if(args)> <! must create new node from old !>
|
|
||||||
<! need to call different adaptor.create*() methods depending of argument count !>
|
|
||||||
<if (!args)>self._adaptor.createFromType(<token>, "<token>")
|
|
||||||
<else><if (!rest(args))>self._adaptor.createFromToken(<token>, <first(args)>)
|
|
||||||
<else><if (!rest(rest(args)))>self._adaptor.createFromToken(<token>, <first(args)>, <first(rest(args))>)
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
@ -1,198 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during normal parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* The situation is not too bad as rewrite (->) usage makes ^ and !
|
|
||||||
* invalid. There is no huge explosion of combinations.
|
|
||||||
*/
|
|
||||||
group ASTParser;
|
|
||||||
|
|
||||||
finishedBacktracking(block) ::= <<
|
|
||||||
<if(backtracking)>
|
|
||||||
if self._state.backtracking == 0:
|
|
||||||
<block>
|
|
||||||
<else>
|
|
||||||
<block>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
@rule.setErrorReturnValue() ::= <<
|
|
||||||
retval.tree = self._adaptor.errorNode(self.input, retval.start, self.input.LT(-1), re)
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID and output=AST */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<label>_tree = <createNodeFromToken(...)>
|
|
||||||
self._adaptor.addChild(root_0, <label>_tree)
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) */
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= "<super.tokenRef(...)>"
|
|
||||||
|
|
||||||
/** ID^ and output=AST */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<label>_tree = <createNodeFromToken(...)>
|
|
||||||
root_0 = self._adaptor.becomeRoot(<label>_tree, root_0)
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ids+=ID! and output=AST */
|
|
||||||
tokenRefBangAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefBang(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN when output=AST but not rewrite alt */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match label+=TOKEN^ when output=AST but not rewrite alt */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,hetero,elementIndex) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
|
|
||||||
// the match set stuff is interesting in that it uses an argument list
|
|
||||||
// to pass code to the default matchSet; another possible way to alter
|
|
||||||
// inherited code. I don't use the region stuff because I need to pass
|
|
||||||
// different chunks depending on the operator. I don't like making
|
|
||||||
// the template name have the operator as the number of templates gets
|
|
||||||
// large but this is the most flexible--this is as opposed to having
|
|
||||||
// the code generator call matchSet then add root code or ruleroot code
|
|
||||||
// plus list label plus ... The combinations might require complicated
|
|
||||||
// rather than just added on code. Investigate that refactoring when
|
|
||||||
// I have more time.
|
|
||||||
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={<finishedBacktracking({self._adaptor.addChild(root_0, <createNodeFromToken(...)>)})>})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= "<super.matchSet(...)>"
|
|
||||||
|
|
||||||
// note there is no matchSetTrack because -> rewrites force sets to be
|
|
||||||
// plain old blocks of alts: (A|B|...|C)
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<if(label)>
|
|
||||||
<label> = self.input.LT(1)<\n>
|
|
||||||
<endif>
|
|
||||||
<super.matchSet(..., postmatchCode={<finishedBacktracking({root_0 = self._adaptor.becomeRoot(<createNodeFromToken(...)>, root_0)})>})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule when output=AST */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<finishedBacktracking({self._adaptor.addChild(root_0, <label>.tree)})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule! is same as normal rule ref */
|
|
||||||
ruleRefBang(rule,label,elementIndex,args,scope) ::= "<super.ruleRef(...)>"
|
|
||||||
|
|
||||||
/** rule^ */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<finishedBacktracking({root_0 = self._adaptor.becomeRoot(<label>.tree, root_0)})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule! when output=AST is a rule ref with list addition */
|
|
||||||
ruleRefBangAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefBang(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule^ */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// WILDCARD AST
|
|
||||||
|
|
||||||
wildcard(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<label>_tree = self._adaptor.createWithPayload(<label>)
|
|
||||||
self._adaptor.addChild(root_0, <label>_tree)
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
wildcardBang(label,elementIndex) ::= "<super.wildcard(...)>"
|
|
||||||
|
|
||||||
wildcardRuleRoot(label,elementIndex) ::= <<
|
|
||||||
<super.wildcard(...)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<label>_tree = self._adaptor.createWithPayload(<label>)
|
|
||||||
root_0 = self._adaptor.becomeRoot(<label>_tree, root_0)
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
createNodeFromToken(label,hetero) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<hetero>(<label>) <! new MethodNode(IDLabel) !>
|
|
||||||
<else>
|
|
||||||
self._adaptor.createWithPayload(<label>)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<finishedBacktracking({
|
|
||||||
retval.tree = self._adaptor.rulePostProcessing(root_0)
|
|
||||||
self._adaptor.setTokenBoundaries(retval.tree, retval.start, retval.stop)
|
|
||||||
})>
|
|
||||||
>>
|
|
@ -1,295 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/** Templates for building ASTs during tree parsing.
|
|
||||||
*
|
|
||||||
* Deal with many combinations. Dimensions are:
|
|
||||||
* Auto build or rewrite
|
|
||||||
* no label, label, list label (label/no-label handled together)
|
|
||||||
* child, root
|
|
||||||
* token, set, rule, wildcard
|
|
||||||
*
|
|
||||||
* Each combination has its own template except that label/no label
|
|
||||||
* is combined into tokenRef, ruleRef, ...
|
|
||||||
*/
|
|
||||||
group ASTTreeParser;
|
|
||||||
|
|
||||||
finishedBacktracking(block) ::= <<
|
|
||||||
<if(backtracking)>
|
|
||||||
if self._state.backtracking == 0:
|
|
||||||
<block>
|
|
||||||
<else>
|
|
||||||
<block>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add a variable to track last element matched */
|
|
||||||
ruleDeclarations() ::= <<
|
|
||||||
<super.ruleDeclarations()>
|
|
||||||
_first_0 = None
|
|
||||||
_last = None<\n>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** What to emit when there is no rewrite rule. For auto build
|
|
||||||
* mode, does nothing.
|
|
||||||
*/
|
|
||||||
noRewrite(rewriteBlockLevel, treeLevel) ::= <<
|
|
||||||
<finishedBacktracking({
|
|
||||||
<if(rewriteMode)>
|
|
||||||
retval.tree = _first_0
|
|
||||||
if self._adaptor.getParent(retval.tree) is not None and self._adaptor.isNil(self._adaptor.getParent(retval.tree)):
|
|
||||||
retval.tree = self._adaptor.getParent(retval.tree)
|
|
||||||
<endif>
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** match ^(root children) in tree parser; override here to
|
|
||||||
* add tree construction actions.
|
|
||||||
*/
|
|
||||||
tree(root, actionsAfterRoot, children, nullableChildList,
|
|
||||||
enclosingTreeLevel, treeLevel) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
_save_last_<treeLevel> = _last
|
|
||||||
_first_<treeLevel> = None
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
root_<treeLevel> = self._adaptor.nil()<\n>
|
|
||||||
<endif>
|
|
||||||
<root:element()>
|
|
||||||
<if(rewriteMode)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<if(root.el.rule)>
|
|
||||||
if _first_<enclosingTreeLevel> is None:
|
|
||||||
_first_<enclosingTreeLevel> = <root.el.label>.tree<\n>
|
|
||||||
<else>
|
|
||||||
if _first_<enclosingTreeLevel> is None:
|
|
||||||
_first_<enclosingTreeLevel> = <root.el.label><\n>
|
|
||||||
<endif>
|
|
||||||
})>
|
|
||||||
<endif>
|
|
||||||
<actionsAfterRoot:element()>
|
|
||||||
<if(nullableChildList)>
|
|
||||||
if self.input.LA(1) == DOWN:
|
|
||||||
self.match(self.input, DOWN, None)
|
|
||||||
<children:element()>
|
|
||||||
self.match(self.input, UP, None)
|
|
||||||
|
|
||||||
<else>
|
|
||||||
self.match(self.input, DOWN, None)
|
|
||||||
<children:element()>
|
|
||||||
self.match(self.input, UP, None)<\n>
|
|
||||||
<endif>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
self._adaptor.addChild(root_<enclosingTreeLevel>, root_<treeLevel>)<\n>
|
|
||||||
<endif>
|
|
||||||
_last = _save_last_<treeLevel>
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
// TOKEN AST STUFF
|
|
||||||
|
|
||||||
/** ID! and output=AST (same as plain tokenRef) 'cept add
|
|
||||||
* setting of _last
|
|
||||||
*/
|
|
||||||
tokenRefBang(token,label,elementIndex) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ID auto construct */
|
|
||||||
tokenRef(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = <hetero>(<label>)
|
|
||||||
<else>
|
|
||||||
<label>_tree = self._adaptor.dupNode(<label>)
|
|
||||||
<endif><\n>
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, <label>_tree)
|
|
||||||
})>
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
<finishedBacktracking({
|
|
||||||
if _first_<treeLevel> is None:
|
|
||||||
_first_<treeLevel> = <label><\n>
|
|
||||||
})>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** label+=TOKEN auto construct */
|
|
||||||
tokenRefAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRef(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(ID ...) auto construct */
|
|
||||||
tokenRefRuleRoot(token,label,elementIndex,hetero) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.tokenRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = <hetero>(<label>)
|
|
||||||
<else>
|
|
||||||
<label>_tree = self._adaptor.dupNode(<label>)
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(<label>_tree, root_<treeLevel>)
|
|
||||||
})>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Match ^(label+=TOKEN ...) auto construct */
|
|
||||||
tokenRefRuleRootAndListLabel(token,label,elementIndex,hetero) ::= <<
|
|
||||||
<tokenRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label,...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// SET AST
|
|
||||||
matchSet(s,label,hetero,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = <hetero>(<label>)
|
|
||||||
<else>
|
|
||||||
<label>_tree = self._adaptor.dupNode(<label>)
|
|
||||||
<endif><\n>
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, <label>_tree)
|
|
||||||
})>
|
|
||||||
<endif>
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchRuleBlockSet(s,label,hetero,elementIndex,postmatchCode,treeLevel="0") ::= <<
|
|
||||||
<matchSet(...)>
|
|
||||||
<noRewrite()> <! set return tree !>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetBang(s,label,elementIndex,postmatchCode) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.matchSet(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
matchSetRuleRoot(s,label,hetero,elementIndex,debug) ::= <<
|
|
||||||
<super.matchSet(..., postmatchCode={
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<if(hetero)>
|
|
||||||
<label>_tree = <hetero>(<label>)
|
|
||||||
<else>
|
|
||||||
<label>_tree = self._adaptor.dupNode(<label>)
|
|
||||||
<endif><\n>
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(<label>_tree, root_<treeLevel>)
|
|
||||||
})>
|
|
||||||
<endif>
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
// RULE REF AST
|
|
||||||
|
|
||||||
/** rule auto construct */
|
|
||||||
ruleRef(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
self._adaptor.addChild(root_<treeLevel>, <label>.tree)
|
|
||||||
<else> <! rewrite mode !>
|
|
||||||
if _first_<treeLevel> is None:
|
|
||||||
_first_<treeLevel> = <label>.tree<\n>
|
|
||||||
<endif>
|
|
||||||
})>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule auto construct */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) auto construct */
|
|
||||||
ruleRefRuleRoot(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.ruleRef(...)>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
root_<treeLevel> = self._adaptor.becomeRoot(<label>.tree, root_<treeLevel>)
|
|
||||||
})>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) auto construct */
|
|
||||||
ruleRefRuleRootAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRefRuleRoot(...)>
|
|
||||||
<listLabel(elem=label+".tree",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.ruleRefTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=AST and tracking for rewrite */
|
|
||||||
ruleRefTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.ruleRefTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrack(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.ruleRefRootTrack(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** ^(x+=rule ...) rewrite */
|
|
||||||
ruleRefRuleRootTrackAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
_last = self.input.LT(1)
|
|
||||||
<super.ruleRefRuleRootTrackAndListLabel(...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Streams for token refs are tree nodes now; override to
|
|
||||||
* change nextToken to nextNode.
|
|
||||||
*/
|
|
||||||
createRewriteNodeFromElement(token,hetero,scope) ::= <<
|
|
||||||
<if(hetero)>
|
|
||||||
<hetero>(stream_<token>.nextNode())
|
|
||||||
<else>
|
|
||||||
stream_<token>.nextNode()
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
ruleCleanUp() ::= <<
|
|
||||||
<super.ruleCleanUp()>
|
|
||||||
<if(!rewriteMode)>
|
|
||||||
<finishedBacktracking({
|
|
||||||
retval.tree = self._adaptor.rulePostProcessing(root_0)
|
|
||||||
})>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
@ -1,181 +0,0 @@
|
|||||||
/*
|
|
||||||
[The "BSD licence"]
|
|
||||||
Copyright (c) 2005-2006 Terence Parr
|
|
||||||
All rights reserved.
|
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
|
||||||
modification, are permitted provided that the following conditions
|
|
||||||
are met:
|
|
||||||
1. Redistributions of source code must retain the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer.
|
|
||||||
2. Redistributions in binary form must reproduce the above copyright
|
|
||||||
notice, this list of conditions and the following disclaimer in the
|
|
||||||
documentation and/or other materials provided with the distribution.
|
|
||||||
3. The name of the author may not be used to endorse or promote products
|
|
||||||
derived from this software without specific prior written permission.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
|
||||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
|
||||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
|
||||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
|
||||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
|
||||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
*/
|
|
||||||
/** Template subgroup to add template rewrite output
|
|
||||||
* If debugging, then you'll also get STDbg.stg loaded.
|
|
||||||
*/
|
|
||||||
group ST;
|
|
||||||
|
|
||||||
@outputFile.imports() ::= <<
|
|
||||||
<@super.imports()>
|
|
||||||
import stringtemplate3
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Add this to each rule's return value struct */
|
|
||||||
@returnScope.ruleReturnInit() ::= <<
|
|
||||||
self.st = None
|
|
||||||
>>
|
|
||||||
|
|
||||||
@returnScope.ruleReturnMembers() ::= <<
|
|
||||||
def getTemplate(self):
|
|
||||||
return self.st
|
|
||||||
|
|
||||||
def toString(self):
|
|
||||||
if self.st is not None:
|
|
||||||
return self.st.toString()
|
|
||||||
return None
|
|
||||||
__str__ = toString
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.init() ::= <<
|
|
||||||
<@super.init()>
|
|
||||||
self.templateLib = stringtemplate3.StringTemplateGroup(
|
|
||||||
'<name>Templates', lexer='angle-bracket'
|
|
||||||
)
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
@genericParser.members() ::= <<
|
|
||||||
<@super.members()>
|
|
||||||
def setTemplateLib(self, templateLib):
|
|
||||||
self.templateLib = templateLib
|
|
||||||
|
|
||||||
def getTemplateLib(self):
|
|
||||||
return self.templateLib
|
|
||||||
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** x+=rule when output=template */
|
|
||||||
ruleRefAndListLabel(rule,label,elementIndex,args,scope) ::= <<
|
|
||||||
<ruleRef(...)>
|
|
||||||
<listLabel(elem=label+".st",...)>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplate(alts) ::= <<
|
|
||||||
# TEMPLATE REWRITE
|
|
||||||
<if(backtracking)>
|
|
||||||
if self._state.backtracking == 0:
|
|
||||||
<first(alts):rewriteTemplateAltFirst()>
|
|
||||||
<rest(alts):{el<rewriteTemplateAlt()>}>
|
|
||||||
<if(rewriteMode)><replaceTextInLine()><endif>
|
|
||||||
|
|
||||||
<else>
|
|
||||||
<first(alts):rewriteTemplateAltFirst()>
|
|
||||||
<rest(alts):{el<rewriteTemplateAlt()>}>
|
|
||||||
<if(rewriteMode)><replaceTextInLine()><endif>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
replaceTextInLine() ::= <<
|
|
||||||
<if(TREE_PARSER)>
|
|
||||||
self.input.getTokenStream().replace(
|
|
||||||
self.input.getTreeAdaptor().getTokenStartIndex(retval.start),
|
|
||||||
self.input.getTreeAdaptor().getTokenStopIndex(retval.start),
|
|
||||||
retval.st
|
|
||||||
)
|
|
||||||
<else>
|
|
||||||
self.input.replace(
|
|
||||||
retval.start.getTokenIndex(),
|
|
||||||
self.input.LT(-1).getTokenIndex(),
|
|
||||||
retval.st
|
|
||||||
)
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplateAltFirst() ::= <<
|
|
||||||
<if(it.pred)>
|
|
||||||
if <it.pred>:
|
|
||||||
# <it.description>
|
|
||||||
retval.st = <it.alt>
|
|
||||||
<\n>
|
|
||||||
<else>
|
|
||||||
# <it.description>
|
|
||||||
retval.st = <it.alt>
|
|
||||||
<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteTemplateAlt() ::= <<
|
|
||||||
<if(it.pred)>
|
|
||||||
if <it.pred>:
|
|
||||||
# <it.description>
|
|
||||||
retval.st = <it.alt>
|
|
||||||
<\n>
|
|
||||||
<else>
|
|
||||||
se:
|
|
||||||
# <it.description>
|
|
||||||
retval.st = <it.alt>
|
|
||||||
<\n>
|
|
||||||
<endif>
|
|
||||||
>>
|
|
||||||
|
|
||||||
rewriteEmptyTemplate(alts) ::= <<
|
|
||||||
None
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Invoke a template with a set of attribute name/value pairs.
|
|
||||||
* Set the value of the rule's template *after* having set
|
|
||||||
* the attributes because the rule's template might be used as
|
|
||||||
* an attribute to build a bigger template; you get a self-embedded
|
|
||||||
* template.
|
|
||||||
*/
|
|
||||||
rewriteExternalTemplate(name,args) ::= <<
|
|
||||||
self.templateLib.getInstanceOf("<name>"<if(args)>,
|
|
||||||
attributes={<args:{a | "<a.name>": <a.value>}; separator=", ">}<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** expr is a string expression that says what template to load */
|
|
||||||
rewriteIndirectTemplate(expr,args) ::= <<
|
|
||||||
self.templateLib.getInstanceOf(<expr><if(args)>,
|
|
||||||
attributes={<args:{a | "<a.name>": <a.value>}; separator=", ">}<endif>)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Invoke an inline template with a set of attribute name/value pairs */
|
|
||||||
rewriteInlineTemplate(args, template) ::= <<
|
|
||||||
stringtemplate3.StringTemplate(
|
|
||||||
"<template>",
|
|
||||||
group=self.templateLib<if(args)>,
|
|
||||||
attributes={<args:{a | "<a.name>": <a.value>}; separator=", ">}
|
|
||||||
<endif>
|
|
||||||
)
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** plain -> {foo} action */
|
|
||||||
rewriteAction(action) ::= <<
|
|
||||||
<action>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** An action has %st.attrName=expr; or %{st}.attrName=expr; */
|
|
||||||
actionSetAttribute(st,attrName,expr) ::= <<
|
|
||||||
(<st>)["<attrName>"] = <expr>
|
|
||||||
>>
|
|
||||||
|
|
||||||
/** Translate %{stringExpr} */
|
|
||||||
actionStringConstructor(stringExpr) ::= <<
|
|
||||||
stringtemplate3.StringTemplate(<stringExpr>, group=self.templateLib)
|
|
||||||
>>
|
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user