forked from jasder/antlr
added {...}?<msg="foo"> option
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9300]
This commit is contained in:
parent
1cd3bacaf2
commit
61e9eade6a
|
@ -204,9 +204,12 @@ public class DefaultANTLRErrorStrategy implements ANTLRErrorStrategy {
|
||||||
throws RecognitionException
|
throws RecognitionException
|
||||||
{
|
{
|
||||||
String ruleName = recognizer.getRuleNames()[recognizer._ctx.getRuleIndex()];
|
String ruleName = recognizer.getRuleNames()[recognizer._ctx.getRuleIndex()];
|
||||||
String msg = "rule "+ruleName+" failed predicate: {"+
|
String msg = "rule "+ruleName+" "+e.msg;
|
||||||
e.predicateText+"}?";
|
recognizer.notifyListeners(curToken(recognizer), msg, e);
|
||||||
recognizer.notifyListeners(e.offendingToken, msg, e);
|
}
|
||||||
|
|
||||||
|
private Token curToken(BaseRecognizer recognizer) {
|
||||||
|
return ((TokenStream)recognizer.getInputStream()).LT(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void reportUnwantedToken(BaseRecognizer recognizer) {
|
public void reportUnwantedToken(BaseRecognizer recognizer) {
|
||||||
|
|
|
@ -28,31 +28,29 @@
|
||||||
*/
|
*/
|
||||||
package org.antlr.v4.runtime;
|
package org.antlr.v4.runtime;
|
||||||
|
|
||||||
|
import com.sun.istack.internal.Nullable;
|
||||||
|
import org.antlr.v4.runtime.atn.*;
|
||||||
|
|
||||||
/** A semantic predicate failed during validation. Validation of predicates
|
/** A semantic predicate failed during validation. Validation of predicates
|
||||||
* occurs when normally parsing the alternative just like matching a token.
|
* occurs when normally parsing the alternative just like matching a token.
|
||||||
* Disambiguating predicate evaluation occurs when we hoist a predicate into
|
* Disambiguating predicate evaluation occurs when we test a predicate during
|
||||||
* a prediction decision.
|
* prediction.
|
||||||
*/
|
*/
|
||||||
public class FailedPredicateException extends RecognitionException {
|
public class FailedPredicateException extends RecognitionException {
|
||||||
public String ruleName;
|
public int ruleIndex;
|
||||||
public String predicateText;
|
public int predIndex;
|
||||||
|
public String msg;
|
||||||
|
|
||||||
public FailedPredicateException(BaseRecognizer recognizer, String predText) {
|
public FailedPredicateException(BaseRecognizer recognizer) {
|
||||||
super(recognizer, recognizer.getInputStream(), recognizer._ctx);
|
this(recognizer, null);
|
||||||
this.predicateText = predText;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// public FailedPredicateException(BaseRecognizer recognizer,
|
public FailedPredicateException(BaseRecognizer recognizer, @Nullable String msg) {
|
||||||
// IntStream input,
|
super(recognizer, recognizer.getInputStream(), recognizer._ctx);
|
||||||
// String ruleName,
|
ATNState s = recognizer._interp.atn.states.get(recognizer._ctx.s);
|
||||||
// String predicateText)
|
PredicateTransition trans = (PredicateTransition)s.transition(0);
|
||||||
// {
|
ruleIndex = trans.ruleIndex;
|
||||||
// super(recognizer, input, recognizer._ctx);
|
predIndex = trans.predIndex;
|
||||||
// this.ruleName = ruleName;
|
this.msg = msg;
|
||||||
// this.predicateText = predicateText;
|
|
||||||
// }
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return "FailedPredicateException("+ruleName+",{"+predicateText+"}?)";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -447,7 +447,8 @@ ForcedAction(a, chunks) ::= "<chunks>"
|
||||||
ArgAction(a, chunks) ::= "<chunks>"
|
ArgAction(a, chunks) ::= "<chunks>"
|
||||||
|
|
||||||
SemPred(p, chunks) ::= <<
|
SemPred(p, chunks) ::= <<
|
||||||
if (!(<chunks>)) throw new FailedPredicateException(this, "");
|
setState(<p.stateNumber>);
|
||||||
|
if (!(<chunks>)) throw new FailedPredicateException(this, "<p.msg>");
|
||||||
>>
|
>>
|
||||||
|
|
||||||
ActionText(t) ::= "<t.text>"
|
ActionText(t) ::= "<t.text>"
|
||||||
|
|
|
@ -109,6 +109,8 @@ element returns [List<? extends SrcOp> omos]
|
||||||
| subrule {$omos = $subrule.omos;}
|
| subrule {$omos = $subrule.omos;}
|
||||||
| ACTION {$omos = controller.action($ACTION);}
|
| ACTION {$omos = controller.action($ACTION);}
|
||||||
| SEMPRED {$omos = controller.sempred($SEMPRED);}
|
| SEMPRED {$omos = controller.sempred($SEMPRED);}
|
||||||
|
| ^(ACTION elementOptions) {$omos = controller.action($ACTION);}
|
||||||
|
| ^(SEMPRED elementOptions) {$omos = controller.sempred($SEMPRED);}
|
||||||
| treeSpec {$omos = DefaultOutputModelFactory.list($treeSpec.treeMatch);}
|
| treeSpec {$omos = DefaultOutputModelFactory.list($treeSpec.treeMatch);}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -209,6 +211,7 @@ elementOption
|
||||||
: ID
|
: ID
|
||||||
| ^(ASSIGN ID ID)
|
| ^(ASSIGN ID ID)
|
||||||
| ^(ASSIGN ID STRING_LITERAL)
|
| ^(ASSIGN ID STRING_LITERAL)
|
||||||
|
| ^(ASSIGN ID DOUBLE_QUOTE_STRING_LITERAL)
|
||||||
;
|
;
|
||||||
|
|
||||||
// R E W R I T E S T U F F
|
// R E W R I T E S T U F F
|
||||||
|
|
|
@ -30,9 +30,17 @@
|
||||||
package org.antlr.v4.codegen.model;
|
package org.antlr.v4.codegen.model;
|
||||||
|
|
||||||
import org.antlr.v4.codegen.OutputModelFactory;
|
import org.antlr.v4.codegen.OutputModelFactory;
|
||||||
import org.antlr.v4.tool.ast.GrammarAST;
|
import org.antlr.v4.tool.ast.*;
|
||||||
|
|
||||||
/** */
|
/** */
|
||||||
public class SemPred extends Action {
|
public class SemPred extends Action {
|
||||||
public SemPred(OutputModelFactory factory, GrammarAST ast) { super(factory,ast); }
|
public String msg; // user-specified in grammar option
|
||||||
|
|
||||||
|
public SemPred(OutputModelFactory factory, GrammarAST ast) {
|
||||||
|
super(factory,ast);
|
||||||
|
this.msg = ((PredAST)ast).getOption("msg");
|
||||||
|
if ( msg==null ) {
|
||||||
|
msg = "failed predicate: "+ast.getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,8 +276,10 @@ optionValue
|
||||||
|
|
||||||
| // The value is a long string
|
| // The value is a long string
|
||||||
//
|
//
|
||||||
STRING_LITERAL<TerminalAST>
|
STRING_LITERAL
|
||||||
|
|
||||||
|
| DOUBLE_QUOTE_STRING_LITERAL
|
||||||
|
|
||||||
| // The value was an integer number
|
| // The value was an integer number
|
||||||
//
|
//
|
||||||
INT
|
INT
|
||||||
|
@ -594,8 +596,7 @@ element
|
||||||
| -> atom
|
| -> atom
|
||||||
)
|
)
|
||||||
| ebnf
|
| ebnf
|
||||||
| ACTION<ActionAST>
|
| actionElement
|
||||||
| SEMPRED -> SEMPRED<PredAST>
|
|
||||||
| treeSpec
|
| treeSpec
|
||||||
( ebnfSuffix -> ^( ebnfSuffix ^(BLOCK<BlockAST>[$treeSpec.start,"BLOCK"] ^(ALT<AltAST> treeSpec ) ) )
|
( ebnfSuffix -> ^( ebnfSuffix ^(BLOCK<BlockAST>[$treeSpec.start,"BLOCK"] ^(ALT<AltAST> treeSpec ) ) )
|
||||||
| -> treeSpec
|
| -> treeSpec
|
||||||
|
@ -628,20 +629,24 @@ element
|
||||||
recover(input,re);
|
recover(input,re);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
actionElement
|
||||||
|
@after {
|
||||||
|
GrammarAST options = (GrammarAST)$tree.getFirstChildWithType(ANTLRParser.ELEMENT_OPTIONS);
|
||||||
|
if ( options!=null ) {
|
||||||
|
Grammar.setNodeOptions($tree, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: ACTION<ActionAST>
|
||||||
|
| ACTION elementOptions -> ^(ACTION<ActionAST> elementOptions)
|
||||||
|
| SEMPRED<PredAST>
|
||||||
|
| SEMPRED elementOptions -> ^(SEMPRED<PredAST> elementOptions)
|
||||||
|
;
|
||||||
|
|
||||||
labeledElement
|
labeledElement
|
||||||
: id (ass=ASSIGN|ass=PLUS_ASSIGN)
|
: id (ass=ASSIGN|ass=PLUS_ASSIGN)
|
||||||
( atom -> ^($ass id atom)
|
( atom -> ^($ass id atom)
|
||||||
| block (op=ROOT|op=BANG)? -> {$op!=null}? ^($ass id ^($op block))
|
| block (op=ROOT|op=BANG)? -> {$op!=null}? ^($ass id ^($op block))
|
||||||
-> ^($ass id block)
|
-> ^($ass id block)
|
||||||
/*
|
|
||||||
| {buildAST}? blockSet
|
|
||||||
{
|
|
||||||
RecognitionException e =
|
|
||||||
new v4ParserException("can't '"+
|
|
||||||
input.LT(1).getText()+" "+input.LT(2).getText()+"'", input);
|
|
||||||
reportError(missingSemi);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
)
|
)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -710,14 +715,6 @@ ebnfSuffix
|
||||||
;
|
;
|
||||||
|
|
||||||
atom
|
atom
|
||||||
@after {
|
|
||||||
if ( $tree.getType()==DOT ) {
|
|
||||||
GrammarAST options = (GrammarAST)$tree.getFirstChildWithType(ANTLRParser.OPTIONS);
|
|
||||||
if ( options!=null ) {
|
|
||||||
Grammar.setNodeOptions($tree, options);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: // Qualified reference delegate.rule. This must be
|
: // Qualified reference delegate.rule. This must be
|
||||||
// lexically contiguous (no spaces either side of the DOT)
|
// lexically contiguous (no spaces either side of the DOT)
|
||||||
// otherwise it is two references with a wildcard in between
|
// otherwise it is two references with a wildcard in between
|
||||||
|
@ -736,7 +733,18 @@ atom
|
||||||
| terminal (ROOT^ | BANG^)?
|
| terminal (ROOT^ | BANG^)?
|
||||||
| ruleref
|
| ruleref
|
||||||
| notSet (ROOT^|BANG^)?
|
| notSet (ROOT^|BANG^)?
|
||||||
| // Wildcard '.' means any character in a lexer, any
|
| wildcard
|
||||||
|
;
|
||||||
|
catch [RecognitionException re] { throw re; } // pass upwards to element
|
||||||
|
|
||||||
|
wildcard
|
||||||
|
@after {
|
||||||
|
GrammarAST options = (GrammarAST)$tree.getFirstChildWithType(ANTLRParser.ELEMENT_OPTIONS);
|
||||||
|
if ( options!=null ) {
|
||||||
|
Grammar.setNodeOptions($tree, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: // Wildcard '.' means any character in a lexer, any
|
||||||
// token in parser and any node or subtree in a tree parser
|
// token in parser and any node or subtree in a tree parser
|
||||||
// Because the terminal rule is allowed to be the node
|
// Because the terminal rule is allowed to be the node
|
||||||
// specification for the start of a tree rule, we must
|
// specification for the start of a tree rule, we must
|
||||||
|
@ -744,9 +752,8 @@ atom
|
||||||
DOT elementOptions? (astop=ROOT|astop=BANG)?
|
DOT elementOptions? (astop=ROOT|astop=BANG)?
|
||||||
-> {astop!=null}? ^($astop ^(WILDCARD<TerminalAST>[$DOT] elementOptions?))
|
-> {astop!=null}? ^($astop ^(WILDCARD<TerminalAST>[$DOT] elementOptions?))
|
||||||
-> ^(WILDCARD<TerminalAST>[$DOT] elementOptions?)
|
-> ^(WILDCARD<TerminalAST>[$DOT] elementOptions?)
|
||||||
;
|
;
|
||||||
catch [RecognitionException re] { throw re; } // pass upwards to element
|
|
||||||
|
|
||||||
// --------------------
|
// --------------------
|
||||||
// Inverted element set
|
// Inverted element set
|
||||||
//
|
//
|
||||||
|
@ -827,7 +834,7 @@ if ( options!=null ) {
|
||||||
Grammar.setNodeOptions($tree, options);
|
Grammar.setNodeOptions($tree, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
: TOKEN_REF elementOptions? -> ^(TOKEN_REF<TerminalAST> elementOptions?)
|
: TOKEN_REF elementOptions? -> ^(TOKEN_REF<TerminalAST> elementOptions?)
|
||||||
| STRING_LITERAL elementOptions? -> ^(STRING_LITERAL<TerminalAST> elementOptions?)
|
| STRING_LITERAL elementOptions? -> ^(STRING_LITERAL<TerminalAST> elementOptions?)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -837,14 +844,14 @@ elementOptions
|
||||||
: LT elementOption (COMMA elementOption)* GT -> ^(ELEMENT_OPTIONS[$LT,"ELEMENT_OPTIONS"] elementOption+)
|
: LT elementOption (COMMA elementOption)* GT -> ^(ELEMENT_OPTIONS[$LT,"ELEMENT_OPTIONS"] elementOption+)
|
||||||
;
|
;
|
||||||
|
|
||||||
// WHen used with elements we can specify what the tree node type can
|
// When used with elements we can specify what the tree node type can
|
||||||
// be and also assign settings of various options (which we do not check here)
|
// be and also assign settings of various options (which we do not check here)
|
||||||
elementOption
|
elementOption
|
||||||
: // This format indicates the default node option
|
: // This format indicates the default element option
|
||||||
qid
|
qid
|
||||||
|
|
||||||
| // This format indicates option assignment
|
| // This format indicates option assignment
|
||||||
id ASSIGN^ (qid | STRING_LITERAL<TerminalAST>)
|
id ASSIGN^ (qid | STRING_LITERAL | DOUBLE_QUOTE_STRING_LITERAL)
|
||||||
;
|
;
|
||||||
|
|
||||||
rewrite
|
rewrite
|
||||||
|
@ -897,7 +904,7 @@ rewriteTreeElement
|
||||||
|
|
||||||
rewriteTreeAtom
|
rewriteTreeAtom
|
||||||
@after {
|
@after {
|
||||||
GrammarAST options = (GrammarAST)$tree.getFirstChildWithType(ANTLRParser.OPTIONS);
|
GrammarAST options = (GrammarAST)$tree.getFirstChildWithType(ANTLRParser.ELEMENT_OPTIONS);
|
||||||
if ( options!=null ) {
|
if ( options!=null ) {
|
||||||
Grammar.setNodeOptions($tree, options);
|
Grammar.setNodeOptions($tree, options);
|
||||||
}
|
}
|
||||||
|
|
|
@ -95,6 +95,8 @@ element returns [ATNFactory.Handle p]
|
||||||
| subrule {$p = $subrule.p;}
|
| subrule {$p = $subrule.p;}
|
||||||
| ACTION {$p = factory.action((ActionAST)$ACTION);}
|
| ACTION {$p = factory.action((ActionAST)$ACTION);}
|
||||||
| SEMPRED {$p = factory.sempred((PredAST)$SEMPRED);}
|
| SEMPRED {$p = factory.sempred((PredAST)$SEMPRED);}
|
||||||
|
| ^(ACTION .) {$p = factory.action((ActionAST)$ACTION);}
|
||||||
|
| ^(SEMPRED .) {$p = factory.sempred((PredAST)$SEMPRED);}
|
||||||
| treeSpec {$p = $treeSpec.p;}
|
| treeSpec {$p = $treeSpec.p;}
|
||||||
| ^(ROOT a=astOperand) {$p = $a.p;}
|
| ^(ROOT a=astOperand) {$p = $a.p;}
|
||||||
| ^(BANG a=astOperand) {$p = $a.p;}
|
| ^(BANG a=astOperand) {$p = $a.p;}
|
||||||
|
|
|
@ -152,10 +152,10 @@ public void discoverSTRewrite(GrammarAST rew) { }
|
||||||
public void discoverTreeRewrite(GrammarAST rew) { }
|
public void discoverTreeRewrite(GrammarAST rew) { }
|
||||||
|
|
||||||
public void ruleRef(GrammarAST ref, ActionAST arg) { }
|
public void ruleRef(GrammarAST ref, ActionAST arg) { }
|
||||||
public void tokenRef(TerminalAST ref, GrammarAST options) { }
|
public void tokenRef(TerminalAST ref) { }
|
||||||
public void terminalOption(TerminalAST t, GrammarAST ID, GrammarAST value) { }
|
public void elementOption(GrammarASTWithOptions t, GrammarAST ID, GrammarAST value) { }
|
||||||
public void stringRef(TerminalAST ref, GrammarAST options) { }
|
public void stringRef(TerminalAST ref) { }
|
||||||
public void wildcardRef(GrammarAST ref, GrammarAST options) { }
|
public void wildcardRef(GrammarAST ref) { }
|
||||||
public void actionInAlt(ActionAST action) { }
|
public void actionInAlt(ActionAST action) { }
|
||||||
public void sempredInAlt(PredAST pred) { }
|
public void sempredInAlt(PredAST pred) { }
|
||||||
public void label(GrammarAST op, GrammarAST ID, GrammarAST element) { }
|
public void label(GrammarAST op, GrammarAST ID, GrammarAST element) { }
|
||||||
|
@ -165,9 +165,9 @@ public void bangOp(GrammarAST op, GrammarAST opnd) { }
|
||||||
|
|
||||||
public void discoverRewrites(GrammarAST result) { }
|
public void discoverRewrites(GrammarAST result) { }
|
||||||
public void finishRewrites(GrammarAST result) { }
|
public void finishRewrites(GrammarAST result) { }
|
||||||
public void rewriteTokenRef(TerminalAST ast, GrammarAST options, ActionAST arg) { }
|
public void rewriteTokenRef(TerminalAST ast, ActionAST arg) { }
|
||||||
public void rewriteTerminalOption(TerminalAST t, GrammarAST ID, GrammarAST value) { }
|
public void rewriteTerminalOption(TerminalAST t, GrammarAST ID, GrammarAST value) { }
|
||||||
public void rewriteStringRef(TerminalAST ast, GrammarAST options) { }
|
public void rewriteStringRef(TerminalAST ast) { }
|
||||||
public void rewriteRuleRef(GrammarAST ast) { }
|
public void rewriteRuleRef(GrammarAST ast) { }
|
||||||
public void rewriteLabelRef(GrammarAST ast) { }
|
public void rewriteLabelRef(GrammarAST ast) { }
|
||||||
public void rewriteAction(ActionAST ast) { }
|
public void rewriteAction(ActionAST ast) { }
|
||||||
|
@ -224,6 +224,7 @@ optionValue returns [String v]
|
||||||
@init {$v = $start.token.getText();}
|
@init {$v = $start.token.getText();}
|
||||||
: ID
|
: ID
|
||||||
| STRING_LITERAL
|
| STRING_LITERAL
|
||||||
|
| DOUBLE_QUOTE_STRING_LITERAL
|
||||||
| INT
|
| INT
|
||||||
| STAR
|
| STAR
|
||||||
;
|
;
|
||||||
|
@ -352,11 +353,14 @@ element
|
||||||
: labeledElement
|
: labeledElement
|
||||||
| atom
|
| atom
|
||||||
| subrule
|
| subrule
|
||||||
| ACTION {actionInAlt((ActionAST)$ACTION);}
|
| ACTION {actionInAlt((ActionAST)$ACTION);}
|
||||||
| SEMPRED {sempredInAlt((PredAST)$SEMPRED);}
|
| SEMPRED {sempredInAlt((PredAST)$SEMPRED);}
|
||||||
|
| ^(ACTION elementOptions) {actionInAlt((ActionAST)$ACTION);}
|
||||||
|
| ^(SEMPRED elementOptions) {sempredInAlt((PredAST)$SEMPRED);}
|
||||||
|
|
||||||
| treeSpec
|
| treeSpec
|
||||||
| ^(ROOT astOperand) {rootOp($ROOT, $astOperand.start);}
|
| ^(ROOT astOperand) {rootOp($ROOT, $astOperand.start);}
|
||||||
| ^(BANG astOperand) {bangOp($BANG, $astOperand.start);}
|
| ^(BANG astOperand) {bangOp($BANG, $astOperand.start);}
|
||||||
| ^(NOT blockSet)
|
| ^(NOT blockSet)
|
||||||
| ^(NOT block)
|
| ^(NOT block)
|
||||||
| DOWN_TOKEN
|
| DOWN_TOKEN
|
||||||
|
@ -398,8 +402,8 @@ ebnfSuffix
|
||||||
atom: range
|
atom: range
|
||||||
| ^(DOT ID terminal)
|
| ^(DOT ID terminal)
|
||||||
| ^(DOT ID ruleref)
|
| ^(DOT ID ruleref)
|
||||||
| ^(WILDCARD elementOptions) {wildcardRef($WILDCARD, $elementOptions.start);}
|
| ^(WILDCARD elementOptions) {wildcardRef($WILDCARD);}
|
||||||
| WILDCARD {wildcardRef($WILDCARD, null);}
|
| WILDCARD {wildcardRef($WILDCARD);}
|
||||||
| terminal
|
| terminal
|
||||||
| blockSet
|
| blockSet
|
||||||
| ruleref
|
| ruleref
|
||||||
|
@ -410,12 +414,12 @@ blockSet
|
||||||
;
|
;
|
||||||
|
|
||||||
setElement
|
setElement
|
||||||
: STRING_LITERAL {stringRef((TerminalAST)$STRING_LITERAL, null);}
|
: STRING_LITERAL {stringRef((TerminalAST)$STRING_LITERAL);}
|
||||||
| TOKEN_REF {tokenRef((TerminalAST)$TOKEN_REF, null);}
|
| TOKEN_REF {tokenRef((TerminalAST)$TOKEN_REF);}
|
||||||
| ^(RANGE a=STRING_LITERAL b=STRING_LITERAL)
|
| ^(RANGE a=STRING_LITERAL b=STRING_LITERAL)
|
||||||
{
|
{
|
||||||
stringRef((TerminalAST)$a, null);
|
stringRef((TerminalAST)$a);
|
||||||
stringRef((TerminalAST)$b, null);
|
stringRef((TerminalAST)$b);
|
||||||
}
|
}
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -437,20 +441,21 @@ range
|
||||||
|
|
||||||
terminal
|
terminal
|
||||||
: ^(STRING_LITERAL elementOptions)
|
: ^(STRING_LITERAL elementOptions)
|
||||||
{stringRef((TerminalAST)$STRING_LITERAL, $elementOptions.start);}
|
{stringRef((TerminalAST)$STRING_LITERAL);}
|
||||||
| STRING_LITERAL {stringRef((TerminalAST)$STRING_LITERAL, null);}
|
| STRING_LITERAL {stringRef((TerminalAST)$STRING_LITERAL);}
|
||||||
| ^(TOKEN_REF elementOptions) {tokenRef((TerminalAST)$TOKEN_REF, $elementOptions.start);}
|
| ^(TOKEN_REF elementOptions) {tokenRef((TerminalAST)$TOKEN_REF);}
|
||||||
| TOKEN_REF {tokenRef((TerminalAST)$TOKEN_REF, null);}
|
| TOKEN_REF {tokenRef((TerminalAST)$TOKEN_REF);}
|
||||||
;
|
;
|
||||||
|
|
||||||
elementOptions
|
elementOptions
|
||||||
: ^(ELEMENT_OPTIONS elementOption[(TerminalAST)$start.getParent()]+)
|
: ^(ELEMENT_OPTIONS elementOption[(GrammarASTWithOptions)$start.getParent()]+)
|
||||||
;
|
;
|
||||||
|
|
||||||
elementOption[TerminalAST t]
|
elementOption[GrammarASTWithOptions t]
|
||||||
: ID {terminalOption(t, $ID, null);}
|
: ID {elementOption(t, $ID, null);}
|
||||||
| ^(ASSIGN id=ID v=ID) {terminalOption(t, $id, $v);}
|
| ^(ASSIGN id=ID v=ID) {elementOption(t, $id, $v);}
|
||||||
| ^(ASSIGN ID v=STRING_LITERAL) {terminalOption(t, $ID, $v);}
|
| ^(ASSIGN ID v=STRING_LITERAL) {elementOption(t, $ID, $v);}
|
||||||
|
| ^(ASSIGN ID v=DOUBLE_QUOTE_STRING_LITERAL) {elementOption(t, $ID, $v);}
|
||||||
;
|
;
|
||||||
|
|
||||||
rewrite
|
rewrite
|
||||||
|
@ -487,16 +492,16 @@ rewriteTreeElement
|
||||||
|
|
||||||
rewriteTreeAtom
|
rewriteTreeAtom
|
||||||
: ^(TOKEN_REF rewriteElementOptions ARG_ACTION)
|
: ^(TOKEN_REF rewriteElementOptions ARG_ACTION)
|
||||||
{rewriteTokenRef((TerminalAST)$start,$rewriteElementOptions.start,(ActionAST)$ARG_ACTION);}
|
{rewriteTokenRef((TerminalAST)$start,(ActionAST)$ARG_ACTION);}
|
||||||
| ^(TOKEN_REF rewriteElementOptions)
|
| ^(TOKEN_REF rewriteElementOptions)
|
||||||
{rewriteTokenRef((TerminalAST)$start,$rewriteElementOptions.start,null);}
|
{rewriteTokenRef((TerminalAST)$start,null);}
|
||||||
| ^(TOKEN_REF ARG_ACTION)
|
| ^(TOKEN_REF ARG_ACTION)
|
||||||
{rewriteTokenRef((TerminalAST)$start,null,(ActionAST)$ARG_ACTION);}
|
{rewriteTokenRef((TerminalAST)$start,(ActionAST)$ARG_ACTION);}
|
||||||
| TOKEN_REF {rewriteTokenRef((TerminalAST)$start,null,null);}
|
| TOKEN_REF {rewriteTokenRef((TerminalAST)$start,null);}
|
||||||
| RULE_REF {rewriteRuleRef($start);}
|
| RULE_REF {rewriteRuleRef($start);}
|
||||||
| ^(STRING_LITERAL rewriteElementOptions)
|
| ^(STRING_LITERAL rewriteElementOptions)
|
||||||
{rewriteStringRef((TerminalAST)$start,$rewriteElementOptions.start);}
|
{rewriteStringRef((TerminalAST)$start);}
|
||||||
| STRING_LITERAL {rewriteStringRef((TerminalAST)$start,null);}
|
| STRING_LITERAL {rewriteStringRef((TerminalAST)$start);}
|
||||||
| LABEL {rewriteLabelRef($start);}
|
| LABEL {rewriteLabelRef($start);}
|
||||||
| ACTION {rewriteAction((ActionAST)$start);}
|
| ACTION {rewriteAction((ActionAST)$start);}
|
||||||
;
|
;
|
||||||
|
|
|
@ -31,11 +31,8 @@ package org.antlr.v4.semantics;
|
||||||
|
|
||||||
import org.antlr.runtime.Token;
|
import org.antlr.runtime.Token;
|
||||||
import org.antlr.v4.misc.Utils;
|
import org.antlr.v4.misc.Utils;
|
||||||
import org.antlr.v4.parse.ANTLRParser;
|
import org.antlr.v4.parse.*;
|
||||||
import org.antlr.v4.parse.GrammarTreeVisitor;
|
import org.antlr.v4.tool.*;
|
||||||
import org.antlr.v4.tool.ErrorManager;
|
|
||||||
import org.antlr.v4.tool.ErrorType;
|
|
||||||
import org.antlr.v4.tool.Grammar;
|
|
||||||
import org.antlr.v4.tool.ast.*;
|
import org.antlr.v4.tool.ast.*;
|
||||||
import org.stringtemplate.v4.misc.MultiMap;
|
import org.stringtemplate.v4.misc.MultiMap;
|
||||||
|
|
||||||
|
@ -130,6 +127,13 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public static final Set<String> legalSemPredOptions =
|
||||||
|
new HashSet<String>() {
|
||||||
|
{
|
||||||
|
add("msg");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/** Set of valid imports. E.g., can only import a tree parser into
|
/** Set of valid imports. E.g., can only import a tree parser into
|
||||||
* another tree parser. Maps delegate to set of delegator grammar types.
|
* another tree parser. Maps delegate to set of delegator grammar types.
|
||||||
* validDelegations.get(LEXER) gives list of the kinds of delegators
|
* validDelegations.get(LEXER) gives list of the kinds of delegators
|
||||||
|
@ -225,10 +229,10 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void terminalOption(TerminalAST t, GrammarAST ID, GrammarAST value) {
|
public void elementOption(GrammarASTWithOptions elem, GrammarAST ID, GrammarAST value) {
|
||||||
String v = null;
|
String v = null;
|
||||||
if ( value!=null ) v = value.getText();
|
if ( value!=null ) v = value.getText();
|
||||||
boolean ok = checkTokenOptions(ID, v);
|
boolean ok = checkElementOptions(elem, ID, v);
|
||||||
// if ( ok ) {
|
// if ( ok ) {
|
||||||
// if ( v!=null ) {
|
// if ( v!=null ) {
|
||||||
// t.setOption(ID.getText(), v);
|
// t.setOption(ID.getText(), v);
|
||||||
|
@ -268,7 +272,7 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void wildcardRef(GrammarAST ref, GrammarAST options) {
|
public void wildcardRef(GrammarAST ref) {
|
||||||
checkWildcardRoot(ref);
|
checkWildcardRoot(ref);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -400,8 +404,30 @@ public class BasicSemanticChecks extends GrammarTreeVisitor {
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Check option is appropriate for token; parent is ELEMENT_OPTIONS */
|
/** Check option is appropriate for elem; parent of ID is ELEMENT_OPTIONS */
|
||||||
boolean checkTokenOptions(GrammarAST ID, String value) {
|
boolean checkElementOptions(GrammarASTWithOptions elem, GrammarAST ID, String value) {
|
||||||
|
if ( elem instanceof TerminalAST ) {
|
||||||
|
return checkTokenOptions((TerminalAST)elem, ID, value);
|
||||||
|
}
|
||||||
|
if ( elem.getType()==ANTLRParser.ACTION ) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if ( elem.getType()==ANTLRParser.SEMPRED ) {
|
||||||
|
Token optionID = ID.token;
|
||||||
|
String fileName = optionID.getInputStream().getSourceName();
|
||||||
|
if ( value!=null && !legalSemPredOptions.contains(optionID.getText()) ) {
|
||||||
|
g.tool.errMgr.grammarError(ErrorType.ILLEGAL_OPTION,
|
||||||
|
fileName,
|
||||||
|
optionID,
|
||||||
|
optionID.getText());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
boolean checkTokenOptions(TerminalAST elem, GrammarAST ID, String value) {
|
||||||
Token optionID = ID.token;
|
Token optionID = ID.token;
|
||||||
String fileName = optionID.getInputStream().getSourceName();
|
String fileName = optionID.getInputStream().getSourceName();
|
||||||
// don't care about ID<ASTNodeName> options
|
// don't care about ID<ASTNodeName> options
|
||||||
|
|
|
@ -30,12 +30,9 @@
|
||||||
package org.antlr.v4.semantics;
|
package org.antlr.v4.semantics;
|
||||||
|
|
||||||
import org.antlr.v4.parse.GrammarTreeVisitor;
|
import org.antlr.v4.parse.GrammarTreeVisitor;
|
||||||
import org.antlr.v4.tool.ast.ActionAST;
|
import org.antlr.v4.tool.ast.*;
|
||||||
import org.antlr.v4.tool.ast.GrammarAST;
|
|
||||||
import org.antlr.v4.tool.ast.TerminalAST;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
public class RewriteRefs extends GrammarTreeVisitor {
|
public class RewriteRefs extends GrammarTreeVisitor {
|
||||||
List<GrammarAST> shallow = new ArrayList<GrammarAST>();
|
List<GrammarAST> shallow = new ArrayList<GrammarAST>();
|
||||||
|
@ -52,12 +49,12 @@ public class RewriteRefs extends GrammarTreeVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rewriteTokenRef(TerminalAST ast, GrammarAST options, ActionAST arg) {
|
public void rewriteTokenRef(TerminalAST ast, ActionAST arg) {
|
||||||
track(ast);
|
track(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rewriteStringRef(TerminalAST ast, GrammarAST options) {
|
public void rewriteStringRef(TerminalAST ast) {
|
||||||
track(ast);
|
track(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,18 +29,11 @@
|
||||||
|
|
||||||
package org.antlr.v4.semantics;
|
package org.antlr.v4.semantics;
|
||||||
|
|
||||||
import org.antlr.v4.parse.GrammarTreeVisitor;
|
import org.antlr.v4.parse.*;
|
||||||
import org.antlr.v4.parse.ScopeParser;
|
import org.antlr.v4.tool.*;
|
||||||
import org.antlr.v4.tool.AttributeDict;
|
|
||||||
import org.antlr.v4.tool.Grammar;
|
|
||||||
import org.antlr.v4.tool.LabelElementPair;
|
|
||||||
import org.antlr.v4.tool.Rule;
|
|
||||||
import org.antlr.v4.tool.ast.*;
|
import org.antlr.v4.tool.ast.*;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
/** Collects (create) rules, terminals, strings, actions, scopes etc... from AST
|
/** Collects (create) rules, terminals, strings, actions, scopes etc... from AST
|
||||||
* side-effects: sets resolver field of asts for actions and
|
* side-effects: sets resolver field of asts for actions and
|
||||||
|
@ -178,7 +171,7 @@ public class SymbolCollector extends GrammarTreeVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void stringRef(TerminalAST ref, GrammarAST options) {
|
public void stringRef(TerminalAST ref) {
|
||||||
terminals.add(ref);
|
terminals.add(ref);
|
||||||
strings.add(ref.getText());
|
strings.add(ref.getText());
|
||||||
if ( currentRule!=null ) {
|
if ( currentRule!=null ) {
|
||||||
|
@ -187,7 +180,7 @@ public class SymbolCollector extends GrammarTreeVisitor {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void tokenRef(TerminalAST ref, GrammarAST options) {
|
public void tokenRef(TerminalAST ref) {
|
||||||
terminals.add(ref);
|
terminals.add(ref);
|
||||||
tokenIDRefs.add(ref);
|
tokenIDRefs.add(ref);
|
||||||
if ( currentRule!=null ) {
|
if ( currentRule!=null ) {
|
||||||
|
@ -211,12 +204,12 @@ public class SymbolCollector extends GrammarTreeVisitor {
|
||||||
public void rewriteRuleRef(GrammarAST ast) { rewriteElements.add(ast); }
|
public void rewriteRuleRef(GrammarAST ast) { rewriteElements.add(ast); }
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rewriteStringRef(TerminalAST ast, GrammarAST options) {
|
public void rewriteStringRef(TerminalAST ast) {
|
||||||
rewriteElements.add(ast);
|
rewriteElements.add(ast);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void rewriteTokenRef(TerminalAST ast, GrammarAST options, ActionAST arg) {
|
public void rewriteTokenRef(TerminalAST ast, ActionAST arg) {
|
||||||
rewriteElements.add(ast);
|
rewriteElements.add(ast);
|
||||||
if ( arg!=null ) arg.resolver = currentRule.alt[currentOuterAltNumber];
|
if ( arg!=null ) arg.resolver = currentRule.alt[currentOuterAltNumber];
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,26 +29,17 @@
|
||||||
|
|
||||||
package org.antlr.v4.tool;
|
package org.antlr.v4.tool;
|
||||||
|
|
||||||
import org.antlr.runtime.tree.TreeVisitor;
|
import org.antlr.runtime.tree.*;
|
||||||
import org.antlr.runtime.tree.TreeVisitorAction;
|
|
||||||
import org.antlr.runtime.tree.TreeWizard;
|
|
||||||
import org.antlr.v4.Tool;
|
import org.antlr.v4.Tool;
|
||||||
import org.antlr.v4.misc.CharSupport;
|
import org.antlr.v4.misc.*;
|
||||||
import org.antlr.v4.misc.OrderedHashMap;
|
import org.antlr.v4.parse.*;
|
||||||
import org.antlr.v4.parse.ANTLRParser;
|
import org.antlr.v4.runtime.*;
|
||||||
import org.antlr.v4.parse.GrammarASTAdaptor;
|
|
||||||
import org.antlr.v4.parse.GrammarTreeVisitor;
|
|
||||||
import org.antlr.v4.parse.TokenVocabParser;
|
|
||||||
import org.antlr.v4.runtime.Lexer;
|
|
||||||
import org.antlr.v4.runtime.Token;
|
|
||||||
import org.antlr.v4.runtime.atn.ATN;
|
import org.antlr.v4.runtime.atn.ATN;
|
||||||
import org.antlr.v4.runtime.dfa.DFA;
|
import org.antlr.v4.runtime.dfa.DFA;
|
||||||
import org.antlr.v4.runtime.misc.IntSet;
|
import org.antlr.v4.runtime.misc.*;
|
||||||
import org.antlr.v4.runtime.misc.IntervalSet;
|
|
||||||
import org.antlr.v4.tool.ast.*;
|
import org.antlr.v4.tool.ast.*;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.*;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Grammar implements AttributeResolver {
|
public class Grammar implements AttributeResolver {
|
||||||
|
@ -756,7 +747,7 @@ public class Grammar implements AttributeResolver {
|
||||||
final Set<String> strings = new HashSet<String>();
|
final Set<String> strings = new HashSet<String>();
|
||||||
GrammarTreeVisitor collector = new GrammarTreeVisitor() {
|
GrammarTreeVisitor collector = new GrammarTreeVisitor() {
|
||||||
@Override
|
@Override
|
||||||
public void stringRef(TerminalAST ref, GrammarAST options) {
|
public void stringRef(TerminalAST ref) {
|
||||||
strings.add(ref.getText());
|
strings.add(ref.getText());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -35,7 +35,7 @@ import org.antlr.v4.tool.AttributeResolver;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class ActionAST extends GrammarAST implements RuleElementAST {
|
public class ActionAST extends GrammarASTWithOptions implements RuleElementAST {
|
||||||
// Alt, rule, grammar space
|
// Alt, rule, grammar space
|
||||||
public AttributeResolver resolver;
|
public AttributeResolver resolver;
|
||||||
public List<Token> chunks; // useful for ANTLR IDE developers
|
public List<Token> chunks; // useful for ANTLR IDE developers
|
||||||
|
|
|
@ -30,9 +30,9 @@
|
||||||
package org.antlr.v4.tool.ast;
|
package org.antlr.v4.tool.ast;
|
||||||
|
|
||||||
import org.antlr.runtime.Token;
|
import org.antlr.runtime.Token;
|
||||||
|
import org.antlr.v4.misc.CharSupport;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
public abstract class GrammarASTWithOptions extends GrammarAST {
|
public abstract class GrammarASTWithOptions extends GrammarAST {
|
||||||
protected Map<String, String> options;
|
protected Map<String, String> options;
|
||||||
|
@ -49,6 +49,9 @@ public abstract class GrammarASTWithOptions extends GrammarAST {
|
||||||
|
|
||||||
public void setOption(String key, String value) {
|
public void setOption(String key, String value) {
|
||||||
if ( options==null ) options = new HashMap<String, String>();
|
if ( options==null ) options = new HashMap<String, String>();
|
||||||
|
if ( value.startsWith("'") || value.startsWith("\"") ) {
|
||||||
|
value = CharSupport.getStringFromGrammarStringLiteral(value);
|
||||||
|
}
|
||||||
options.put(key, value);
|
options.put(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue