refactoring resolving; alts know about rules and those know about grammars.
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6688]
This commit is contained in:
parent
b3f7c8e3cc
commit
172851245e
|
@ -117,13 +117,13 @@ CANNOT_ALIAS_TOKENS_IN_LEXER(arg) ::=
|
|||
ATTRIBUTE_REF_NOT_IN_RULE(arg,arg2) ::=
|
||||
"reference to attribute outside of a rule: <arg><if(arg2)>.<arg2><endif>"
|
||||
UNKNOWN_ATTRIBUTE_IN_SCOPE(arg,arg2) ::=
|
||||
"unknown attribute for <arg>: <arg2>"
|
||||
"attribute <arg> isn't a valid property in <arg2>"
|
||||
UNKNOWN_RULE_ATTRIBUTE(arg,arg2) ::=
|
||||
"unknown attribute for rule <arg>: <arg2>"
|
||||
UNKNOWN_SIMPLE_ATTRIBUTE(arg,args2) ::=
|
||||
"attribute is not a token, parameter, or return value: <arg>"
|
||||
ISOLATED_RULE_SCOPE(arg) ::=
|
||||
"missing attribute access on rule scope: <arg>"
|
||||
UNKNOWN_SIMPLE_ATTRIBUTE(arg,arg2) ::=
|
||||
"unknown attribute reference <arg> in <arg2>"
|
||||
ISOLATED_RULE_SCOPE(arg,arg2) ::=
|
||||
"missing attribute access on rule reference <arg> in <arg2>"
|
||||
INVALID_RULE_PARAMETER_REF(arg,arg2) ::=
|
||||
"cannot access rule <arg>'s parameter: <arg2>"
|
||||
INVALID_RULE_SCOPE_ATTRIBUTE_REF(arg,arg2) ::=
|
||||
|
@ -199,8 +199,6 @@ DOUBLE_QUOTES_ILLEGAL(arg) ::=
|
|||
"string literals must use single quotes (such as \'begin\'): <arg>"
|
||||
INVALID_TEMPLATE_ACTION(arg) ::=
|
||||
"invalid StringTemplate % shorthand syntax: '<arg>'"
|
||||
MISSING_ATTRIBUTE_NAME() ::=
|
||||
"missing attribute name on $ reference"
|
||||
ARG_INIT_VALUES_ILLEGAL(arg) ::=
|
||||
"rule parameters may not have init values: <arg>"
|
||||
REWRITE_OR_OP_WITH_NO_OUTPUT_OPTION(arg) ::=
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRLexer.g 2010-02-11 11:14:45
|
||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ANTLRLexer.g 2010-02-12 14:08:47
|
||||
|
||||
/*
|
||||
[The "BSD licence"]
|
||||
|
|
|
@ -330,7 +330,7 @@ tokenSpec
|
|||
// the grammar spec, rather than being declared within and therefore associated
|
||||
// with, a specific rule.
|
||||
attrScope
|
||||
: SCOPE id ACTION -> ^(SCOPE id ACTION)
|
||||
: SCOPE id ACTION -> ^(SCOPE id ACTION<ActionAST>)
|
||||
;
|
||||
|
||||
// A declaration of a language target specifc section,
|
||||
|
@ -338,7 +338,7 @@ attrScope
|
|||
// sections, they are just passed on to the language target.
|
||||
/** Match stuff like @parser::members {int i;} */
|
||||
action
|
||||
: AT (actionScopeName COLONCOLON)? id ACTION -> ^(AT actionScopeName? id ACTION)
|
||||
: AT (actionScopeName COLONCOLON)? id ACTION -> ^(AT actionScopeName? id ACTION<ActionAST>)
|
||||
;
|
||||
|
||||
/** Sometimes the scope names will collide with keywords; allow them as
|
||||
|
@ -436,13 +436,13 @@ exceptionGroup
|
|||
// Specifies a handler for a particular type of exception
|
||||
// thrown by a rule
|
||||
exceptionHandler
|
||||
: CATCH ARG_ACTION ACTION -> ^(CATCH ARG_ACTION ACTION)
|
||||
: CATCH ARG_ACTION ACTION -> ^(CATCH ARG_ACTION ACTION<ActionAST>)
|
||||
;
|
||||
|
||||
// Specifies a block of code to run after the rule and any
|
||||
// expcetion blocks have exceuted.
|
||||
finallyClause
|
||||
: FINALLY ACTION -> ^(FINALLY ACTION)
|
||||
: FINALLY ACTION -> ^(FINALLY ACTION<ActionAST>)
|
||||
;
|
||||
|
||||
// An individual rule level configuration as referenced by the ruleActions
|
||||
|
@ -499,7 +499,7 @@ ruleScopeSpec
|
|||
//
|
||||
/** Match stuff like @init {int i;} */
|
||||
ruleAction
|
||||
: AT id ACTION -> ^(AT id ACTION)
|
||||
: AT id ACTION -> ^(AT id ACTION<ActionAST>)
|
||||
;
|
||||
|
||||
// A set of access modifiers that may be applied to rule declarations
|
||||
|
@ -563,7 +563,7 @@ element
|
|||
| -> atom
|
||||
)
|
||||
| ebnf
|
||||
| ACTION
|
||||
| ACTION<ActionAST>
|
||||
| SEMPRED
|
||||
( IMPLIES -> GATED_SEMPRED[$IMPLIES]
|
||||
| -> SEMPRED
|
||||
|
@ -683,35 +683,13 @@ notTerminal
|
|||
// of options, which apply only to that block.
|
||||
//
|
||||
block
|
||||
: LPAREN
|
||||
|
||||
: LPAREN
|
||||
// A new blocked altlist may have a set of options set sepcifically
|
||||
// for it.
|
||||
//
|
||||
optionsSpec?
|
||||
|
||||
(
|
||||
// Optional @ sections OR an action, however we allow both
|
||||
// to be present and will let the semantic checking phase determine
|
||||
// what is allowable.
|
||||
//
|
||||
ra+=ruleAction*
|
||||
ACTION?
|
||||
|
||||
// COLON is optional with a block
|
||||
//
|
||||
COLON
|
||||
)?
|
||||
|
||||
// List of alts for this Paren block
|
||||
//
|
||||
altList
|
||||
|
||||
( optionsSpec? ra+=ruleAction* COLON )?
|
||||
altList
|
||||
RPAREN
|
||||
|
||||
// Rewrite as a block
|
||||
//
|
||||
-> ^(BLOCK<BlockAST> optionsSpec? $ra* ACTION? altList )
|
||||
-> ^(BLOCK<BlockAST> optionsSpec? $ra* altList )
|
||||
;
|
||||
|
||||
// ----------------
|
||||
|
@ -845,7 +823,7 @@ rewriteTreeAtom
|
|||
| RULE_REF
|
||||
| STRING_LITERAL elementOptions? -> ^(STRING_LITERAL<TerminalAST> elementOptions?)
|
||||
| DOLLAR id -> LABEL[$DOLLAR,$id.text] // reference to a label in a rewrite rule
|
||||
| ACTION
|
||||
| ACTION<ActionAST>
|
||||
;
|
||||
|
||||
rewriteTreeEbnf
|
||||
|
@ -887,7 +865,7 @@ rewriteTemplate
|
|||
rewriteIndirectTemplateHead
|
||||
|
||||
| // -> {...}
|
||||
ACTION
|
||||
ACTION<ActionAST>
|
||||
;
|
||||
|
||||
/** -> foo(a={...}, ...) */
|
||||
|
@ -899,7 +877,7 @@ rewriteTemplateRef
|
|||
/** -> ({expr})(a={...}, ...) */
|
||||
rewriteIndirectTemplateHead
|
||||
: lp=LPAREN ACTION RPAREN LPAREN rewriteTemplateArgs RPAREN
|
||||
-> ^(TEMPLATE[$lp,"TEMPLATE"] ACTION rewriteTemplateArgs?)
|
||||
-> ^(TEMPLATE[$lp,"TEMPLATE"] ACTION<ActionAST> rewriteTemplateArgs?)
|
||||
;
|
||||
|
||||
rewriteTemplateArgs
|
||||
|
@ -909,7 +887,7 @@ rewriteTemplateArgs
|
|||
;
|
||||
|
||||
rewriteTemplateArg
|
||||
: id ASSIGN ACTION -> ^(ARG[$ASSIGN] id ACTION)
|
||||
: id ASSIGN ACTION -> ^(ARG[$ASSIGN] id ACTION<ActionAST>)
|
||||
;
|
||||
|
||||
// The name of the grammar, and indeed some other grammar elements may
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,4 @@
|
|||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ASTVerifier.g 2010-02-11 11:14:48
|
||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 ASTVerifier.g 2010-02-12 14:08:50
|
||||
|
||||
/*
|
||||
[The "BSD license"]
|
||||
|
|
|
@ -45,20 +45,20 @@ LINE_COMMENT
|
|||
|
||||
SET_QUALIFIED_ATTR
|
||||
: '$' x=ID '.' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';'
|
||||
{delegate.setQualifiedAttr($x, $y, $expr);}
|
||||
{delegate.setQualifiedAttr($text, $x, $y, $expr);}
|
||||
;
|
||||
|
||||
QUALIFIED_ATTR
|
||||
: '$' x=ID '.' y=ID {input.LA(1)!='('}? {delegate.qualifiedAttr($x, $y);}
|
||||
: '$' x=ID '.' y=ID {input.LA(1)!='('}? {delegate.qualifiedAttr($text, $x, $y);}
|
||||
;
|
||||
|
||||
SET_DYNAMIC_SCOPE_ATTR
|
||||
: '$' x=ID '::' y=ID WS? '=' expr=ATTR_VALUE_EXPR ';'
|
||||
{delegate.setDynamicScopeAttr($x, $y, $expr);}
|
||||
{delegate.setDynamicScopeAttr($text, $x, $y, $expr);}
|
||||
;
|
||||
|
||||
DYNAMIC_SCOPE_ATTR
|
||||
: '$' x=ID '::' y=ID {delegate.dynamicScopeAttr($x, $y);}
|
||||
: '$' x=ID '::' y=ID {delegate.dynamicScopeAttr($text, $x, $y);}
|
||||
;
|
||||
|
||||
/** To access deeper (than top of stack) scopes, use the notation:
|
||||
|
@ -72,31 +72,31 @@ DYNAMIC_SCOPE_ATTR
|
|||
SET_DYNAMIC_NEGATIVE_INDEXED_SCOPE_ATTR
|
||||
: '$' x=ID '[' '-' index=SCOPE_INDEX_EXPR ']' '::' y=ID
|
||||
WS? ('=' expr=ATTR_VALUE_EXPR ';')?
|
||||
{delegate.setDynamicNegativeIndexedScopeAttr($x, $y, $index, $expr);}
|
||||
{delegate.setDynamicNegativeIndexedScopeAttr($text, $x, $y, $index, $expr);}
|
||||
;
|
||||
|
||||
DYNAMIC_NEGATIVE_INDEXED_SCOPE_ATTR
|
||||
: '$' x=ID '[' '-' index=SCOPE_INDEX_EXPR ']' '::' y=ID
|
||||
{delegate.dynamicNegativeIndexedScopeAttr($x, $y, $index);}
|
||||
{delegate.dynamicNegativeIndexedScopeAttr($text, $x, $y, $index);}
|
||||
;
|
||||
|
||||
SET_DYNAMIC_ABSOLUTE_INDEXED_SCOPE_ATTR
|
||||
: '$' x=ID '[' index=SCOPE_INDEX_EXPR ']' '::' y=ID
|
||||
WS? ('=' expr=ATTR_VALUE_EXPR ';')?
|
||||
{delegate.setDynamicAbsoluteIndexedScopeAttr($x, $y, $index, $expr);}
|
||||
WS? '=' expr=ATTR_VALUE_EXPR ';'
|
||||
{delegate.setDynamicAbsoluteIndexedScopeAttr($text, $x, $y, $index, $expr);}
|
||||
;
|
||||
|
||||
DYNAMIC_ABSOLUTE_INDEXED_SCOPE_ATTR
|
||||
: '$' x=ID '[' index=SCOPE_INDEX_EXPR ']' '::' y=ID
|
||||
{delegate.dynamicAbsoluteIndexedScopeAttr($x, $y, $index);}
|
||||
{delegate.dynamicAbsoluteIndexedScopeAttr($text, $x, $y, $index);}
|
||||
;
|
||||
|
||||
SET_ATTR
|
||||
: '$' x=ID WS? '=' expr=ATTR_VALUE_EXPR ';' {delegate.setAttr($x, $expr);}
|
||||
: '$' x=ID WS? '=' expr=ATTR_VALUE_EXPR ';' {delegate.setAttr($text, $x, $expr);}
|
||||
;
|
||||
|
||||
ATTR
|
||||
: '$' x=ID {delegate.attr($x);}
|
||||
: '$' x=ID {delegate.attr($text, $x);}
|
||||
;
|
||||
|
||||
/** %foo(a={},b={},...) ctor */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -4,23 +4,23 @@ import org.antlr.runtime.Token;
|
|||
|
||||
/** */
|
||||
public interface ActionSplitterListener {
|
||||
void setQualifiedAttr(Token x, Token y, Token expr);
|
||||
void qualifiedAttr(Token x, Token y);
|
||||
void setAttr(Token x, Token expr);
|
||||
void attr(Token x);
|
||||
void setQualifiedAttr(String expr, Token x, Token y, Token rhs);
|
||||
void qualifiedAttr(String expr, Token x, Token y);
|
||||
void setAttr(String expr, Token x, Token rhs);
|
||||
void attr(String expr, Token x);
|
||||
|
||||
void setDynamicScopeAttr(Token x, Token y, Token expr);
|
||||
void dynamicScopeAttr(Token x, Token y);
|
||||
void setDynamicNegativeIndexedScopeAttr(Token x, Token y, Token index, Token expr);
|
||||
void dynamicNegativeIndexedScopeAttr(Token x, Token y, Token index);
|
||||
void setDynamicAbsoluteIndexedScopeAttr(Token x, Token y, Token index, Token expr);
|
||||
void dynamicAbsoluteIndexedScopeAttr(Token x, Token y, Token index);
|
||||
void setDynamicScopeAttr(String expr, Token x, Token y, Token rhs);
|
||||
void dynamicScopeAttr(String expr, Token x, Token y);
|
||||
void setDynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs);
|
||||
void dynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index);
|
||||
void setDynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs);
|
||||
void dynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index);
|
||||
|
||||
void templateInstance();
|
||||
void indirectTemplateInstance();
|
||||
void setExprAttribute();
|
||||
void setAttribute();
|
||||
void templateExpr();
|
||||
void templateInstance(String expr);
|
||||
void indirectTemplateInstance(String expr);
|
||||
void setExprAttribute(String expr);
|
||||
void setAttribute(String expr);
|
||||
void templateExpr(String expr);
|
||||
|
||||
void unknownSyntax(String text);
|
||||
void text(String text);
|
||||
|
|
|
@ -11,20 +11,7 @@ public class GrammarASTAdaptor extends CommonTreeAdaptor {
|
|||
public GrammarASTAdaptor(CharStream input) { this.input = input; }
|
||||
|
||||
public Object create(Token token) {
|
||||
if ( token==null ) return new GrammarAST(token);
|
||||
switch ( token.getType() ) {
|
||||
// case ANTLRParser.BLOCK :
|
||||
// return new BlockAST(token);
|
||||
// case ANTLRParser.RULE :
|
||||
// return new RuleAST(token);
|
||||
// case ANTLRParser.PARSER_GRAMMAR :
|
||||
// case ANTLRParser.COMBINED_GRAMMAR :
|
||||
// case ANTLRParser.TREE_GRAMMAR :
|
||||
// case ANTLRParser.LEXER_GRAMMAR :
|
||||
// return new GrammarRootAST(token);
|
||||
default :
|
||||
return new GrammarAST(token);
|
||||
}
|
||||
return new GrammarAST(token);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,11 +12,11 @@ import java.util.List;
|
|||
public class AttributeChecks implements ActionSplitterListener {
|
||||
public Grammar g;
|
||||
public Rule r; // null if action outside of rule
|
||||
public Alternative alt; // null if action outside of rule
|
||||
public GrammarAST node;
|
||||
public Alternative alt; // null if action outside of alt; could be in rule
|
||||
public ActionAST node;
|
||||
public String action;
|
||||
|
||||
public AttributeChecks(Grammar g, Rule r, Alternative alt, GrammarAST node, String action) {
|
||||
public AttributeChecks(Grammar g, Rule r, Alternative alt, ActionAST node, String action) {
|
||||
this.g = g;
|
||||
this.r = r;
|
||||
this.alt = alt;
|
||||
|
@ -24,62 +24,112 @@ public class AttributeChecks implements ActionSplitterListener {
|
|||
this.action = action;
|
||||
}
|
||||
|
||||
public void examine() {
|
||||
public static void checkAllAttributeExpressions(Grammar g, List<Rule> rules) {
|
||||
for (Rule r : rules) {
|
||||
for (ActionAST a : r.namedActions.values()) {
|
||||
AttributeChecks checker = new AttributeChecks(g, r, null, a, a.getText());
|
||||
checker.examineAction();
|
||||
}
|
||||
for (int i=1; i<=r.numberOfAlts; i++) {
|
||||
Alternative alt = r.alt[i];
|
||||
for (ActionAST a : alt.actions) {
|
||||
AttributeChecks checker =
|
||||
new AttributeChecks(g, r, alt, a, a.getText());
|
||||
checker.examineAction();
|
||||
}
|
||||
}
|
||||
for (ActionAST a : r.exceptionActions) {
|
||||
AttributeChecks checker = new AttributeChecks(g, r, null, a, a.getText());
|
||||
checker.examineAction();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void examineAction() {
|
||||
ANTLRStringStream in = new ANTLRStringStream(action);
|
||||
in.setLine(node.getLine());
|
||||
in.setCharPositionInLine(node.getCharPositionInLine());
|
||||
ActionSplitter splitter = new ActionSplitter(in, this);
|
||||
splitter.getActionChunks(); // forces eval, fills extractor
|
||||
List<Token> chunks = splitter.getActionChunks(); // forces eval, fills extractor
|
||||
//System.out.println(chunks);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// LISTENER METHODS
|
||||
|
||||
public void setQualifiedAttr(Token x, Token y, Token expr) {
|
||||
System.out.println(x+"."+y+"="+expr);
|
||||
new AttributeChecks(g, r, alt, node, expr.getText()).examine();
|
||||
public void setQualifiedAttr(String expr, Token x, Token y, Token rhs) {
|
||||
if ( !node.space.resolves(x.getText(), y.getText(), node) ) {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE, // TODO; not right error
|
||||
g.fileName, x, x.getText(), expr);
|
||||
}
|
||||
new AttributeChecks(g, r, alt, node, rhs.getText()).examineAction();
|
||||
}
|
||||
|
||||
public void qualifiedAttr(Token x, Token y) {
|
||||
System.out.println(x+"."+y);
|
||||
AttributeScope s = r.resolveScope(x.getText(), alt);
|
||||
if ( s==null ) {
|
||||
System.err.println("not found: "+x);
|
||||
public void qualifiedAttr(String expr, Token x, Token y) {
|
||||
if ( !node.space.resolves(x.getText(), node) ) {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
return;
|
||||
}
|
||||
|
||||
// ???if y is not prop of x, we don't care; we'll ignore and leave as simple attr
|
||||
|
||||
if ( !node.space.resolves(x.getText(), y.getText(), node) ) {
|
||||
if ( node.space.resolveToRuleRef(x.getText(), node) ) {
|
||||
ErrorManager.grammarError(ErrorType.INVALID_RULE_PARAMETER_REF,
|
||||
g.fileName, y, y.getText(), expr);
|
||||
}
|
||||
else {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_ATTRIBUTE_IN_SCOPE,
|
||||
g.fileName, y, y.getText(), expr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setAttr(Token x, Token expr) {
|
||||
System.out.println(x+"="+expr);
|
||||
if ( !r.resolves(x.getText(), alt) ) System.err.println("not found: "+x);
|
||||
new AttributeChecks(g, r, alt, node, expr.getText()).examine();
|
||||
public void setAttr(String expr, Token x, Token rhs) {
|
||||
if ( !node.space.resolves(x.getText(), node) ) {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
}
|
||||
new AttributeChecks(g, r, alt, node, rhs.getText()).examineAction();
|
||||
}
|
||||
|
||||
public void attr(Token x) { // arg, retval, predefined, token ref, rule ref, current rule
|
||||
System.out.println(x);
|
||||
if ( !r.resolves(x.getText(), alt) ) System.err.println("not found: "+x);
|
||||
public void attr(String expr, Token x) { // arg, retval, predefined, token ref, rule ref, current rule
|
||||
// TODO: check for isolated rule ref "+x+" in "+expr);
|
||||
if ( node.space.resolveToRuleRef(x.getText(), node) ) {
|
||||
ErrorManager.grammarError(ErrorType.ISOLATED_RULE_SCOPE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
return;
|
||||
}
|
||||
if ( !node.space.resolves(x.getText(), node) ) {
|
||||
ErrorManager.grammarError(ErrorType.UNKNOWN_SIMPLE_ATTRIBUTE,
|
||||
g.fileName, x, x.getText(), expr);
|
||||
}
|
||||
}
|
||||
|
||||
public void setDynamicScopeAttr(Token x, Token y, Token expr) { }
|
||||
public void setDynamicScopeAttr(String expr, Token x, Token y, Token rhs) { }
|
||||
|
||||
public void dynamicScopeAttr(Token x, Token y) { }
|
||||
public void dynamicScopeAttr(String expr, Token x, Token y) {
|
||||
|
||||
}
|
||||
|
||||
public void setDynamicNegativeIndexedScopeAttr(Token x, Token y, Token index, Token expr) { }
|
||||
public void setDynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs) { }
|
||||
|
||||
public void dynamicNegativeIndexedScopeAttr(Token x, Token y, Token index) { }
|
||||
public void dynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index) { }
|
||||
|
||||
public void setDynamicAbsoluteIndexedScopeAttr(Token x, Token y, Token index, Token expr) { }
|
||||
public void setDynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs) { }
|
||||
|
||||
public void dynamicAbsoluteIndexedScopeAttr(Token x, Token y, Token index) { }
|
||||
public void dynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index) { }
|
||||
|
||||
public void unknownSyntax(String text) { }
|
||||
public void unknownSyntax(String text) {
|
||||
System.err.println("unknown: "+text);
|
||||
}
|
||||
|
||||
public void text(String text) { }
|
||||
|
||||
// don't care
|
||||
public void templateInstance() { }
|
||||
public void indirectTemplateInstance() { }
|
||||
public void setExprAttribute() { }
|
||||
public void setAttribute() { }
|
||||
public void templateExpr() { }
|
||||
public void templateInstance(String expr) { }
|
||||
public void indirectTemplateInstance(String expr) { }
|
||||
public void setExprAttribute(String expr) { }
|
||||
public void setAttribute(String expr) { }
|
||||
public void templateExpr(String expr) { }
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 BasicSemanticTriggers.g 2010-02-11 12:59:15
|
||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 BasicSemanticTriggers.g 2010-02-12 14:54:09
|
||||
|
||||
/*
|
||||
[The "BSD license"]
|
||||
|
@ -26,15 +26,14 @@
|
|||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.antlr.v4.semantics;
|
||||
import org.antlr.v4.tool.*;
|
||||
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.*;import java.util.Stack;
|
||||
import java.util.List;
|
||||
import org.antlr.runtime.tree.TreeNodeStream;
|
||||
import org.antlr.runtime.tree.TreeRuleReturnScope;
|
||||
import org.antlr.v4.tool.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
/** Triggers for the basic semantics of the input. Side-effects:
|
||||
* Set token, block, rule options in the tree. Load field option
|
||||
* with grammar options. Only legal options are set.
|
||||
|
|
|
@ -153,19 +153,36 @@ finishRule
|
|||
|
||||
rulelNamedAction
|
||||
: {inContext("RULE")}? ^(AT ID ACTION)
|
||||
{currentRule.namedActions.put($ID.text,$ACTION);}
|
||||
{
|
||||
currentRule.namedActions.put($ID.text,(ActionAST)$ACTION);
|
||||
((ActionAST)$ACTION).space = currentRule;
|
||||
}
|
||||
;
|
||||
|
||||
ruleAction
|
||||
: {inContext("RULE ...")}? ACTION {currentRule.alt[currentAlt].actions.add($ACTION);}
|
||||
: {inContext("RULE ...")&&!inContext("SCOPE")&&
|
||||
!inContext("CATCH")&&!inContext("FINALLY")}?
|
||||
ACTION
|
||||
{
|
||||
currentRule.alt[currentAlt].actions.add((ActionAST)$ACTION);
|
||||
((ActionAST)$ACTION).space = currentRule.alt[currentAlt];
|
||||
}
|
||||
;
|
||||
|
||||
exceptionHandler
|
||||
: ^(CATCH ARG_ACTION ACTION) {currentRule.exceptionActions.add($ACTION);}
|
||||
: ^(CATCH ARG_ACTION ACTION)
|
||||
{
|
||||
currentRule.exceptionActions.add((ActionAST)$ACTION);
|
||||
((ActionAST)$ACTION).space = currentRule;
|
||||
}
|
||||
;
|
||||
|
||||
finallyClause
|
||||
: ^(FINALLY ACTION) {currentRule.exceptionActions.add($ACTION);}
|
||||
: ^(FINALLY ACTION)
|
||||
{
|
||||
currentRule.exceptionActions.add((ActionAST)$ACTION);
|
||||
((ActionAST)$ACTION).space = currentRule;
|
||||
}
|
||||
;
|
||||
|
||||
ruleArg
|
||||
|
@ -205,8 +222,8 @@ rewriteElement
|
|||
labeledElement
|
||||
@after {
|
||||
LabelElementPair lp = new LabelElementPair(g, $id, $e, $start.getType());
|
||||
currentRule.labelDefs.map($id.text, lp);
|
||||
currentRule.alt[currentAlt].labelDefs.map($id.text, $id);
|
||||
//currentRule.labelDefs.map($id.text, lp);
|
||||
currentRule.alt[currentAlt].labelDefs.map($id.text, lp);
|
||||
}
|
||||
: {inContext("RULE ...")}?
|
||||
( ^(ASSIGN id=ID e=.)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 CollectSymbols.g 2010-02-11 12:59:15
|
||||
// $ANTLR 3.2.1-SNAPSHOT Jan 26, 2010 15:12:28 CollectSymbols.g 2010-02-12 14:54:08
|
||||
|
||||
/*
|
||||
[The "BSD license"]
|
||||
|
@ -26,19 +26,15 @@
|
|||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.antlr.v4.semantics;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.parse.*;
|
||||
import java.util.Set;
|
||||
import java.util.HashSet;
|
||||
import org.stringtemplate.v4.misc.MultiMap;
|
||||
|
||||
|
||||
import org.antlr.runtime.*;
|
||||
import org.antlr.runtime.tree.*;import java.util.Stack;
|
||||
import java.util.List;
|
||||
import org.antlr.runtime.tree.TreeNodeStream;
|
||||
import org.antlr.runtime.tree.TreeRuleReturnScope;
|
||||
import org.antlr.v4.parse.ScopeParser;
|
||||
import org.antlr.v4.tool.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
/** Collects rules, terminals, strings, actions, scopes etc... from AST
|
||||
* Side-effects: None
|
||||
*/
|
||||
|
@ -737,7 +733,10 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
match(input, Token.UP, null); if (state.failed) return ;
|
||||
if ( state.backtracking==1 ) {
|
||||
currentRule.namedActions.put((ID6!=null?ID6.getText():null),ACTION7);
|
||||
|
||||
currentRule.namedActions.put((ID6!=null?ID6.getText():null),(ActionAST)ACTION7);
|
||||
((ActionAST)ACTION7).space = currentRule;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -755,21 +754,25 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
|
||||
// $ANTLR start "ruleAction"
|
||||
// CollectSymbols.g:159:1: ruleAction : {...}? ACTION ;
|
||||
// CollectSymbols.g:162:1: ruleAction : {...}? ACTION ;
|
||||
public final void ruleAction() throws RecognitionException {
|
||||
GrammarAST ACTION8=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:160:2: ({...}? ACTION )
|
||||
// CollectSymbols.g:160:4: {...}? ACTION
|
||||
// CollectSymbols.g:163:2: ({...}? ACTION )
|
||||
// CollectSymbols.g:163:4: {...}? ACTION
|
||||
{
|
||||
if ( !((inContext("RULE ..."))) ) {
|
||||
if ( !((inContext("RULE ...")&&!inContext("SCOPE")&&
|
||||
!inContext("CATCH")&&!inContext("FINALLY"))) ) {
|
||||
if (state.backtracking>0) {state.failed=true; return ;}
|
||||
throw new FailedPredicateException(input, "ruleAction", "inContext(\"RULE ...\")");
|
||||
throw new FailedPredicateException(input, "ruleAction", "inContext(\"RULE ...\")&&!inContext(\"SCOPE\")&&\n\t\t !inContext(\"CATCH\")&&!inContext(\"FINALLY\")");
|
||||
}
|
||||
ACTION8=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_ruleAction430); if (state.failed) return ;
|
||||
ACTION8=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_ruleAction432); if (state.failed) return ;
|
||||
if ( state.backtracking==1 ) {
|
||||
currentRule.alt[currentAlt].actions.add(ACTION8);
|
||||
|
||||
currentRule.alt[currentAlt].actions.add((ActionAST)ACTION8);
|
||||
((ActionAST)ACTION8).space = currentRule.alt[currentAlt];
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -787,23 +790,26 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
|
||||
// $ANTLR start "exceptionHandler"
|
||||
// CollectSymbols.g:163:1: exceptionHandler : ^( CATCH ARG_ACTION ACTION ) ;
|
||||
// CollectSymbols.g:172:1: exceptionHandler : ^( CATCH ARG_ACTION ACTION ) ;
|
||||
public final void exceptionHandler() throws RecognitionException {
|
||||
GrammarAST ACTION9=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:164:2: ( ^( CATCH ARG_ACTION ACTION ) )
|
||||
// CollectSymbols.g:164:4: ^( CATCH ARG_ACTION ACTION )
|
||||
// CollectSymbols.g:173:2: ( ^( CATCH ARG_ACTION ACTION ) )
|
||||
// CollectSymbols.g:173:4: ^( CATCH ARG_ACTION ACTION )
|
||||
{
|
||||
match(input,CATCH,FOLLOW_CATCH_in_exceptionHandler444); if (state.failed) return ;
|
||||
match(input,CATCH,FOLLOW_CATCH_in_exceptionHandler448); if (state.failed) return ;
|
||||
|
||||
match(input, Token.DOWN, null); if (state.failed) return ;
|
||||
match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_exceptionHandler446); if (state.failed) return ;
|
||||
ACTION9=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_exceptionHandler448); if (state.failed) return ;
|
||||
match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_exceptionHandler450); if (state.failed) return ;
|
||||
ACTION9=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_exceptionHandler452); if (state.failed) return ;
|
||||
|
||||
match(input, Token.UP, null); if (state.failed) return ;
|
||||
if ( state.backtracking==1 ) {
|
||||
currentRule.exceptionActions.add(ACTION9);
|
||||
|
||||
currentRule.exceptionActions.add((ActionAST)ACTION9);
|
||||
((ActionAST)ACTION9).space = currentRule;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -821,22 +827,25 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
|
||||
// $ANTLR start "finallyClause"
|
||||
// CollectSymbols.g:167:1: finallyClause : ^( FINALLY ACTION ) ;
|
||||
// CollectSymbols.g:180:1: finallyClause : ^( FINALLY ACTION ) ;
|
||||
public final void finallyClause() throws RecognitionException {
|
||||
GrammarAST ACTION10=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:168:2: ( ^( FINALLY ACTION ) )
|
||||
// CollectSymbols.g:168:4: ^( FINALLY ACTION )
|
||||
// CollectSymbols.g:181:2: ( ^( FINALLY ACTION ) )
|
||||
// CollectSymbols.g:181:4: ^( FINALLY ACTION )
|
||||
{
|
||||
match(input,FINALLY,FOLLOW_FINALLY_in_finallyClause463); if (state.failed) return ;
|
||||
match(input,FINALLY,FOLLOW_FINALLY_in_finallyClause469); if (state.failed) return ;
|
||||
|
||||
match(input, Token.DOWN, null); if (state.failed) return ;
|
||||
ACTION10=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_finallyClause465); if (state.failed) return ;
|
||||
ACTION10=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_finallyClause471); if (state.failed) return ;
|
||||
|
||||
match(input, Token.UP, null); if (state.failed) return ;
|
||||
if ( state.backtracking==1 ) {
|
||||
currentRule.exceptionActions.add(ACTION10);
|
||||
|
||||
currentRule.exceptionActions.add((ActionAST)ACTION10);
|
||||
((ActionAST)ACTION10).space = currentRule;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -854,19 +863,19 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
|
||||
// $ANTLR start "ruleArg"
|
||||
// CollectSymbols.g:171:1: ruleArg : {...}? ARG_ACTION ;
|
||||
// CollectSymbols.g:188:1: ruleArg : {...}? ARG_ACTION ;
|
||||
public final void ruleArg() throws RecognitionException {
|
||||
GrammarAST ARG_ACTION11=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:172:2: ({...}? ARG_ACTION )
|
||||
// CollectSymbols.g:172:4: {...}? ARG_ACTION
|
||||
// CollectSymbols.g:189:2: ({...}? ARG_ACTION )
|
||||
// CollectSymbols.g:189:4: {...}? ARG_ACTION
|
||||
{
|
||||
if ( !((inContext("RULE"))) ) {
|
||||
if (state.backtracking>0) {state.failed=true; return ;}
|
||||
throw new FailedPredicateException(input, "ruleArg", "inContext(\"RULE\")");
|
||||
}
|
||||
ARG_ACTION11=(GrammarAST)match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleArg485); if (state.failed) return ;
|
||||
ARG_ACTION11=(GrammarAST)match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleArg491); if (state.failed) return ;
|
||||
if ( state.backtracking==1 ) {
|
||||
|
||||
currentRule.args = ScopeParser.parseTypeList((ARG_ACTION11!=null?ARG_ACTION11.getText():null));
|
||||
|
@ -889,18 +898,18 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
|
||||
// $ANTLR start "ruleReturns"
|
||||
// CollectSymbols.g:179:1: ruleReturns : ^( RETURNS ARG_ACTION ) ;
|
||||
// CollectSymbols.g:196:1: ruleReturns : ^( RETURNS ARG_ACTION ) ;
|
||||
public final void ruleReturns() throws RecognitionException {
|
||||
GrammarAST ARG_ACTION12=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:180:2: ( ^( RETURNS ARG_ACTION ) )
|
||||
// CollectSymbols.g:180:4: ^( RETURNS ARG_ACTION )
|
||||
// CollectSymbols.g:197:2: ( ^( RETURNS ARG_ACTION ) )
|
||||
// CollectSymbols.g:197:4: ^( RETURNS ARG_ACTION )
|
||||
{
|
||||
match(input,RETURNS,FOLLOW_RETURNS_in_ruleReturns502); if (state.failed) return ;
|
||||
match(input,RETURNS,FOLLOW_RETURNS_in_ruleReturns508); if (state.failed) return ;
|
||||
|
||||
match(input, Token.DOWN, null); if (state.failed) return ;
|
||||
ARG_ACTION12=(GrammarAST)match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleReturns504); if (state.failed) return ;
|
||||
ARG_ACTION12=(GrammarAST)match(input,ARG_ACTION,FOLLOW_ARG_ACTION_in_ruleReturns510); if (state.failed) return ;
|
||||
|
||||
match(input, Token.UP, null); if (state.failed) return ;
|
||||
if ( state.backtracking==1 ) {
|
||||
|
@ -925,21 +934,21 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
|
||||
// $ANTLR start "ruleScopeSpec"
|
||||
// CollectSymbols.g:187:1: ruleScopeSpec : {...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) ) ;
|
||||
// CollectSymbols.g:204:1: ruleScopeSpec : {...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) ) ;
|
||||
public final void ruleScopeSpec() throws RecognitionException {
|
||||
GrammarAST ACTION13=null;
|
||||
GrammarAST ids=null;
|
||||
List list_ids=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:188:2: ({...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) ) )
|
||||
// CollectSymbols.g:188:4: {...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) )
|
||||
// CollectSymbols.g:205:2: ({...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) ) )
|
||||
// CollectSymbols.g:205:4: {...}? ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) )
|
||||
{
|
||||
if ( !((inContext("RULE"))) ) {
|
||||
if (state.backtracking>0) {state.failed=true; return ;}
|
||||
throw new FailedPredicateException(input, "ruleScopeSpec", "inContext(\"RULE\")");
|
||||
}
|
||||
// CollectSymbols.g:189:3: ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) )
|
||||
// CollectSymbols.g:206:3: ( ^( SCOPE ACTION ) | ^( SCOPE (ids+= ID )+ ) )
|
||||
int alt6=2;
|
||||
int LA6_0 = input.LA(1);
|
||||
|
||||
|
@ -980,12 +989,12 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
}
|
||||
switch (alt6) {
|
||||
case 1 :
|
||||
// CollectSymbols.g:189:5: ^( SCOPE ACTION )
|
||||
// CollectSymbols.g:206:5: ^( SCOPE ACTION )
|
||||
{
|
||||
match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec527); if (state.failed) return ;
|
||||
match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec533); if (state.failed) return ;
|
||||
|
||||
match(input, Token.DOWN, null); if (state.failed) return ;
|
||||
ACTION13=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_ruleScopeSpec529); if (state.failed) return ;
|
||||
ACTION13=(GrammarAST)match(input,ACTION,FOLLOW_ACTION_in_ruleScopeSpec535); if (state.failed) return ;
|
||||
|
||||
match(input, Token.UP, null); if (state.failed) return ;
|
||||
if ( state.backtracking==1 ) {
|
||||
|
@ -998,12 +1007,12 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
}
|
||||
break;
|
||||
case 2 :
|
||||
// CollectSymbols.g:194:5: ^( SCOPE (ids+= ID )+ )
|
||||
// CollectSymbols.g:211:5: ^( SCOPE (ids+= ID )+ )
|
||||
{
|
||||
match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec542); if (state.failed) return ;
|
||||
match(input,SCOPE,FOLLOW_SCOPE_in_ruleScopeSpec548); if (state.failed) return ;
|
||||
|
||||
match(input, Token.DOWN, null); if (state.failed) return ;
|
||||
// CollectSymbols.g:194:16: (ids+= ID )+
|
||||
// CollectSymbols.g:211:16: (ids+= ID )+
|
||||
int cnt5=0;
|
||||
loop5:
|
||||
do {
|
||||
|
@ -1017,9 +1026,9 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
switch (alt5) {
|
||||
case 1 :
|
||||
// CollectSymbols.g:194:16: ids+= ID
|
||||
// CollectSymbols.g:211:16: ids+= ID
|
||||
{
|
||||
ids=(GrammarAST)match(input,ID,FOLLOW_ID_in_ruleScopeSpec546); if (state.failed) return ;
|
||||
ids=(GrammarAST)match(input,ID,FOLLOW_ID_in_ruleScopeSpec552); if (state.failed) return ;
|
||||
if (list_ids==null) list_ids=new ArrayList();
|
||||
list_ids.add(ids);
|
||||
|
||||
|
@ -1066,14 +1075,14 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
};
|
||||
|
||||
// $ANTLR start "rewriteElement"
|
||||
// CollectSymbols.g:198:1: rewriteElement : {...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL ) ;
|
||||
// CollectSymbols.g:215:1: rewriteElement : {...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL ) ;
|
||||
public final CollectSymbols.rewriteElement_return rewriteElement() throws RecognitionException {
|
||||
CollectSymbols.rewriteElement_return retval = new CollectSymbols.rewriteElement_return();
|
||||
retval.start = input.LT(1);
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:200:2: ({...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL ) )
|
||||
// CollectSymbols.g:201:6: {...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL )
|
||||
// CollectSymbols.g:217:2: ({...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL ) )
|
||||
// CollectSymbols.g:218:6: {...}? ( TOKEN_REF | RULE_REF | STRING_LITERAL | LABEL )
|
||||
{
|
||||
if ( !((inContext("RESULT ..."))) ) {
|
||||
if (state.backtracking>0) {state.failed=true; return retval;}
|
||||
|
@ -1110,7 +1119,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
};
|
||||
|
||||
// $ANTLR start "labeledElement"
|
||||
// CollectSymbols.g:205:1: labeledElement : {...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) ) ;
|
||||
// CollectSymbols.g:222:1: labeledElement : {...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) ) ;
|
||||
public final CollectSymbols.labeledElement_return labeledElement() throws RecognitionException {
|
||||
CollectSymbols.labeledElement_return retval = new CollectSymbols.labeledElement_return();
|
||||
retval.start = input.LT(1);
|
||||
|
@ -1119,14 +1128,14 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
GrammarAST e=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:211:2: ({...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) ) )
|
||||
// CollectSymbols.g:211:4: {...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
|
||||
// CollectSymbols.g:228:2: ({...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) ) )
|
||||
// CollectSymbols.g:228:4: {...}? ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
|
||||
{
|
||||
if ( !((inContext("RULE ..."))) ) {
|
||||
if (state.backtracking>0) {state.failed=true; return retval;}
|
||||
throw new FailedPredicateException(input, "labeledElement", "inContext(\"RULE ...\")");
|
||||
}
|
||||
// CollectSymbols.g:212:3: ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
|
||||
// CollectSymbols.g:229:3: ( ^( ASSIGN id= ID e= . ) | ^( PLUS_ASSIGN id= ID e= . ) )
|
||||
int alt7=2;
|
||||
int LA7_0 = input.LA(1);
|
||||
|
||||
|
@ -1145,12 +1154,12 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
}
|
||||
switch (alt7) {
|
||||
case 1 :
|
||||
// CollectSymbols.g:212:5: ^( ASSIGN id= ID e= . )
|
||||
// CollectSymbols.g:229:5: ^( ASSIGN id= ID e= . )
|
||||
{
|
||||
match(input,ASSIGN,FOLLOW_ASSIGN_in_labeledElement610); if (state.failed) return retval;
|
||||
match(input,ASSIGN,FOLLOW_ASSIGN_in_labeledElement616); if (state.failed) return retval;
|
||||
|
||||
match(input, Token.DOWN, null); if (state.failed) return retval;
|
||||
id=(GrammarAST)match(input,ID,FOLLOW_ID_in_labeledElement614); if (state.failed) return retval;
|
||||
id=(GrammarAST)match(input,ID,FOLLOW_ID_in_labeledElement620); if (state.failed) return retval;
|
||||
e=(GrammarAST)input.LT(1);
|
||||
matchAny(input); if (state.failed) return retval;
|
||||
|
||||
|
@ -1159,12 +1168,12 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
}
|
||||
break;
|
||||
case 2 :
|
||||
// CollectSymbols.g:213:5: ^( PLUS_ASSIGN id= ID e= . )
|
||||
// CollectSymbols.g:230:5: ^( PLUS_ASSIGN id= ID e= . )
|
||||
{
|
||||
match(input,PLUS_ASSIGN,FOLLOW_PLUS_ASSIGN_in_labeledElement626); if (state.failed) return retval;
|
||||
match(input,PLUS_ASSIGN,FOLLOW_PLUS_ASSIGN_in_labeledElement632); if (state.failed) return retval;
|
||||
|
||||
match(input, Token.DOWN, null); if (state.failed) return retval;
|
||||
id=(GrammarAST)match(input,ID,FOLLOW_ID_in_labeledElement630); if (state.failed) return retval;
|
||||
id=(GrammarAST)match(input,ID,FOLLOW_ID_in_labeledElement636); if (state.failed) return retval;
|
||||
e=(GrammarAST)input.LT(1);
|
||||
matchAny(input); if (state.failed) return retval;
|
||||
|
||||
|
@ -1181,8 +1190,8 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
if ( state.backtracking==1 ) {
|
||||
|
||||
LabelElementPair lp = new LabelElementPair(g, id, e, ((GrammarAST)retval.start).getType());
|
||||
currentRule.labelDefs.map((id!=null?id.getText():null), lp);
|
||||
currentRule.alt[currentAlt].labelDefs.map((id!=null?id.getText():null), id);
|
||||
//currentRule.labelDefs.map((id!=null?id.getText():null), lp);
|
||||
currentRule.alt[currentAlt].labelDefs.map((id!=null?id.getText():null), lp);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1200,7 +1209,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
};
|
||||
|
||||
// $ANTLR start "terminal"
|
||||
// CollectSymbols.g:217:1: terminal : ({...}? STRING_LITERAL | TOKEN_REF );
|
||||
// CollectSymbols.g:234:1: terminal : ({...}? STRING_LITERAL | TOKEN_REF );
|
||||
public final CollectSymbols.terminal_return terminal() throws RecognitionException {
|
||||
CollectSymbols.terminal_return retval = new CollectSymbols.terminal_return();
|
||||
retval.start = input.LT(1);
|
||||
|
@ -1209,7 +1218,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
GrammarAST TOKEN_REF15=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:218:5: ({...}? STRING_LITERAL | TOKEN_REF )
|
||||
// CollectSymbols.g:235:5: ({...}? STRING_LITERAL | TOKEN_REF )
|
||||
int alt8=2;
|
||||
int LA8_0 = input.LA(1);
|
||||
|
||||
|
@ -1228,13 +1237,13 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
}
|
||||
switch (alt8) {
|
||||
case 1 :
|
||||
// CollectSymbols.g:218:7: {...}? STRING_LITERAL
|
||||
// CollectSymbols.g:235:7: {...}? STRING_LITERAL
|
||||
{
|
||||
if ( !((!inContext("TOKENS ASSIGN"))) ) {
|
||||
if (state.backtracking>0) {state.failed=true; return retval;}
|
||||
throw new FailedPredicateException(input, "terminal", "!inContext(\"TOKENS ASSIGN\")");
|
||||
}
|
||||
STRING_LITERAL14=(GrammarAST)match(input,STRING_LITERAL,FOLLOW_STRING_LITERAL_in_terminal656); if (state.failed) return retval;
|
||||
STRING_LITERAL14=(GrammarAST)match(input,STRING_LITERAL,FOLLOW_STRING_LITERAL_in_terminal662); if (state.failed) return retval;
|
||||
if ( state.backtracking==1 ) {
|
||||
|
||||
terminals.add(((GrammarAST)retval.start));
|
||||
|
@ -1248,9 +1257,9 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
}
|
||||
break;
|
||||
case 2 :
|
||||
// CollectSymbols.g:226:7: TOKEN_REF
|
||||
// CollectSymbols.g:243:7: TOKEN_REF
|
||||
{
|
||||
TOKEN_REF15=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal671); if (state.failed) return retval;
|
||||
TOKEN_REF15=(GrammarAST)match(input,TOKEN_REF,FOLLOW_TOKEN_REF_in_terminal677); if (state.failed) return retval;
|
||||
if ( state.backtracking==1 ) {
|
||||
|
||||
terminals.add(TOKEN_REF15);
|
||||
|
@ -1278,15 +1287,15 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
|
||||
|
||||
// $ANTLR start "ruleref"
|
||||
// CollectSymbols.g:236:1: ruleref : RULE_REF ;
|
||||
// CollectSymbols.g:253:1: ruleref : RULE_REF ;
|
||||
public final void ruleref() throws RecognitionException {
|
||||
GrammarAST RULE_REF16=null;
|
||||
|
||||
try {
|
||||
// CollectSymbols.g:238:5: ( RULE_REF )
|
||||
// CollectSymbols.g:238:7: RULE_REF
|
||||
// CollectSymbols.g:255:5: ( RULE_REF )
|
||||
// CollectSymbols.g:255:7: RULE_REF
|
||||
{
|
||||
RULE_REF16=(GrammarAST)match(input,RULE_REF,FOLLOW_RULE_REF_in_ruleref696); if (state.failed) return ;
|
||||
RULE_REF16=(GrammarAST)match(input,RULE_REF,FOLLOW_RULE_REF_in_ruleref702); if (state.failed) return ;
|
||||
if ( state.backtracking==1 ) {
|
||||
|
||||
rulerefs.add(RULE_REF16);
|
||||
|
@ -1501,26 +1510,26 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
|
|||
public static final BitSet FOLLOW_AT_in_rulelNamedAction408 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ID_in_rulelNamedAction410 = new BitSet(new long[]{0x0000000000010000L});
|
||||
public static final BitSet FOLLOW_ACTION_in_rulelNamedAction412 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_ACTION_in_ruleAction430 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_CATCH_in_exceptionHandler444 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ARG_ACTION_in_exceptionHandler446 = new BitSet(new long[]{0x0000000000010000L});
|
||||
public static final BitSet FOLLOW_ACTION_in_exceptionHandler448 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_FINALLY_in_finallyClause463 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ACTION_in_finallyClause465 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_ARG_ACTION_in_ruleArg485 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_RETURNS_in_ruleReturns502 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ARG_ACTION_in_ruleReturns504 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_SCOPE_in_ruleScopeSpec527 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ACTION_in_ruleScopeSpec529 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_SCOPE_in_ruleScopeSpec542 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ID_in_ruleScopeSpec546 = new BitSet(new long[]{0x0000000000000008L,0x0000000000800000L});
|
||||
public static final BitSet FOLLOW_set_in_rewriteElement574 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_ASSIGN_in_labeledElement610 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ID_in_labeledElement614 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});
|
||||
public static final BitSet FOLLOW_PLUS_ASSIGN_in_labeledElement626 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ID_in_labeledElement630 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});
|
||||
public static final BitSet FOLLOW_STRING_LITERAL_in_terminal656 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_TOKEN_REF_in_terminal671 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_RULE_REF_in_ruleref696 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_ACTION_in_ruleAction432 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_CATCH_in_exceptionHandler448 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ARG_ACTION_in_exceptionHandler450 = new BitSet(new long[]{0x0000000000010000L});
|
||||
public static final BitSet FOLLOW_ACTION_in_exceptionHandler452 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_FINALLY_in_finallyClause469 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ACTION_in_finallyClause471 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_ARG_ACTION_in_ruleArg491 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_RETURNS_in_ruleReturns508 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ARG_ACTION_in_ruleReturns510 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_SCOPE_in_ruleScopeSpec533 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ACTION_in_ruleScopeSpec535 = new BitSet(new long[]{0x0000000000000008L});
|
||||
public static final BitSet FOLLOW_SCOPE_in_ruleScopeSpec548 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ID_in_ruleScopeSpec552 = new BitSet(new long[]{0x0000000000000008L,0x0000000000800000L});
|
||||
public static final BitSet FOLLOW_set_in_rewriteElement580 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_ASSIGN_in_labeledElement616 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ID_in_labeledElement620 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});
|
||||
public static final BitSet FOLLOW_PLUS_ASSIGN_in_labeledElement632 = new BitSet(new long[]{0x0000000000000004L});
|
||||
public static final BitSet FOLLOW_ID_in_labeledElement636 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});
|
||||
public static final BitSet FOLLOW_STRING_LITERAL_in_terminal662 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_TOKEN_REF_in_terminal677 = new BitSet(new long[]{0x0000000000000002L});
|
||||
public static final BitSet FOLLOW_RULE_REF_in_ruleref702 = new BitSet(new long[]{0x0000000000000002L});
|
||||
|
||||
}
|
|
@ -4,7 +4,9 @@ import org.antlr.runtime.RecognitionException;
|
|||
import org.antlr.runtime.tree.BufferedTreeNodeStream;
|
||||
import org.antlr.v4.parse.ASTVerifier;
|
||||
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||
import org.antlr.v4.tool.*;
|
||||
import org.antlr.v4.tool.ErrorManager;
|
||||
import org.antlr.v4.tool.Grammar;
|
||||
import org.antlr.v4.tool.Rule;
|
||||
|
||||
/** */
|
||||
public class SemanticPipeline {
|
||||
|
@ -45,28 +47,14 @@ public class SemanticPipeline {
|
|||
|
||||
// CHECK FOR SYMBOL COLLISIONS
|
||||
SymbolChecks symcheck = new SymbolChecks(g, collector);
|
||||
symcheck.examine();
|
||||
symcheck.examine(); // side-effect: strip away redef'd rules.
|
||||
|
||||
// STORE RULES IN GRAMMAR
|
||||
for (Rule r : collector.rules) g.defineRule(r);
|
||||
|
||||
// CHECK ATTRIBUTE EXPRESSIONS FOR SEMANTIC VALIDITY
|
||||
checkAttributeExpressions(g, collector);
|
||||
AttributeChecks.checkAllAttributeExpressions(g, collector.rules);
|
||||
|
||||
// ASSIGN TOKEN TYPES
|
||||
}
|
||||
|
||||
public void checkAttributeExpressions(Grammar g, CollectSymbols collector) {
|
||||
for (Rule r : collector.rules) {
|
||||
for (GrammarAST a : r.namedActions.values()) {
|
||||
AttributeChecks checker = new AttributeChecks(g, r, null, a, a.getText());
|
||||
checker.examine();
|
||||
}
|
||||
for (int i=1; i<=r.numberOfAlts; i++) {
|
||||
Alternative alt = r.alt[i];
|
||||
for (GrammarAST a : alt.actions) {
|
||||
AttributeChecks checker =
|
||||
new AttributeChecks(g, r, alt, a, a.getText());
|
||||
checker.examine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import java.util.*;
|
|||
/** Check for symbol problems; no side-effects. Inefficient to walk rules
|
||||
* and such multiple times, but I like isolating all error checking outside
|
||||
* of code that actually defines symbols etc...
|
||||
*
|
||||
* Side-effect: strip away redef'd rules.
|
||||
*/
|
||||
public class SymbolChecks {
|
||||
protected Grammar g;
|
||||
|
@ -48,6 +50,8 @@ public class SymbolChecks {
|
|||
|
||||
public void checkForRuleConflicts(List<Rule> rules) {
|
||||
if ( rules==null ) return;
|
||||
int i = 0;
|
||||
List<Integer> toRemove = new ArrayList<Integer>();
|
||||
for (Rule r : collector.rules) {
|
||||
if ( nameToRuleMap.get(r.name)==null ) {
|
||||
nameToRuleMap.put(r.name, r);
|
||||
|
@ -56,13 +60,16 @@ public class SymbolChecks {
|
|||
GrammarAST idNode = (GrammarAST)r.ast.getChild(0);
|
||||
ErrorManager.grammarError(ErrorType.RULE_REDEFINITION,
|
||||
g.fileName, idNode.token, r.name);
|
||||
toRemove.add(i);
|
||||
}
|
||||
if ( globalScopeNames.contains(r.name) ) {
|
||||
GrammarAST idNode = (GrammarAST)r.ast.getChild(0);
|
||||
ErrorManager.grammarError(ErrorType.SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE,
|
||||
g.fileName, idNode.token, r.name);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
collector.rules.removeAll(toRemove);
|
||||
}
|
||||
|
||||
public void checkScopeRedefinitions(List<GrammarAST> scopes) {
|
||||
|
@ -178,13 +185,16 @@ public class SymbolChecks {
|
|||
checkForRuleScopeAttributeConflict(r);
|
||||
Map<String, LabelElementPair> labelNameSpace =
|
||||
new HashMap<String, LabelElementPair>();
|
||||
for (List<LabelElementPair> pairs : r.labelDefs.values() ) {
|
||||
for (LabelElementPair p : pairs) {
|
||||
checkForLabelConflict(r, p.label);
|
||||
String name = p.label.getText();
|
||||
LabelElementPair prev = labelNameSpace.get(name);
|
||||
if ( prev==null ) labelNameSpace.put(name, p);
|
||||
else checkForTypeMismatch(prev, p);
|
||||
for (int i=1; i<=r.numberOfAlts; i++) {
|
||||
Alternative a = r.alt[i];
|
||||
for (List<LabelElementPair> pairs : a.labelDefs.values() ) {
|
||||
for (LabelElementPair p : pairs) {
|
||||
checkForLabelConflict(r, p.label);
|
||||
String name = p.label.getText();
|
||||
LabelElementPair prev = labelNameSpace.get(name);
|
||||
if ( prev==null ) labelNameSpace.put(name, p);
|
||||
else checkForTypeMismatch(prev, p);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
package org.antlr.v4.tool;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
|
||||
public class ActionAST extends GrammarAST {
|
||||
// Alt, rule, grammar space
|
||||
public SymbolSpace space;
|
||||
public ActionAST(Token t) { super(t); }
|
||||
public ActionAST(int type) { super(type); }
|
||||
public ActionAST(int type, Token t) { super(type, t); }
|
||||
}
|
|
@ -9,7 +9,9 @@ import java.util.List;
|
|||
/** Record use/def information about an outermost alternative in a subrule
|
||||
* or rule of a grammar.
|
||||
*/
|
||||
public class Alternative {
|
||||
public class Alternative implements SymbolSpace {
|
||||
Rule rule;
|
||||
|
||||
// token IDs, string literals in this alt
|
||||
public MultiMap<String, GrammarAST> tokenRefs = new MultiMap<String, GrammarAST>();
|
||||
|
||||
|
@ -17,7 +19,7 @@ public class Alternative {
|
|||
public MultiMap<String, GrammarAST> ruleRefs = new MultiMap<String, GrammarAST>();
|
||||
|
||||
/** A list of all LabelElementPair attached to tokens like id=ID, ids+=ID */
|
||||
public MultiMap<String, GrammarAST> labelDefs = new MultiMap<String, GrammarAST>();
|
||||
public MultiMap<String, LabelElementPair> labelDefs = new MultiMap<String, LabelElementPair>();
|
||||
|
||||
// track all token, rule, label refs in rewrite (right of ->)
|
||||
public List<GrammarAST> rewriteElements = new ArrayList<GrammarAST>();
|
||||
|
@ -27,8 +29,53 @@ public class Alternative {
|
|||
* We need to examine these actions before code generation so
|
||||
* that we can detect refs to $rule.attr etc...
|
||||
*/
|
||||
public List<GrammarAST> actions = new ArrayList<GrammarAST>();
|
||||
public List<ActionAST> actions = new ArrayList<ActionAST>();
|
||||
|
||||
public Alternative() {
|
||||
public Alternative(Rule r) { this.rule = r; }
|
||||
|
||||
public SymbolSpace getParent() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Is isolated x a token/rule/label ref? */
|
||||
public boolean resolves(String x, ActionAST node) {
|
||||
boolean inAlt =
|
||||
tokenRefs.get(x)!=null||
|
||||
ruleRefs.get(x)!=null ||
|
||||
labelDefs.get(x)!=null;
|
||||
if ( inAlt ) return inAlt;
|
||||
return rule.resolves(x, node);
|
||||
}
|
||||
|
||||
/** Find x as token/rule/label ref then find y in properties list. */
|
||||
public boolean resolves(String x, String y, ActionAST node) {
|
||||
if ( tokenRefs.get(x)!=null ) { // token ref in this alt?
|
||||
return rule.getPredefinedScope(LabelType.TOKEN_LABEL).get(y)!=null;
|
||||
}
|
||||
if ( ruleRefs.get(x)!=null ) { // rule ref in this alt?
|
||||
// look up rule, ask it to resolve y (must be retval or predefined)
|
||||
return rule.g.getRule(x).resolvesAsRetvalOrProperty(y);
|
||||
}
|
||||
List<LabelElementPair> labels = labelDefs.get(x); // label?
|
||||
if ( labels!=null ) {
|
||||
// it's a label ref, compute scope from label type and grammar type
|
||||
LabelElementPair anyLabelDef = labels.get(0);
|
||||
if ( rule.getPredefinedScope(anyLabelDef.type).get(y)!=null) return true;
|
||||
if ( anyLabelDef.type==LabelType.RULE_LABEL ) {
|
||||
Rule ref = rule.g.getRule(anyLabelDef.element.getText());
|
||||
return ref.resolvesAsRetvalOrProperty(y);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean resolveToRuleRef(String x, ActionAST node) {
|
||||
if ( ruleRefs.get(x)!=null ) return true;
|
||||
List<LabelElementPair> labels = labelDefs.get(x);
|
||||
if ( labels!=null ) { // it's a label ref. is it a rule label?
|
||||
LabelElementPair anyLabelDef = labels.get(0);
|
||||
if ( anyLabelDef.type==LabelType.RULE_LABEL ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,6 +79,7 @@ public enum ErrorType {
|
|||
UNKNOWN_SIMPLE_ATTRIBUTE(ErrorSeverity.ERROR, true, true),
|
||||
INVALID_RULE_PARAMETER_REF(ErrorSeverity.ERROR, true, true),
|
||||
UNKNOWN_RULE_ATTRIBUTE(ErrorSeverity.ERROR, true, true),
|
||||
UNKNOWN_ATTRIBUTE_IN_SCOPE(ErrorSeverity.ERROR, true, true),
|
||||
ISOLATED_RULE_SCOPE(ErrorSeverity.ERROR, true, true),
|
||||
SYMBOL_CONFLICTS_WITH_GLOBAL_SCOPE(ErrorSeverity.ERROR, true, true),
|
||||
LABEL_CONFLICTS_WITH_RULE(ErrorSeverity.ERROR, true, true),
|
||||
|
|
|
@ -8,11 +8,10 @@ import org.antlr.v4.Tool;
|
|||
import org.antlr.v4.parse.ANTLRLexer;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.antlr.v4.parse.GrammarASTAdaptor;
|
||||
import org.stringtemplate.v4.misc.MultiMap;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
public class Grammar {
|
||||
public class Grammar implements SymbolSpace {
|
||||
public static final Set doNotCopyOptionsToLexer =
|
||||
new HashSet() {
|
||||
{
|
||||
|
@ -46,8 +45,8 @@ public class Grammar {
|
|||
|
||||
/** If we're imported, who imported us? If null, implies grammar is root */
|
||||
public Grammar parent;
|
||||
protected List<Grammar> importedGrammars;
|
||||
protected Map<String, Rule> rules = new LinkedHashMap<String, Rule>();
|
||||
public List<Grammar> importedGrammars;
|
||||
public Map<String, Rule> rules = new LinkedHashMap<String, Rule>();
|
||||
|
||||
/** Map a scope to a map of name:action pairs.
|
||||
* The code generator will use this to fill holes in the output files.
|
||||
|
@ -122,7 +121,7 @@ public class Grammar {
|
|||
}
|
||||
|
||||
public void defineRule(Rule r) { rules.put(r.name, r); }
|
||||
|
||||
|
||||
public Rule getRule(String name) { return rules.get(name); }
|
||||
|
||||
/** Get list of all delegates from all grammars in the delegate subtree of g.
|
||||
|
@ -211,6 +210,20 @@ public class Grammar {
|
|||
return null;
|
||||
}
|
||||
|
||||
public SymbolSpace getParent() { return null; }
|
||||
|
||||
public boolean resolves(String x, ActionAST node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean resolves(String x, String y, ActionAST node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean resolveToRuleRef(String x, ActionAST node) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Given a grammar type, what should be the default action scope?
|
||||
* If I say @members in a COMBINED grammar, for example, the
|
||||
* default scope should be "parser".
|
||||
|
|
|
@ -1,15 +1,11 @@
|
|||
package org.antlr.v4.tool;
|
||||
|
||||
import org.antlr.runtime.Token;
|
||||
import org.antlr.v4.parse.ANTLRParser;
|
||||
import org.stringtemplate.v4.misc.MultiMap;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public class Rule {
|
||||
public class Rule implements SymbolSpace {
|
||||
/** Rule refs have a predefined set of attributes as well as
|
||||
* the return values and args.
|
||||
*/
|
||||
|
@ -57,20 +53,20 @@ public class Rule {
|
|||
* I track the AST node for the action in case I need the line number
|
||||
* for errors.
|
||||
*/
|
||||
public Map<String, GrammarAST> namedActions =
|
||||
new HashMap<String, GrammarAST>();
|
||||
public Map<String, ActionAST> namedActions =
|
||||
new HashMap<String, ActionAST>();
|
||||
|
||||
/** Track exception handlers, finally action */
|
||||
public List<GrammarAST> exceptionActions = new ArrayList<GrammarAST>();
|
||||
public List<ActionAST> exceptionActions = new ArrayList<ActionAST>();
|
||||
|
||||
public int numberOfAlts;
|
||||
|
||||
/** Labels are visible to all alts in a rule. Record all defs here.
|
||||
* We need to ensure labels are used to track same kind of symbols.
|
||||
* Tracks all label defs for a label.
|
||||
*/
|
||||
public MultiMap<String, LabelElementPair> labelDefs =
|
||||
new MultiMap<String, LabelElementPair>();
|
||||
*/
|
||||
|
||||
public Alternative[] alt;
|
||||
|
||||
|
@ -80,61 +76,151 @@ public class Rule {
|
|||
this.ast = ast;
|
||||
this.numberOfAlts = numberOfAlts;
|
||||
alt = new Alternative[numberOfAlts+1]; // 1..n
|
||||
for (int i=1; i<=numberOfAlts; i++) alt[i] = new Alternative();
|
||||
for (int i=1; i<=numberOfAlts; i++) alt[i] = new Alternative(this);
|
||||
}
|
||||
|
||||
public boolean resolves(String name, Alternative alt) {
|
||||
Attribute a = resolve(name);
|
||||
if ( a!=null ) return true; // ok
|
||||
if ( alt.tokenRefs.get(name)!=null||
|
||||
alt.ruleRefs.get(name)!=null ||
|
||||
alt.labelDefs.get(name)!=null )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
public SymbolSpace getParent() { return g; }
|
||||
|
||||
/** Is isolated x an arg, retval, predefined prop? */
|
||||
public boolean resolves(String x, ActionAST node) {
|
||||
if ( resolvesAsRetvalOrProperty(x) ) return true;
|
||||
if ( args.get(x)!=null ) return true;
|
||||
// resolve outside of an alt?
|
||||
if ( node.space instanceof Alternative ) return getParent().resolves(x, node);
|
||||
return getLabelNames().contains(x); // can see all labels if not in alt
|
||||
}
|
||||
|
||||
/** Look up name from context of this rule and an alternative.
|
||||
* Find an arg, retval, predefined property, or label/rule/token ref.
|
||||
|
||||
/** For $x.y, is x an arg, retval, predefined prop, token/rule/label ref?
|
||||
* If so, make sure y resolves within that perspective.
|
||||
*/
|
||||
public Attribute resolve(String name) {
|
||||
Attribute a = args.get(name); if ( a!=null ) return a;
|
||||
a = retvals.get(name); if ( a!=null ) return a;
|
||||
String grammarLabelKey = g.getTypeString() + ":" + LabelType.RULE_LABEL;
|
||||
AttributeScope properties =
|
||||
Grammar.grammarAndLabelRefTypeToScope.get(grammarLabelKey);
|
||||
a = properties.get(name);
|
||||
if ( a!=null ) return a;
|
||||
|
||||
//alt[currentAlt].tokenRefs
|
||||
// not here? look in grammar for global scope
|
||||
return null;
|
||||
}
|
||||
|
||||
public AttributeScope resolveScope(String name, Alternative alt) {
|
||||
AttributeScope s = args; if ( s.get(name)!=null ) return s;
|
||||
s = retvals; if ( s.get(name)!=null ) return s;
|
||||
s = retvals; if ( s.get(name)!=null ) return s;
|
||||
String grammarLabelKey = g.getTypeString() + ":" + LabelType.RULE_LABEL;
|
||||
s = Grammar.grammarAndLabelRefTypeToScope.get(grammarLabelKey);
|
||||
if ( s.get(name)!=null ) return s;
|
||||
if ( alt.tokenRefs.get(name)!=null ) {
|
||||
grammarLabelKey = g.getTypeString() + ":" + LabelType.TOKEN_LABEL;
|
||||
return Grammar.grammarAndLabelRefTypeToScope.get(grammarLabelKey);
|
||||
public boolean resolves(String x, String y, ActionAST node) {
|
||||
if ( x.equals(this.name) ) { // $x.y ref in rule x is same as $y
|
||||
return resolves(y, node);
|
||||
}
|
||||
if ( alt.ruleRefs.get(name)!=null ) {
|
||||
grammarLabelKey = g.getTypeString() + ":" + LabelType.RULE_LABEL;
|
||||
return Grammar.grammarAndLabelRefTypeToScope.get(grammarLabelKey);
|
||||
|
||||
MultiMap<String, LabelElementPair> labelDefs = null;
|
||||
if ( node.space instanceof Alternative) {
|
||||
labelDefs = ((Alternative)node.space).labelDefs;
|
||||
}
|
||||
List<LabelElementPair> labels = labelDefs.get(name);
|
||||
else labelDefs = getLabelDefs();
|
||||
|
||||
List<LabelElementPair> labels = labelDefs.get(x); // label?
|
||||
if ( labels!=null ) {
|
||||
// it's a label ref, compute scope from label type and grammar type
|
||||
LabelElementPair anyLabelDef = labels.get(0);
|
||||
grammarLabelKey = g.getTypeString() + ":" + anyLabelDef.type;
|
||||
return Grammar.grammarAndLabelRefTypeToScope.get(grammarLabelKey);
|
||||
// predefined?
|
||||
if ( getPredefinedScope(anyLabelDef.type).get(y)!=null) return true;
|
||||
if ( anyLabelDef.type==LabelType.RULE_LABEL ) {
|
||||
Rule ref = g.getRule(anyLabelDef.element.getText());
|
||||
return ref.resolvesAsRetvalOrProperty(y);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean resolveToRuleRef(String x, ActionAST node) {
|
||||
if ( x.equals(this.name) ) return true;
|
||||
MultiMap<String, LabelElementPair> labelDefs = null;
|
||||
if ( node.space instanceof Alternative) {
|
||||
labelDefs = ((Alternative)node.space).labelDefs;
|
||||
}
|
||||
else labelDefs = getLabelDefs();
|
||||
List<LabelElementPair> labels = labelDefs.get(x);
|
||||
if ( labels!=null ) { // it's a label ref. is it a rule label?
|
||||
LabelElementPair anyLabelDef = labels.get(0);
|
||||
if ( anyLabelDef.type==LabelType.RULE_LABEL ) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean resolvesAsRetvalOrProperty(String y) {
|
||||
if ( retvals.get(y)!=null ) return true;
|
||||
AttributeScope s = getPredefinedScope(LabelType.RULE_LABEL);
|
||||
return s.get(y)!=null;
|
||||
}
|
||||
|
||||
public Set<String> getRuleRefs() {
|
||||
Set<String> refs = new HashSet<String>();
|
||||
for (Alternative a : alt) refs.addAll(a.ruleRefs.keySet());
|
||||
return refs;
|
||||
}
|
||||
|
||||
public Set<String> getLabelNames() {
|
||||
Set<String> refs = new HashSet<String>();
|
||||
for (int i=1; i<=numberOfAlts; i++) {
|
||||
refs.addAll(alt[i].labelDefs.keySet());
|
||||
}
|
||||
return refs;
|
||||
}
|
||||
|
||||
public MultiMap<String, LabelElementPair> getLabelDefs() {
|
||||
MultiMap<String, LabelElementPair> defs =
|
||||
new MultiMap<String, LabelElementPair>();
|
||||
for (int i=1; i<=numberOfAlts; i++) {
|
||||
for (List<LabelElementPair> pairs : alt[i].labelDefs.values()) {
|
||||
for (LabelElementPair p : pairs) {
|
||||
defs.map(p.label.getText(), p);
|
||||
}
|
||||
}
|
||||
}
|
||||
return defs;
|
||||
}
|
||||
|
||||
/** Look up name from context of this rule and an alternative.
|
||||
* Find an arg, retval, predefined property, or label/rule/token ref.
|
||||
*/
|
||||
// public Attribute resolve(String name) {
|
||||
// Attribute a = args.get(name); if ( a!=null ) return a;
|
||||
// a = retvals.get(name); if ( a!=null ) return a;
|
||||
// AttributeScope properties = getPredefinedScope(LabelType.RULE_LABEL);
|
||||
// a = properties.get(name);
|
||||
// if ( a!=null ) return a;
|
||||
//
|
||||
// //alt[currentAlt].tokenRefs
|
||||
// // not here? look in grammar for global scope
|
||||
// return null;
|
||||
// }
|
||||
|
||||
/** Resolve x in $x.y to
|
||||
*/
|
||||
// public AttributeScope resolveScope(String name, Alternative alt) {
|
||||
// AttributeScope s = null;
|
||||
// if ( this.name.equals(name) ) { // $r ref in rule r
|
||||
// s = resolveLocalAttributeScope(name);
|
||||
// if ( s!=null ) return s;
|
||||
// }
|
||||
//
|
||||
// if ( alt.tokenRefs.get(name)!=null ) { // token ref in this alt?
|
||||
// return getPredefinedScope(LabelType.TOKEN_LABEL);
|
||||
// }
|
||||
// if ( alt.ruleRefs.get(name)!=null ) { // rule ref in this alt?
|
||||
// s = getLocalAttributeScope(name);
|
||||
// if ( s!=null ) return s;
|
||||
// }
|
||||
// List<GrammarAST> labels = alt.labelDefs.get(name); // label
|
||||
// if ( labels!=null ) {
|
||||
// // it's a label ref, compute scope from label type and grammar type
|
||||
// LabelElementPair anyLabelDef = labels.get(0);
|
||||
// return getPredefinedScope(anyLabelDef.type);
|
||||
// }
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// /** Look for name in the arg, return value, predefined property,
|
||||
// * or dynamic scope attribute list for this rule.
|
||||
// */
|
||||
// public AttributeScope resolveLocalAttributeScope(String name) {
|
||||
// if ( args.get(name)!=null ) return args;
|
||||
// if ( retvals.get(name)!=null ) return retvals;
|
||||
// AttributeScope s = getPredefinedScope(LabelType.RULE_LABEL);
|
||||
// if ( s.get(name)!=null ) return s;
|
||||
// if ( scope!=null && scope.get(name)!=null ) return scope;
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public AttributeScope getPredefinedScope(LabelType ltype) {
|
||||
String grammarLabelKey = g.getTypeString() + ":" + ltype;
|
||||
return Grammar.grammarAndLabelRefTypeToScope.get(grammarLabelKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -143,7 +229,6 @@ public class Rule {
|
|||
"name='" + name + '\'' +
|
||||
", args=" + args +
|
||||
", retvals=" + retvals +
|
||||
", labels=" + labelDefs +
|
||||
", scope=" + scope +
|
||||
'}';
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
package org.antlr.v4.tool;
|
||||
|
||||
/** Grammars, rules, and alternatives all have symbols visible to
|
||||
* actions. To evaluate attr exprs, ask action for its space
|
||||
* then ask space to resolve. If not found in one space we look
|
||||
* at parent. Alt's parent is rule; rule's parent is grammar.
|
||||
*/
|
||||
public interface SymbolSpace {
|
||||
public SymbolSpace getParent();
|
||||
public boolean resolves(String x, ActionAST node);
|
||||
public boolean resolves(String x, String y, ActionAST node);
|
||||
public boolean resolveToRuleRef(String x, ActionAST node);
|
||||
}
|
Loading…
Reference in New Issue