detect missing ';' on rule

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 6709]
This commit is contained in:
parrt 2010-02-20 17:28:43 -08:00
parent 483c5881a1
commit 0e38fd9c47
32 changed files with 4196 additions and 3460 deletions

View File

@ -93,7 +93,7 @@ NO_VIABLE_DFA_ALT(arg,arg2) ::=
*/
// GRAMMAR ERRORS
SYNTAX_ERROR(arg) ::= "syntax error: <arg>"
SYNTAX_ERROR(arg) ::= "<arg>"
RULE_REDEFINITION(arg) ::=
"rule <arg> redefinition"
SCOPE_REDEFINITION(arg) ::=

View File

@ -291,7 +291,7 @@ public class Tool {
}
}
public GrammarRootAST load(String fileName) {
public GrammarAST load(String fileName) {
ANTLRFileStream in = null;
try {
in = new ANTLRFileStream(fileName);
@ -302,18 +302,18 @@ public class Tool {
return load(in);
}
public GrammarRootAST loadFromString(String grammar) {
public GrammarAST loadFromString(String grammar) {
return load(new ANTLRStringStream(grammar));
}
public GrammarRootAST load(CharStream in) {
public GrammarAST load(CharStream in) {
try {
ANTLRLexer lexer = new ANTLRLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ANTLRParser p = new ANTLRParser(tokens);
p.setTreeAdaptor(new GrammarASTAdaptor(in));
ParserRuleReturnScope r = p.grammarSpec();
return (GrammarRootAST)r.getTree();
return (GrammarAST)r.getTree();
}
catch (RecognitionException re) {
// TODO: do we gen errors now?
@ -324,8 +324,10 @@ public class Tool {
public void process() {
// testing parser
GrammarRootAST ast = load(grammarFileNames.get(0));
GrammarAST t = load(grammarFileNames.get(0));
GrammarRootAST lexerAST = null;
if ( t instanceof GrammarASTErrorNode ) return; // came back as error node
GrammarRootAST ast = (GrammarRootAST)t;
if ( ast.grammarType==ANTLRParser.COMBINED ) {
lexerAST = extractImplicitLexer(ast); // alters ast
}

View File

@ -0,0 +1,41 @@
package org.antlr.v4.analysis;
public class Label implements Comparable, Cloneable {
public static final int INVALID = -7;
public static final int ACTION = -6;
public static final int EPSILON = -5;
public static final String EPSILON_STR = "<EPSILON>";
/** label is a semantic predicate; implies label is epsilon also */
public static final int SEMPRED = -4;
/** label is a set of tokens or char */
public static final int SET = -3;
/** End of Token is like EOF for lexer rules. It implies that no more
* characters are available and that NFA conversion should terminate
* for this path. For example
*
* A : 'a' 'b' | 'a' ;
*
* yields a DFA predictor:
*
* o-a->o-b->1 predict alt 1
* |
* |-EOT->o predict alt 2
*
* To generate code for EOT, treat it as the "default" path, which
* implies there is no way to mismatch a char for the state from
* which the EOT emanates.
*/
public static final int EOT = -2;
public static final int EOF = -1;
public int compareTo(Object o) {
return 0;
}
}

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} ANTLRLexer.g 2010-02-16 17:54:23
// $ANTLR ${project.version} ${buildNumber} ANTLRLexer.g 2010-02-19 17:45:05
/*
[The "BSD licence"]
@ -263,7 +263,7 @@ public class ANTLRLexer extends Lexer {
if ( (( input.LA(2) != '/')) ) {
alt3=1;
}
else if ( ((( true )||(( true )&&( !(input.LA(1) == '*' && input.LA(2) == '/') )))) ) {
else if ( (((( true )&&( !(input.LA(1) == '*' && input.LA(2) == '/') ))||( true ))) ) {
alt3=2;
}
else {

View File

@ -73,7 +73,6 @@ tokens {
EPSILON;
ALT;
ALTLIST;
RESULT;
ID;
ARG;
ARGLIST;
@ -132,6 +131,22 @@ package org.antlr.v4.parse;
import org.antlr.v4.tool.*;
}
@members {
Stack paraphrases = new Stack();
public void displayRecognitionError(String[] tokenNames,
RecognitionException e)
{
String msg = ErrorManager.getParserErrorMessage(this, e);
if ( paraphrases.size()>0 ) {
String paraphrase = (String)paraphrases.peek();
msg = msg+" while "+paraphrase;
}
List stack = getRuleInvocationStack(e, this.getClass().getName());
msg += ", rule stack = "+stack;
ErrorManager.syntaxError(ErrorType.SYNTAX_ERROR, getSourceName(), e.token, e, msg);
}
}
// The main entry point for parsing a V3 grammar from top to toe. This is
// the method call from whence to obtain the AST for the parse.
//
@ -158,7 +173,7 @@ grammarSpec
// constrained by some arbitrary order of declarations that nobody
// can remember. In the next phase of the parse, we verify that these
// constructs are valid, not repeated and so on.
prequelConstruct*
sync ( prequelConstruct sync )*
// We should now see at least one ANTLR EBNF style rule
// declaration. If the rules are missing we will let the
@ -351,13 +366,25 @@ actionScopeName
;
rules
: rule*
: sync (rule sync)*
// Rewrite with an enclosing node as this is good for counting
// the number of rules and an easy marker for the walker to detect
// that there are no rules.
->^(RULES rule*)
;
sync
@init {
BitSet followSet = computeErrorRecoverySet();
if ( input.LA(1)!=Token.EOF && !followSet.member(input.LA(1)) ) {
reportError(new NoViableAltException("",0,0,input));
beginResync();
consumeUntil(input, followSet);
endResync();
}
} :
;
// The specification of an EBNF rule in ANTLR style, with all the
// rule level parameters, declarations, actions, rewrite specs and so
// on.
@ -368,6 +395,8 @@ rules
// particular functional element is not valid in the context of the
// grammar type, such as using returns in lexer rules and so on.
rule
@init { paraphrases.push("matching a rule"); }
@after { paraphrases.pop(); }
: // A rule may start with an optional documentation comment
DOC_COMMENT?
@ -406,20 +435,20 @@ rule
// context free and just accept anything that is a syntactically correct
// construct.
//
rulePrequel*
rulePrequels
COLON
// The rule is, at the top level, just a list of alts, with
// finer grained structure defined within the alts.
altListAsBlock
ruleBlock
SEMI
exceptionGroup
-> ^( RULE<RuleAST> id DOC_COMMENT? ruleModifiers? ARG_ACTION?
ruleReturns? rulePrequel* altListAsBlock exceptionGroup*
ruleReturns? rulePrequels? ruleBlock exceptionGroup*
)
;
@ -445,7 +474,13 @@ finallyClause
: FINALLY ACTION -> ^(FINALLY ACTION<ActionAST>)
;
// An individual rule level configuration as referenced by the ruleActions
rulePrequels
@init { paraphrases.push("matching rule preamble"); }
@after { paraphrases.pop(); }
: sync (rulePrequel sync)* -> rulePrequel*
;
// An individual rule level configuration as referenced by the ruleActions
// rule above.
//
rulePrequel
@ -534,13 +569,19 @@ altList
// can be processed by the generic BLOCK rule. Note that we
// use a separate rule so that the BLOCK node has start and stop
// boundaries set correctly by rule post processing of rewrites.
altListAsBlock
ruleBlock
: altList -> ^(BLOCK<BlockAST> altList)
;
catch [ResyncToEndOfRuleBlock e] {
// just resyncing; ignore error
retval.tree = (GrammarAST)adaptor.errorNode(input, retval.start, input.LT(-1), null);
}
// An individual alt with an optional rewrite clause for the
// elements of the alt.
alternative
@init { paraphrases.push("matching alternative"); }
@after { paraphrases.pop(); }
: elements
( rewrite -> ^(ALT_REWRITE elements rewrite)
| -> elements
@ -554,6 +595,11 @@ elements
;
element
@init {
paraphrases.push("looking for rule element");
int m = input.mark();
}
@after { paraphrases.pop(); }
: labeledElement
( ebnfSuffix -> ^( ebnfSuffix ^(BLOCK<BlockAST> ^(ALT labeledElement ) ))
| -> labeledElement
@ -573,6 +619,76 @@ element
| -> treeSpec
)
;
catch [RecognitionException re] {
retval.tree = (GrammarAST)adaptor.errorNode(input, retval.start, input.LT(-1), re);
int ttype = input.get(input.range()).getType();
// look for anything that really belongs at the start of the rule minus the initial ID
if ( ttype==COLON || ttype==RETURNS || ttype==CATCH || ttype==FINALLY || ttype==AT ) {
RecognitionException missingSemi =
new v4ParserException("unterminated rule (missing ';') detected at '"+
input.LT(1).getText()+" "+input.LT(2).getText()+"'", input);
reportError(missingSemi);
if ( ttype==CATCH || ttype==FINALLY ) {
input.seek(input.range()); // ignore what's before rule trailer stuff
}
if ( ttype==RETURNS || ttype==AT ) { // scan back looking for ID of rule header
int p = input.index();
Token t = input.get(p);
while ( t.getType()!=RULE_REF && t.getType()!=TOKEN_REF ) {
p--;
t = input.get(p);
}
input.seek(p);
}
throw new ResyncToEndOfRuleBlock(); // make sure it goes back to rule block level to recover
}
reportError(re);
recover(input,re);
/*
input.rewind(m);
final List subset = input.get(input.index(), input.range());
System.out.println("failed to match as element: '"+subset);
CommonTokenStream ns = new CommonTokenStream(
new TokenSource() {
int i = 0;
public Token nextToken() {
if ( i>=subset.size() ) return Token.EOF_TOKEN;
return (Token)subset.get(i++);
}
public String getSourceName() { return null; }
});
ANTLRParser errorParser = new ANTLRParser(ns);
errorParser.setTreeAdaptor(this.adaptor);
errorParser.element_errors(re);
retval.tree = (GrammarAST)adaptor.errorNode(input, retval.start, input.LT(-1), re);
*/
}
/*
element_errors[RecognitionException origError]
options {backtrack=true;}
@init {
int m = input.mark();
//state.backtracking++;
}
@after {
//state.backtracking--;
}
: ( DOC_COMMENT? ruleModifiers? id ARG_ACTION? ruleReturns? rulePrequel* COLON
| exceptionGroup
)
{reportError(missingSemi); recover(input,null);}
;
catch [RecognitionException ignore] {
input.rewind(m);
input.consume(); // kill at least one token
reportError(origError);
BitSet followSet = computeErrorRecoverySet();
beginResync();
consumeUntil(input, followSet);
endResync();
}
*/
labeledElement : id (ASSIGN^|PLUS_ASSIGN^) (atom|block) ;
@ -650,8 +766,7 @@ atom: range (ROOT^ | BANG^)? // Range x..y - only valid in lexers
| ruleref
| notSet (ROOT^|BANG^)?
;
catch [RecognitionException re] { throw re; } // pass upwards to element
// --------------------
// Inverted element set
@ -704,6 +819,7 @@ ruleref
| -> ^(RULE_REF ARG_ACTION?)
)
;
catch [RecognitionException re] { throw re; } // pass upwards to element
// ---------------
// Character Range
@ -895,12 +1011,18 @@ rewriteTemplateArg
// reference, hence this rule is used to pick up whichever it is and rewrite
// it as a generic ID token.
id
@init { paraphrases.push("looking for an identifier"); }
@after { paraphrases.pop(); }
: RULE_REF ->ID[$RULE_REF]
| TOKEN_REF ->ID[$TOKEN_REF]
| TEMPLATE ->ID[$TEMPLATE] // keyword
;
qid : id (DOT id)* -> ID[$qid.start, $text] ;
qid
@init { paraphrases.push("looking for a qualified identifier"); }
@after { paraphrases.pop(); }
: id (DOT id)* -> ID[$qid.start, $text]
;
alternativeEntry : alternative EOF ; // allow gunit to call alternative and see EOF afterwards
elementEntry : element EOF ;

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,22 @@
LT=43
COMBINED=91
COMBINED=90
STAR=48
BACKTRACK_SEMPRED=96
BACKTRACK_SEMPRED=95
DOUBLE_ANGLE_STRING_LITERAL=11
FORCED_ACTION=5
ARGLIST=89
ARGLIST=88
ALTLIST=85
NOT=60
SEMPRED=4
ACTION=16
TOKEN_REF=62
RULEMODIFIERS=74
ST_RESULT=100
ST_RESULT=99
RPAREN=41
RET=90
RET=89
IMPORT=22
STRING_LITERAL=67
ARG=88
ARG=87
ARG_ACTION=14
DOUBLE_QUOTE_STRING_LITERAL=10
COMMENT=9
@ -24,7 +24,7 @@ GRAMMAR=27
ACTION_CHAR_LITERAL=13
WSCHARS=65
RULEACTIONS=75
INITACTION=92
INITACTION=91
ALT_REWRITE=101
IMPLIES=42
RBRACE=61
@ -36,7 +36,7 @@ THROWS=32
INT=64
CHAR_RANGE=82
EPSILON=83
LIST=98
LIST=97
COLONCOLON=37
WSNLCHARS=18
WS=70
@ -48,10 +48,10 @@ CLOSURE=79
PARSER=25
DOLLAR=53
PROTECTED=28
ELEMENT_OPTIONS=99
ELEMENT_OPTIONS=98
NESTED_ACTION=15
FRAGMENT=23
ID=87
ID=86
TREE_BEGIN=58
LPAREN=40
AT=59
@ -61,7 +61,7 @@ TREE=26
SCOPE=21
ETC=56
COMMA=38
WILDCARD=97
WILDCARD=96
DOC_COMMENT=6
PLUS=49
REWRITE_BLOCK=77
@ -73,8 +73,8 @@ UNICODE_ESC=69
HEX_DIGIT=68
RANGE=55
TOKENS=20
GATED_SEMPRED=94
RESULT=86
RESULT=100
GATED_SEMPRED=93
BANG=47
ACTION_STRING_LITERAL=12
ROOT=52
@ -86,9 +86,9 @@ SYNPRED=81
COLON=36
QUESTION=46
FINALLY=34
LABEL=93
LABEL=92
TEMPLATE=35
SYN_SEMPRED=95
SYN_SEMPRED=94
ERRCHAR=71
BLOCK=76
PLUS_ASSIGN=50

View File

@ -72,13 +72,13 @@ public String getErrorMessage(RecognitionException e,
{
List stack = getRuleInvocationStack(e, this.getClass().getName());
String msg = null;
String inputContext =
((CommonTree)input.LT(-3)).token+" "+
((CommonTree)input.LT(-2)).token+" "+
((CommonTree)input.LT(-1)).token+" >>>"+
((CommonTree)input.LT(1)).token+"<<< "+
((CommonTree)input.LT(2)).token+" "+
((CommonTree)input.LT(3)).token;
String inputContext =
input.LT(-3) == null ? "" : ((Tree)input.LT(-3)).getText()+" "+
input.LT(-2) == null ? "" : ((Tree)input.LT(-2)).getText()+" "+
input.LT(-1) == null ? "" : ((Tree)input.LT(-1)).getText()+" >>>"+
input.LT(1) == null ? "" : ((Tree)input.LT(1)).getText()+"<<< "+
input.LT(2) == null ? "" : ((Tree)input.LT(2)).getText()+" "+
input.LT(3) == null ? "" : ((Tree)input.LT(3)).getText();
if ( e instanceof NoViableAltException ) {
NoViableAltException nvae = (NoViableAltException)e;
msg = " no viable alt; token="+e.token+
@ -104,6 +104,23 @@ public void traceIn(String ruleName, int ruleIndex) {
System.out.print(" backtracking="+state.backtracking);
}
System.out.println();
}
protected void mismatch(IntStream input, int ttype, BitSet follow)
throws RecognitionException {
throw new MismatchedTokenException(ttype, input);
}
public void recoverFromMismatchedToken(IntStream input,
RecognitionException e, BitSet follow)
throws RecognitionException
{
throw e;
}
}
// Alter code generation so catch-clauses get replace with // this action.
@rulecatch { catch (RecognitionException e) {
throw e;
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,22 +1,22 @@
COMBINED=91
COMBINED=90
LT=43
STAR=48
BACKTRACK_SEMPRED=96
BACKTRACK_SEMPRED=95
DOUBLE_ANGLE_STRING_LITERAL=11
FORCED_ACTION=5
ARGLIST=89
ARGLIST=88
ALTLIST=85
NOT=60
SEMPRED=4
ACTION=16
TOKEN_REF=62
RULEMODIFIERS=74
ST_RESULT=100
ST_RESULT=99
RPAREN=41
RET=90
RET=89
IMPORT=22
STRING_LITERAL=67
ARG=88
ARG=87
ARG_ACTION=14
DOUBLE_QUOTE_STRING_LITERAL=10
COMMENT=9
@ -24,7 +24,7 @@ ACTION_CHAR_LITERAL=13
GRAMMAR=27
RULEACTIONS=75
WSCHARS=65
INITACTION=92
INITACTION=91
ALT_REWRITE=101
IMPLIES=42
RULE=72
@ -36,7 +36,7 @@ THROWS=32
CHAR_RANGE=82
INT=64
EPSILON=83
LIST=98
LIST=97
COLONCOLON=37
WSNLCHARS=18
WS=70
@ -48,10 +48,10 @@ CLOSURE=79
PARSER=25
DOLLAR=53
PROTECTED=28
ELEMENT_OPTIONS=99
ELEMENT_OPTIONS=98
NESTED_ACTION=15
FRAGMENT=23
ID=87
ID=86
TREE_BEGIN=58
LPAREN=40
AT=59
@ -61,7 +61,7 @@ TREE=26
SCOPE=21
ETC=56
COMMA=38
WILDCARD=97
WILDCARD=96
DOC_COMMENT=6
PLUS=49
REWRITE_BLOCK=77
@ -73,8 +73,8 @@ UNICODE_ESC=69
HEX_DIGIT=68
RANGE=55
TOKENS=20
GATED_SEMPRED=94
RESULT=86
RESULT=100
GATED_SEMPRED=93
BANG=47
ACTION_STRING_LITERAL=12
ROOT=52
@ -87,8 +87,8 @@ COLON=36
QUESTION=46
FINALLY=34
TEMPLATE=35
LABEL=93
SYN_SEMPRED=95
LABEL=92
SYN_SEMPRED=94
ERRCHAR=71
BLOCK=76
ASSIGN=45

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} ActionSplitter.g 2010-02-16 17:54:26
// $ANTLR ${project.version} ${buildNumber} ActionSplitter.g 2010-02-19 17:45:08
package org.antlr.v4.parse;
@ -2175,20 +2175,6 @@ public class ActionSplitter extends org.antlr.v4.runtime.Lexer {
state.failed=false;
return success;
}
public final boolean synpred12_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred12_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
boolean success = !state.failed;
input.rewind(start);
state.backtracking--;
state.failed=false;
return success;
}
public final boolean synpred17_ActionSplitter() {
state.backtracking++;
int start = input.mark();
@ -2217,6 +2203,20 @@ public class ActionSplitter extends org.antlr.v4.runtime.Lexer {
state.failed=false;
return success;
}
public final boolean synpred12_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred12_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
boolean success = !state.failed;
input.rewind(start);
state.backtracking--;
state.failed=false;
return success;
}
public final boolean synpred9_ActionSplitter() {
state.backtracking++;
int start = input.mark();
@ -2399,11 +2399,11 @@ public class ActionSplitter extends org.antlr.v4.runtime.Lexer {
state.failed=false;
return success;
}
public final boolean synpred15_ActionSplitter() {
public final boolean synpred3_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred15_ActionSplitter_fragment(); // can never throw exception
synpred3_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
@ -2413,11 +2413,11 @@ public class ActionSplitter extends org.antlr.v4.runtime.Lexer {
state.failed=false;
return success;
}
public final boolean synpred3_ActionSplitter() {
public final boolean synpred15_ActionSplitter() {
state.backtracking++;
int start = input.mark();
try {
synpred3_ActionSplitter_fragment(); // can never throw exception
synpred15_ActionSplitter_fragment(); // can never throw exception
} catch (RecognitionException re) {
System.err.println("impossible: "+re);
}
@ -2495,17 +2495,17 @@ public class ActionSplitter extends org.antlr.v4.runtime.Lexer {
static final String DFA29_eofS =
"\31\uffff";
static final String DFA29_minS =
"\1\0\1\uffff\1\0\6\uffff\1\0\2\uffff\1\0\1\uffff\1\0\12\uffff";
"\1\0\1\uffff\1\0\12\uffff\1\0\2\uffff\1\0\6\uffff\1\0\1\uffff";
static final String DFA29_maxS =
"\1\uffff\1\uffff\1\0\6\uffff\1\0\2\uffff\1\0\1\uffff\1\0\12\uffff";
"\1\uffff\1\uffff\1\0\12\uffff\1\0\2\uffff\1\0\6\uffff\1\0\1\uffff";
static final String DFA29_acceptS =
"\1\uffff\1\24\1\uffff\1\16\1\17\1\20\1\21\1\22\1\23\1\uffff\1\1"+
"\1\2\1\uffff\1\3\1\uffff\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14"+
"\1\15";
"\1\uffff\1\24\1\uffff\1\4\1\5\1\6\1\7\1\10\1\11\1\12\1\13\1\14\1"+
"\15\1\uffff\1\1\1\2\1\uffff\1\16\1\17\1\20\1\21\1\22\1\23\1\uffff"+
"\1\3";
static final String DFA29_specialS =
"\1\0\1\uffff\1\1\6\uffff\1\2\2\uffff\1\3\1\uffff\1\4\12\uffff}>";
"\1\0\1\uffff\1\1\12\uffff\1\2\2\uffff\1\3\6\uffff\1\4\1\uffff}>";
static final String[] DFA29_transitionS = {
"\44\1\1\16\1\2\11\1\1\11\54\1\1\14\uffa3\1",
"\44\1\1\2\1\20\11\1\1\15\54\1\1\27\uffa3\1",
"",
"\1\uffff",
"",
@ -2514,21 +2514,21 @@ public class ActionSplitter extends org.antlr.v4.runtime.Lexer {
"",
"",
"",
"",
"",
"",
"",
"\1\uffff",
"",
"",
"\1\uffff",
"",
"",
"",
"",
"",
"",
"\1\uffff",
"",
"",
"",
"",
"",
"",
"",
"",
"",
""
};
@ -2574,13 +2574,13 @@ public class ActionSplitter extends org.antlr.v4.runtime.Lexer {
s = -1;
if ( ((LA29_0>='\u0000' && LA29_0<='#')||(LA29_0>='&' && LA29_0<='.')||(LA29_0>='0' && LA29_0<='[')||(LA29_0>=']' && LA29_0<='\uFFFF')) ) {s = 1;}
else if ( (LA29_0=='%') ) {s = 2;}
else if ( (LA29_0=='$') ) {s = 2;}
else if ( (LA29_0=='/') ) {s = 9;}
else if ( (LA29_0=='/') ) {s = 13;}
else if ( (LA29_0=='\\') ) {s = 12;}
else if ( (LA29_0=='%') ) {s = 16;}
else if ( (LA29_0=='$') ) {s = 14;}
else if ( (LA29_0=='\\') ) {s = 23;}
if ( s>=0 ) return s;
break;
@ -2591,83 +2591,83 @@ public class ActionSplitter extends org.antlr.v4.runtime.Lexer {
int index29_2 = input.index();
input.rewind();
s = -1;
if ( (synpred14_ActionSplitter()) ) {s = 3;}
if ( (synpred4_ActionSplitter()) ) {s = 3;}
else if ( (synpred15_ActionSplitter()) ) {s = 4;}
else if ( (synpred5_ActionSplitter()) ) {s = 4;}
else if ( (synpred16_ActionSplitter()) ) {s = 5;}
else if ( (synpred6_ActionSplitter()) ) {s = 5;}
else if ( (synpred17_ActionSplitter()) ) {s = 6;}
else if ( (synpred7_ActionSplitter()) ) {s = 6;}
else if ( (synpred18_ActionSplitter()) ) {s = 7;}
else if ( (synpred8_ActionSplitter()) ) {s = 7;}
else if ( (synpred19_ActionSplitter()) ) {s = 8;}
else if ( (synpred9_ActionSplitter()) ) {s = 8;}
else if ( (synpred10_ActionSplitter()) ) {s = 9;}
else if ( (synpred11_ActionSplitter()) ) {s = 10;}
else if ( (synpred12_ActionSplitter()) ) {s = 11;}
else if ( (synpred13_ActionSplitter()) ) {s = 12;}
input.seek(index29_2);
if ( s>=0 ) return s;
break;
case 2 :
int LA29_9 = input.LA(1);
int LA29_13 = input.LA(1);
int index29_9 = input.index();
int index29_13 = input.index();
input.rewind();
s = -1;
if ( (synpred1_ActionSplitter()) ) {s = 10;}
if ( (synpred1_ActionSplitter()) ) {s = 14;}
else if ( (synpred2_ActionSplitter()) ) {s = 11;}
else if ( (synpred2_ActionSplitter()) ) {s = 15;}
else if ( (true) ) {s = 1;}
input.seek(index29_9);
input.seek(index29_13);
if ( s>=0 ) return s;
break;
case 3 :
int LA29_12 = input.LA(1);
int LA29_16 = input.LA(1);
int index29_12 = input.index();
int index29_16 = input.index();
input.rewind();
s = -1;
if ( (synpred3_ActionSplitter()) ) {s = 13;}
if ( (synpred14_ActionSplitter()) ) {s = 17;}
else if ( (synpred15_ActionSplitter()) ) {s = 18;}
else if ( (synpred16_ActionSplitter()) ) {s = 19;}
else if ( (synpred17_ActionSplitter()) ) {s = 20;}
else if ( (synpred18_ActionSplitter()) ) {s = 21;}
else if ( (synpred19_ActionSplitter()) ) {s = 22;}
input.seek(index29_16);
if ( s>=0 ) return s;
break;
case 4 :
int LA29_23 = input.LA(1);
int index29_23 = input.index();
input.rewind();
s = -1;
if ( (synpred3_ActionSplitter()) ) {s = 24;}
else if ( (true) ) {s = 1;}
input.seek(index29_12);
if ( s>=0 ) return s;
break;
case 4 :
int LA29_14 = input.LA(1);
int index29_14 = input.index();
input.rewind();
s = -1;
if ( (synpred4_ActionSplitter()) ) {s = 15;}
else if ( (synpred5_ActionSplitter()) ) {s = 16;}
else if ( (synpred6_ActionSplitter()) ) {s = 17;}
else if ( (synpred7_ActionSplitter()) ) {s = 18;}
else if ( (synpred8_ActionSplitter()) ) {s = 19;}
else if ( (synpred9_ActionSplitter()) ) {s = 20;}
else if ( (synpred10_ActionSplitter()) ) {s = 21;}
else if ( (synpred11_ActionSplitter()) ) {s = 22;}
else if ( (synpred12_ActionSplitter()) ) {s = 23;}
else if ( (synpred13_ActionSplitter()) ) {s = 24;}
input.seek(index29_14);
input.seek(index29_23);
if ( s>=0 ) return s;
break;
}

View File

@ -0,0 +1,7 @@
package org.antlr.v4.parse;
/** Used to throw us out of deeply nested element back to end of a rule's
* alt list. Note it's not under RecognitionException.
*/
public class ResyncToEndOfRuleBlock extends RuntimeException {
}

View File

@ -0,0 +1,17 @@
package org.antlr.v4.parse;
import org.antlr.runtime.IntStream;
import org.antlr.runtime.RecognitionException;
/** */
public class v4ParserException extends RecognitionException {
public String msg;
/** Used for remote debugger deserialization */
public v4ParserException() {;}
public v4ParserException(String msg, IntStream input) {
super(input);
this.msg = msg;
}
}

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} BasicSemanticTriggers.g 2010-02-17 12:27:38
// $ANTLR ${project.version} ${buildNumber} BasicSemanticTriggers.g 2010-02-19 17:45:09
/*
[The "BSD license"]
@ -40,15 +40,15 @@ import java.util.List;
*/
public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter {
public static final String[] tokenNames = new String[] {
"<invalid>", "<EOR>", "<DOWN>", "<UP>", "SEMPRED", "FORCED_ACTION", "DOC_COMMENT", "SRC", "NLCHARS", "COMMENT", "DOUBLE_QUOTE_STRING_LITERAL", "DOUBLE_ANGLE_STRING_LITERAL", "ACTION_STRING_LITERAL", "ACTION_CHAR_LITERAL", "ARG_ACTION", "NESTED_ACTION", "ACTION", "ACTION_ESC", "WSNLCHARS", "OPTIONS", "TOKENS", "SCOPE", "IMPORT", "FRAGMENT", "LEXER", "PARSER", "TREE", "GRAMMAR", "PROTECTED", "PUBLIC", "PRIVATE", "RETURNS", "THROWS", "CATCH", "FINALLY", "TEMPLATE", "COLON", "COLONCOLON", "COMMA", "SEMI", "LPAREN", "RPAREN", "IMPLIES", "LT", "GT", "ASSIGN", "QUESTION", "BANG", "STAR", "PLUS", "PLUS_ASSIGN", "OR", "ROOT", "DOLLAR", "DOT", "RANGE", "ETC", "RARROW", "TREE_BEGIN", "AT", "NOT", "RBRACE", "TOKEN_REF", "RULE_REF", "INT", "WSCHARS", "ESC_SEQ", "STRING_LITERAL", "HEX_DIGIT", "UNICODE_ESC", "WS", "ERRCHAR", "RULE", "RULES", "RULEMODIFIERS", "RULEACTIONS", "BLOCK", "REWRITE_BLOCK", "OPTIONAL", "CLOSURE", "POSITIVE_CLOSURE", "SYNPRED", "CHAR_RANGE", "EPSILON", "ALT", "ALTLIST", "RESULT", "ID", "ARG", "ARGLIST", "RET", "COMBINED", "INITACTION", "LABEL", "GATED_SEMPRED", "SYN_SEMPRED", "BACKTRACK_SEMPRED", "WILDCARD", "LIST", "ELEMENT_OPTIONS", "ST_RESULT", "ALT_REWRITE"
"<invalid>", "<EOR>", "<DOWN>", "<UP>", "SEMPRED", "FORCED_ACTION", "DOC_COMMENT", "SRC", "NLCHARS", "COMMENT", "DOUBLE_QUOTE_STRING_LITERAL", "DOUBLE_ANGLE_STRING_LITERAL", "ACTION_STRING_LITERAL", "ACTION_CHAR_LITERAL", "ARG_ACTION", "NESTED_ACTION", "ACTION", "ACTION_ESC", "WSNLCHARS", "OPTIONS", "TOKENS", "SCOPE", "IMPORT", "FRAGMENT", "LEXER", "PARSER", "TREE", "GRAMMAR", "PROTECTED", "PUBLIC", "PRIVATE", "RETURNS", "THROWS", "CATCH", "FINALLY", "TEMPLATE", "COLON", "COLONCOLON", "COMMA", "SEMI", "LPAREN", "RPAREN", "IMPLIES", "LT", "GT", "ASSIGN", "QUESTION", "BANG", "STAR", "PLUS", "PLUS_ASSIGN", "OR", "ROOT", "DOLLAR", "DOT", "RANGE", "ETC", "RARROW", "TREE_BEGIN", "AT", "NOT", "RBRACE", "TOKEN_REF", "RULE_REF", "INT", "WSCHARS", "ESC_SEQ", "STRING_LITERAL", "HEX_DIGIT", "UNICODE_ESC", "WS", "ERRCHAR", "RULE", "RULES", "RULEMODIFIERS", "RULEACTIONS", "BLOCK", "REWRITE_BLOCK", "OPTIONAL", "CLOSURE", "POSITIVE_CLOSURE", "SYNPRED", "CHAR_RANGE", "EPSILON", "ALT", "ALTLIST", "ID", "ARG", "ARGLIST", "RET", "COMBINED", "INITACTION", "LABEL", "GATED_SEMPRED", "SYN_SEMPRED", "BACKTRACK_SEMPRED", "WILDCARD", "LIST", "ELEMENT_OPTIONS", "ST_RESULT", "RESULT", "ALT_REWRITE"
};
public static final int COMBINED=91;
public static final int COMBINED=90;
public static final int LT=43;
public static final int STAR=48;
public static final int BACKTRACK_SEMPRED=96;
public static final int BACKTRACK_SEMPRED=95;
public static final int DOUBLE_ANGLE_STRING_LITERAL=11;
public static final int FORCED_ACTION=5;
public static final int ARGLIST=89;
public static final int ARGLIST=88;
public static final int ALTLIST=85;
public static final int NOT=60;
public static final int EOF=-1;
@ -56,12 +56,12 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final int ACTION=16;
public static final int TOKEN_REF=62;
public static final int RULEMODIFIERS=74;
public static final int ST_RESULT=100;
public static final int ST_RESULT=99;
public static final int RPAREN=41;
public static final int RET=90;
public static final int RET=89;
public static final int IMPORT=22;
public static final int STRING_LITERAL=67;
public static final int ARG=88;
public static final int ARG=87;
public static final int ARG_ACTION=14;
public static final int DOUBLE_QUOTE_STRING_LITERAL=10;
public static final int COMMENT=9;
@ -69,7 +69,7 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final int GRAMMAR=27;
public static final int RULEACTIONS=75;
public static final int WSCHARS=65;
public static final int INITACTION=92;
public static final int INITACTION=91;
public static final int ALT_REWRITE=101;
public static final int IMPLIES=42;
public static final int RULE=72;
@ -81,7 +81,7 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final int CHAR_RANGE=82;
public static final int INT=64;
public static final int EPSILON=83;
public static final int LIST=98;
public static final int LIST=97;
public static final int COLONCOLON=37;
public static final int WSNLCHARS=18;
public static final int WS=70;
@ -93,10 +93,10 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final int PARSER=25;
public static final int DOLLAR=53;
public static final int PROTECTED=28;
public static final int ELEMENT_OPTIONS=99;
public static final int ELEMENT_OPTIONS=98;
public static final int NESTED_ACTION=15;
public static final int FRAGMENT=23;
public static final int ID=87;
public static final int ID=86;
public static final int TREE_BEGIN=58;
public static final int LPAREN=40;
public static final int AT=59;
@ -106,7 +106,7 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final int SCOPE=21;
public static final int ETC=56;
public static final int COMMA=38;
public static final int WILDCARD=97;
public static final int WILDCARD=96;
public static final int DOC_COMMENT=6;
public static final int PLUS=49;
public static final int REWRITE_BLOCK=77;
@ -118,8 +118,8 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final int HEX_DIGIT=68;
public static final int RANGE=55;
public static final int TOKENS=20;
public static final int GATED_SEMPRED=94;
public static final int RESULT=86;
public static final int RESULT=100;
public static final int GATED_SEMPRED=93;
public static final int BANG=47;
public static final int ACTION_STRING_LITERAL=12;
public static final int ROOT=52;
@ -132,8 +132,8 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final int QUESTION=46;
public static final int FINALLY=34;
public static final int TEMPLATE=35;
public static final int LABEL=93;
public static final int SYN_SEMPRED=95;
public static final int LABEL=92;
public static final int SYN_SEMPRED=94;
public static final int ERRCHAR=71;
public static final int BLOCK=76;
public static final int ASSIGN=45;
@ -1423,7 +1423,7 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
// BasicSemanticTriggers.g:228:2: ( ( RESULT | ST_RESULT ) )
// BasicSemanticTriggers.g:228:4: ( RESULT | ST_RESULT )
{
if ( input.LA(1)==RESULT||input.LA(1)==ST_RESULT ) {
if ( (input.LA(1)>=ST_RESULT && input.LA(1)<=RESULT) ) {
input.consume();
state.errorRecovery=false;state.failed=false;
}
@ -1520,22 +1520,22 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
static final String DFA1_eofS =
"\14\uffff";
static final String DFA1_minS =
"\1\33\2\uffff\1\2\2\uffff\1\127\1\60\1\3\1\uffff\1\0\1\uffff";
"\1\33\2\uffff\1\2\2\uffff\1\126\1\60\1\3\1\uffff\1\0\1\uffff";
static final String DFA1_maxS =
"\1\144\2\uffff\1\2\2\uffff\2\127\1\3\1\uffff\1\0\1\uffff";
"\1\144\2\uffff\1\2\2\uffff\2\126\1\3\1\uffff\1\0\1\uffff";
static final String DFA1_acceptS =
"\1\uffff\1\1\1\2\1\uffff\1\4\1\6\3\uffff\1\3\1\uffff\1\5";
static final String DFA1_specialS =
"\12\uffff\1\0\1\uffff}>";
static final String[] DFA1_transitionS = {
"\1\1\21\uffff\1\3\32\uffff\1\4\1\2\14\uffff\1\5\15\uffff\1\5",
"\1\1\21\uffff\1\3\32\uffff\1\4\1\2\31\uffff\2\5",
"",
"",
"\1\6",
"",
"",
"\1\7",
"\1\11\17\uffff\1\11\2\uffff\1\10\23\uffff\1\11",
"\1\11\17\uffff\1\11\2\uffff\1\10\22\uffff\1\11",
"\1\12",
"",
"\1\uffff",
@ -1624,15 +1624,15 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final BitSet FOLLOW_GRAMMAR_in_checkGrammarOptions230 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_OPTIONS_in_prequelConstructs253 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_IMPORT_in_prequelConstructs266 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_delegateGrammar_in_prequelConstructs268 = new BitSet(new long[]{0x0000200000000008L,0x0000000000800000L});
public static final BitSet FOLLOW_delegateGrammar_in_prequelConstructs268 = new BitSet(new long[]{0x0000200000000008L,0x0000000000400000L});
public static final BitSet FOLLOW_TOKENS_in_prequelConstructs279 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ASSIGN_in_delegateGrammar312 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_delegateGrammar314 = new BitSet(new long[]{0x0000000000000000L,0x0000000000800000L});
public static final BitSet FOLLOW_ID_in_delegateGrammar314 = new BitSet(new long[]{0x0000000000000000L,0x0000000000400000L});
public static final BitSet FOLLOW_ID_in_delegateGrammar318 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_ID_in_delegateGrammar332 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_RULES_in_rules359 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_ASSIGN_in_option380 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_option384 = new BitSet(new long[]{0x0001000000000000L,0x0000000000800009L});
public static final BitSet FOLLOW_ID_in_option384 = new BitSet(new long[]{0x0001000000000000L,0x0000000000400009L});
public static final BitSet FOLLOW_optionValue_in_option386 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_set_in_optionValue0 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_RULE_in_rule468 = new BitSet(new long[]{0x0000000000000004L});
@ -1645,7 +1645,7 @@ public class BasicSemanticTriggers extends org.antlr.v4.runtime.tree.TreeFilter
public static final BitSet FOLLOW_ARG_ACTION_in_tokenRefWithArgs545 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_ELEMENT_OPTIONS_in_elementOption575 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ASSIGN_in_elementOption586 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_elementOption590 = new BitSet(new long[]{0x0000000000000000L,0x0000000000800000L});
public static final BitSet FOLLOW_ID_in_elementOption590 = new BitSet(new long[]{0x0000000000000000L,0x0000000000400000L});
public static final BitSet FOLLOW_ID_in_elementOption594 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_ASSIGN_in_elementOption608 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_elementOption612 = new BitSet(new long[]{0x0000000000000000L,0x0000000000000008L});

View File

@ -1,22 +1,22 @@
COMBINED=91
COMBINED=90
LT=43
STAR=48
BACKTRACK_SEMPRED=96
BACKTRACK_SEMPRED=95
DOUBLE_ANGLE_STRING_LITERAL=11
FORCED_ACTION=5
ARGLIST=89
ARGLIST=88
ALTLIST=85
NOT=60
SEMPRED=4
ACTION=16
TOKEN_REF=62
RULEMODIFIERS=74
ST_RESULT=100
ST_RESULT=99
RPAREN=41
RET=90
RET=89
IMPORT=22
STRING_LITERAL=67
ARG=88
ARG=87
ARG_ACTION=14
DOUBLE_QUOTE_STRING_LITERAL=10
COMMENT=9
@ -24,7 +24,7 @@ ACTION_CHAR_LITERAL=13
GRAMMAR=27
RULEACTIONS=75
WSCHARS=65
INITACTION=92
INITACTION=91
ALT_REWRITE=101
IMPLIES=42
RULE=72
@ -36,7 +36,7 @@ THROWS=32
CHAR_RANGE=82
INT=64
EPSILON=83
LIST=98
LIST=97
COLONCOLON=37
WSNLCHARS=18
WS=70
@ -48,10 +48,10 @@ CLOSURE=79
PARSER=25
DOLLAR=53
PROTECTED=28
ELEMENT_OPTIONS=99
ELEMENT_OPTIONS=98
NESTED_ACTION=15
FRAGMENT=23
ID=87
ID=86
TREE_BEGIN=58
LPAREN=40
AT=59
@ -61,7 +61,7 @@ TREE=26
SCOPE=21
ETC=56
COMMA=38
WILDCARD=97
WILDCARD=96
DOC_COMMENT=6
PLUS=49
REWRITE_BLOCK=77
@ -73,8 +73,8 @@ UNICODE_ESC=69
HEX_DIGIT=68
RANGE=55
TOKENS=20
GATED_SEMPRED=94
RESULT=86
RESULT=100
GATED_SEMPRED=93
BANG=47
ACTION_STRING_LITERAL=12
ROOT=52
@ -87,8 +87,8 @@ COLON=36
QUESTION=46
FINALLY=34
TEMPLATE=35
LABEL=93
SYN_SEMPRED=95
LABEL=92
SYN_SEMPRED=94
ERRCHAR=71
BLOCK=76
ASSIGN=45

View File

@ -1,4 +1,4 @@
// $ANTLR ${project.version} ${buildNumber} CollectSymbols.g 2010-02-17 12:27:38
// $ANTLR ${project.version} ${buildNumber} CollectSymbols.g 2010-02-19 17:45:09
/*
[The "BSD license"]
@ -40,15 +40,15 @@ import java.util.List;
*/
public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final String[] tokenNames = new String[] {
"<invalid>", "<EOR>", "<DOWN>", "<UP>", "SEMPRED", "FORCED_ACTION", "DOC_COMMENT", "SRC", "NLCHARS", "COMMENT", "DOUBLE_QUOTE_STRING_LITERAL", "DOUBLE_ANGLE_STRING_LITERAL", "ACTION_STRING_LITERAL", "ACTION_CHAR_LITERAL", "ARG_ACTION", "NESTED_ACTION", "ACTION", "ACTION_ESC", "WSNLCHARS", "OPTIONS", "TOKENS", "SCOPE", "IMPORT", "FRAGMENT", "LEXER", "PARSER", "TREE", "GRAMMAR", "PROTECTED", "PUBLIC", "PRIVATE", "RETURNS", "THROWS", "CATCH", "FINALLY", "TEMPLATE", "COLON", "COLONCOLON", "COMMA", "SEMI", "LPAREN", "RPAREN", "IMPLIES", "LT", "GT", "ASSIGN", "QUESTION", "BANG", "STAR", "PLUS", "PLUS_ASSIGN", "OR", "ROOT", "DOLLAR", "DOT", "RANGE", "ETC", "RARROW", "TREE_BEGIN", "AT", "NOT", "RBRACE", "TOKEN_REF", "RULE_REF", "INT", "WSCHARS", "ESC_SEQ", "STRING_LITERAL", "HEX_DIGIT", "UNICODE_ESC", "WS", "ERRCHAR", "RULE", "RULES", "RULEMODIFIERS", "RULEACTIONS", "BLOCK", "REWRITE_BLOCK", "OPTIONAL", "CLOSURE", "POSITIVE_CLOSURE", "SYNPRED", "CHAR_RANGE", "EPSILON", "ALT", "ALTLIST", "RESULT", "ID", "ARG", "ARGLIST", "RET", "COMBINED", "INITACTION", "LABEL", "GATED_SEMPRED", "SYN_SEMPRED", "BACKTRACK_SEMPRED", "WILDCARD", "LIST", "ELEMENT_OPTIONS", "ST_RESULT", "ALT_REWRITE"
"<invalid>", "<EOR>", "<DOWN>", "<UP>", "SEMPRED", "FORCED_ACTION", "DOC_COMMENT", "SRC", "NLCHARS", "COMMENT", "DOUBLE_QUOTE_STRING_LITERAL", "DOUBLE_ANGLE_STRING_LITERAL", "ACTION_STRING_LITERAL", "ACTION_CHAR_LITERAL", "ARG_ACTION", "NESTED_ACTION", "ACTION", "ACTION_ESC", "WSNLCHARS", "OPTIONS", "TOKENS", "SCOPE", "IMPORT", "FRAGMENT", "LEXER", "PARSER", "TREE", "GRAMMAR", "PROTECTED", "PUBLIC", "PRIVATE", "RETURNS", "THROWS", "CATCH", "FINALLY", "TEMPLATE", "COLON", "COLONCOLON", "COMMA", "SEMI", "LPAREN", "RPAREN", "IMPLIES", "LT", "GT", "ASSIGN", "QUESTION", "BANG", "STAR", "PLUS", "PLUS_ASSIGN", "OR", "ROOT", "DOLLAR", "DOT", "RANGE", "ETC", "RARROW", "TREE_BEGIN", "AT", "NOT", "RBRACE", "TOKEN_REF", "RULE_REF", "INT", "WSCHARS", "ESC_SEQ", "STRING_LITERAL", "HEX_DIGIT", "UNICODE_ESC", "WS", "ERRCHAR", "RULE", "RULES", "RULEMODIFIERS", "RULEACTIONS", "BLOCK", "REWRITE_BLOCK", "OPTIONAL", "CLOSURE", "POSITIVE_CLOSURE", "SYNPRED", "CHAR_RANGE", "EPSILON", "ALT", "ALTLIST", "ID", "ARG", "ARGLIST", "RET", "COMBINED", "INITACTION", "LABEL", "GATED_SEMPRED", "SYN_SEMPRED", "BACKTRACK_SEMPRED", "WILDCARD", "LIST", "ELEMENT_OPTIONS", "ST_RESULT", "RESULT", "ALT_REWRITE"
};
public static final int COMBINED=91;
public static final int COMBINED=90;
public static final int LT=43;
public static final int STAR=48;
public static final int BACKTRACK_SEMPRED=96;
public static final int BACKTRACK_SEMPRED=95;
public static final int DOUBLE_ANGLE_STRING_LITERAL=11;
public static final int FORCED_ACTION=5;
public static final int ARGLIST=89;
public static final int ARGLIST=88;
public static final int ALTLIST=85;
public static final int NOT=60;
public static final int EOF=-1;
@ -56,12 +56,12 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final int ACTION=16;
public static final int TOKEN_REF=62;
public static final int RULEMODIFIERS=74;
public static final int ST_RESULT=100;
public static final int ST_RESULT=99;
public static final int RPAREN=41;
public static final int RET=90;
public static final int RET=89;
public static final int IMPORT=22;
public static final int STRING_LITERAL=67;
public static final int ARG=88;
public static final int ARG=87;
public static final int ARG_ACTION=14;
public static final int DOUBLE_QUOTE_STRING_LITERAL=10;
public static final int COMMENT=9;
@ -69,7 +69,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final int GRAMMAR=27;
public static final int RULEACTIONS=75;
public static final int WSCHARS=65;
public static final int INITACTION=92;
public static final int INITACTION=91;
public static final int ALT_REWRITE=101;
public static final int IMPLIES=42;
public static final int RULE=72;
@ -81,7 +81,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final int CHAR_RANGE=82;
public static final int INT=64;
public static final int EPSILON=83;
public static final int LIST=98;
public static final int LIST=97;
public static final int COLONCOLON=37;
public static final int WSNLCHARS=18;
public static final int WS=70;
@ -93,10 +93,10 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final int PARSER=25;
public static final int DOLLAR=53;
public static final int PROTECTED=28;
public static final int ELEMENT_OPTIONS=99;
public static final int ELEMENT_OPTIONS=98;
public static final int NESTED_ACTION=15;
public static final int FRAGMENT=23;
public static final int ID=87;
public static final int ID=86;
public static final int TREE_BEGIN=58;
public static final int LPAREN=40;
public static final int AT=59;
@ -106,7 +106,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final int SCOPE=21;
public static final int ETC=56;
public static final int COMMA=38;
public static final int WILDCARD=97;
public static final int WILDCARD=96;
public static final int DOC_COMMENT=6;
public static final int PLUS=49;
public static final int REWRITE_BLOCK=77;
@ -118,8 +118,8 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final int HEX_DIGIT=68;
public static final int RANGE=55;
public static final int TOKENS=20;
public static final int GATED_SEMPRED=94;
public static final int RESULT=86;
public static final int RESULT=100;
public static final int GATED_SEMPRED=93;
public static final int BANG=47;
public static final int ACTION_STRING_LITERAL=12;
public static final int ROOT=52;
@ -132,8 +132,8 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final int QUESTION=46;
public static final int FINALLY=34;
public static final int TEMPLATE=35;
public static final int LABEL=93;
public static final int SYN_SEMPRED=95;
public static final int LABEL=92;
public static final int SYN_SEMPRED=94;
public static final int ERRCHAR=71;
public static final int BLOCK=76;
public static final int ASSIGN=45;
@ -1399,10 +1399,10 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
static final String DFA1_eofS =
"\41\uffff";
static final String DFA1_minS =
"\1\16\3\2\4\uffff\3\0\6\uffff\1\20\2\127\2\uffff\1\3\1\uffff\1\20"+
"\1\16\3\2\4\uffff\3\0\6\uffff\1\20\2\126\2\uffff\1\3\1\uffff\1\20"+
"\1\4\1\uffff\1\3\1\uffff\1\2\2\0\1\uffff";
static final String DFA1_maxS =
"\1\145\3\2\4\uffff\3\0\6\uffff\3\127\2\uffff\1\127\1\uffff\1\127"+
"\1\145\3\2\4\uffff\3\0\6\uffff\3\126\2\uffff\1\126\1\uffff\1\126"+
"\1\145\1\uffff\1\3\1\uffff\1\3\2\0\1\uffff";
static final String DFA1_acceptS =
"\4\uffff\1\3\1\4\1\5\1\6\3\uffff\1\12\1\14\1\15\1\16\1\17\1\20\3"+
@ -1413,8 +1413,8 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
static final String[] DFA1_transitionS = {
"\1\6\1\uffff\1\16\4\uffff\1\1\11\uffff\1\7\1\uffff\1\20\1\17"+
"\12\uffff\1\3\4\uffff\1\14\10\uffff\1\2\2\uffff\1\12\1\10\3"+
"\uffff\1\11\4\uffff\1\5\13\uffff\1\15\2\uffff\1\4\5\uffff\1"+
"\13\7\uffff\1\15",
"\uffff\1\11\4\uffff\1\5\13\uffff\1\15\1\uffff\1\4\5\uffff\1"+
"\13\10\uffff\1\15",
"\1\21",
"\1\22",
"\1\23",
@ -1431,14 +1431,14 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
"",
"",
"",
"\1\27\106\uffff\1\26",
"\1\27\105\uffff\1\26",
"\1\30",
"\1\31",
"",
"",
"\1\27\14\uffff\1\32\106\uffff\1\27",
"\1\27\14\uffff\1\32\105\uffff\1\27",
"",
"\1\33\106\uffff\1\34",
"\1\33\105\uffff\1\34",
"\77\14\1\35\42\14",
"",
"\1\36",
@ -1591,7 +1591,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final BitSet FOLLOW_ID_in_globalScope257 = new BitSet(new long[]{0x0000000000010000L});
public static final BitSet FOLLOW_ACTION_in_globalScope259 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_AT_in_globalNamedAction278 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_globalNamedAction280 = new BitSet(new long[]{0x0000000000000000L,0x0000000000800000L});
public static final BitSet FOLLOW_ID_in_globalNamedAction280 = new BitSet(new long[]{0x0000000000000000L,0x0000000000400000L});
public static final BitSet FOLLOW_ID_in_globalNamedAction283 = new BitSet(new long[]{0x0000000000010000L});
public static final BitSet FOLLOW_ACTION_in_globalNamedAction285 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_ASSIGN_in_tokensSection308 = new BitSet(new long[]{0x0000000000000004L});
@ -1617,7 +1617,7 @@ public class CollectSymbols extends org.antlr.v4.runtime.tree.TreeFilter {
public static final BitSet FOLLOW_SCOPE_in_ruleScopeSpec543 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ACTION_in_ruleScopeSpec545 = new BitSet(new long[]{0x0000000000000008L});
public static final BitSet FOLLOW_SCOPE_in_ruleScopeSpec558 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_ruleScopeSpec562 = new BitSet(new long[]{0x0000000000000008L,0x0000000000800000L});
public static final BitSet FOLLOW_ID_in_ruleScopeSpec562 = new BitSet(new long[]{0x0000000000000008L,0x0000000000400000L});
public static final BitSet FOLLOW_set_in_rewriteElement590 = new BitSet(new long[]{0x0000000000000002L});
public static final BitSet FOLLOW_ASSIGN_in_labeledElement626 = new BitSet(new long[]{0x0000000000000004L});
public static final BitSet FOLLOW_ID_in_labeledElement630 = new BitSet(new long[]{0xFFFFFFFFFFFFFFF0L,0x0000003FFFFFFFFFL});

View File

@ -1,22 +1,22 @@
COMBINED=91
COMBINED=90
LT=43
STAR=48
BACKTRACK_SEMPRED=96
BACKTRACK_SEMPRED=95
DOUBLE_ANGLE_STRING_LITERAL=11
FORCED_ACTION=5
ARGLIST=89
ARGLIST=88
ALTLIST=85
NOT=60
SEMPRED=4
ACTION=16
TOKEN_REF=62
RULEMODIFIERS=74
ST_RESULT=100
ST_RESULT=99
RPAREN=41
RET=90
RET=89
IMPORT=22
STRING_LITERAL=67
ARG=88
ARG=87
ARG_ACTION=14
DOUBLE_QUOTE_STRING_LITERAL=10
COMMENT=9
@ -24,7 +24,7 @@ ACTION_CHAR_LITERAL=13
GRAMMAR=27
RULEACTIONS=75
WSCHARS=65
INITACTION=92
INITACTION=91
ALT_REWRITE=101
IMPLIES=42
RULE=72
@ -36,7 +36,7 @@ THROWS=32
CHAR_RANGE=82
INT=64
EPSILON=83
LIST=98
LIST=97
COLONCOLON=37
WSNLCHARS=18
WS=70
@ -48,10 +48,10 @@ CLOSURE=79
PARSER=25
DOLLAR=53
PROTECTED=28
ELEMENT_OPTIONS=99
ELEMENT_OPTIONS=98
NESTED_ACTION=15
FRAGMENT=23
ID=87
ID=86
TREE_BEGIN=58
LPAREN=40
AT=59
@ -61,7 +61,7 @@ TREE=26
SCOPE=21
ETC=56
COMMA=38
WILDCARD=97
WILDCARD=96
DOC_COMMENT=6
PLUS=49
REWRITE_BLOCK=77
@ -73,8 +73,8 @@ UNICODE_ESC=69
HEX_DIGIT=68
RANGE=55
TOKENS=20
GATED_SEMPRED=94
RESULT=86
RESULT=100
GATED_SEMPRED=93
BANG=47
ACTION_STRING_LITERAL=12
ROOT=52
@ -87,8 +87,8 @@ COLON=36
QUESTION=46
FINALLY=34
TEMPLATE=35
LABEL=93
SYN_SEMPRED=95
LABEL=92
SYN_SEMPRED=94
ERRCHAR=71
BLOCK=76
ASSIGN=45

View File

@ -2,6 +2,7 @@ package org.antlr.v4.semantics;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.BufferedTreeNodeStream;
import org.antlr.v4.analysis.Label;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.parse.ASTVerifier;
import org.antlr.v4.parse.GrammarASTAdaptor;
@ -12,6 +13,8 @@ import java.util.List;
/** */
public class SemanticPipeline {
public void process(Grammar g) {
if ( g.ast==null ) return;
// VALIDATE AST STRUCTURE
// use buffered node stream as we will look around in stream
// to give good error messages.
@ -23,6 +26,7 @@ public class SemanticPipeline {
try {walker.grammarSpec();}
catch (RecognitionException re) {
ErrorManager.internalError("bad grammar AST structure", re);
return; // don't process; will get internal errors
}
// DO BASIC / EASY SEMANTIC CHECKS
@ -66,6 +70,11 @@ public class SemanticPipeline {
AttributeChecks.checkAllAttributeExpressions(g);
// ASSIGN TOKEN TYPES
//for (GrammarAST a : collector.strings) g.defineAction(a);
//for (String id : symcheck.tokenIDs) g.defineAction(a);
// TODO: move to a use-def or deadcode eliminator
checkRewriteElementsPresentOnLeftSide(g, collector.rules);
}
public void checkRuleArgs(Grammar g, List<GrammarAST> rulerefs) {
@ -111,4 +120,23 @@ public class SemanticPipeline {
}
}
}
public void checkRewriteElementsPresentOnLeftSide(Grammar g, List<Rule> rules) {
for (Rule r : rules) {
for (int a=1; a<=r.numberOfAlts; a++) {
Alternative alt = r.alt[a];
for (GrammarAST e : alt.rewriteElements) {
if ( !(alt.ruleRefs.containsKey(e.getText()) ||
g.getTokenType(e.getText())!= Label.INVALID ||
alt.labelDefs.containsKey(e.getText()) ||
e.getText().equals(r.name)) ) // $r ok in rule r
{
ErrorManager.grammarError(ErrorType.REWRITE_ELEMENT_NOT_PRESENT_ON_LHS,
g.fileName, e.token, e.getText());
}
}
}
}
}
}

View File

@ -16,7 +16,7 @@ public class SymbolChecks {
protected Grammar g;
protected CollectSymbols collector;
protected Map<String, Rule> nameToRuleMap = new HashMap<String, Rule>();
protected Set<String> tokenIDs = new HashSet<String>();
protected Set<String> tokenIDs = new HashSet<String>();
protected Set<String> globalScopeNames = new HashSet<String>();
protected Map<String, Set<String>> actionScopeToActionNames = new HashMap<String, Set<String>>();
@ -46,7 +46,7 @@ public class SymbolChecks {
//checkRuleArgs(collector.rulerefs);
checkForTokenConflicts(collector.tokenIDRefs); // sets tokenIDs
checkForLabelConflicts(collector.rules);
checkRewriteElementsPresentOnLeftSide(collector.rules);
//checkRewriteElementsPresentOnLeftSide(collector.rules); // move to after token type assignment
}
public void checkForRuleConflicts(List<Rule> rules) {
@ -77,7 +77,7 @@ public class SymbolChecks {
globalScopeNames.add(s.getName());
}
else {
Token idNode = ((GrammarAST) s.ast.getChild(0)).token;
Token idNode = ((GrammarAST) s.ast.getParent().getChild(0)).token;
ErrorManager.grammarError(ErrorType.SCOPE_REDEFINITION,
g.fileName, idNode, s.getName());
}
@ -261,20 +261,4 @@ public class SymbolChecks {
}
}
}
public void checkRewriteElementsPresentOnLeftSide(List<Rule> rules) {
for (Rule r : rules) {
for (int a=1; a<=r.numberOfAlts; a++) {
Alternative alt = r.alt[a];
for (GrammarAST e : alt.rewriteElements) {
if ( !(alt.ruleRefs.containsKey(e.getText()) ||
alt.tokenRefs.containsKey(e.getText()) ||
alt.labelDefs.containsKey(e.getText())) ) {
ErrorManager.grammarError(ErrorType.REWRITE_ELEMENT_NOT_PRESENT_ON_LHS,
g.fileName, e.token, e.getText());
}
}
}
}
}
}

View File

@ -36,10 +36,12 @@ public class Alternative implements AttributeResolver {
/** $x Attribute: rule arguments, return values, predefined rule prop.
*/
public Attribute resolveToAttribute(String x, ActionAST node) {
Attribute a = rule.args.get(x); if ( a!=null ) return a;
a = rule.retvals.get(x); if ( a!=null ) return a;
AttributeDict properties = rule.getPredefinedScope(LabelType.RULE_LABEL);
return properties.get(x);
return rule.resolveToAttribute(x, node); // reuse that code
// if ( rule.args==null ) return null;
// Attribute a = rule.args.get(x); if ( a!=null ) return a;
// a = rule.retvals.get(x); if ( a!=null ) return a;
// AttributeDict properties = rule.getPredefinedScope(LabelType.RULE_LABEL);
// return properties.get(x);
}
/** $x.y, x can be surrounding rule, token/rule/label ref. y is visible

View File

@ -1,6 +1,10 @@
package org.antlr.v4.tool;
import org.antlr.runtime.NoViableAltException;
import org.antlr.runtime.Parser;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
import org.antlr.v4.parse.v4ParserException;
import org.stringtemplate.v4.ST;
import org.stringtemplate.v4.STErrorListener;
import org.stringtemplate.v4.STGroup;
@ -166,6 +170,17 @@ public class ErrorManager {
}
public static void syntaxError(ErrorType etype,
String fileName,
Token token,
RecognitionException antlrException,
Object... args)
{
state.get().errors++;
Message msg = new GrammarSyntaxMessage(etype,fileName,token,antlrException,args);
state.get().listener.error(msg);
}
public static void internalError(String error, Throwable e) {
state.get().errors++;
StackTraceElement location = getLastNonErrorManagerCodeLocation(e);
@ -192,6 +207,30 @@ public class ErrorManager {
state.get().listener.error(new ToolMessage(errorType, args));
}
public static String getParserErrorMessage(Parser parser, RecognitionException e) {
String msg = null;
if ( e instanceof NoViableAltException) {
String t = parser.getTokenErrorDisplay(e.token);
String name = "<EOF>";
if ( e.token.getType()>=0 ) name = parser.getTokenNames()[e.token.getType()];
msg = " came as a complete surprise to me";
msg = t+msg;
// if ( t.toLowerCase().equals("'"+name.toLowerCase()+"'") ) {
// msg = t+msg;
// }
// else {
// msg = t+"<"+name+">"+msg;
// }
}
else if ( e instanceof v4ParserException) {
msg = ((v4ParserException)e).msg;
}
else {
msg = parser.getErrorMessage(e, parser.getTokenNames());
}
return msg;
}
/**
* Raise a predefined message with some number of parameters for the StringTemplate
* with error information supplied explicitly.

View File

@ -5,6 +5,7 @@ import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.ParserRuleReturnScope;
import org.antlr.runtime.RecognitionException;
import org.antlr.v4.Tool;
import org.antlr.v4.analysis.Label;
import org.antlr.v4.parse.ANTLRLexer;
import org.antlr.v4.parse.ANTLRParser;
import org.antlr.v4.parse.GrammarASTAdaptor;
@ -48,6 +49,15 @@ public class Grammar implements AttributeResolver {
public List<Grammar> importedGrammars;
public Map<String, Rule> rules = new LinkedHashMap<String, Rule>();
/** Map token like ID (but not literals like "while") to its token type */
public Map<String, Integer> tokenNameToTypeMap = new HashMap<String, Integer>();
/** Map token literals like "while" to its token type. It may be that
* WHILE="while"=35, in which case both tokenIDToTypeMap and this
* field will have entries both mapped to 35.
*/
public Map<String, Integer> stringLiteralToTypeMap = new HashMap<String, Integer>();
/** Map a name to an action.
* The code generator will use this to fill holes in the output files.
* I track the AST node for the action in case I need the line number
@ -70,19 +80,22 @@ public class Grammar implements AttributeResolver {
/** For testing */
public Grammar(String fileName, String grammarText) throws RecognitionException {
this.text = grammarText;
ANTLRStringStream in = new ANTLRStringStream(grammarText);
in.name = fileName;
ANTLRLexer lexer = new ANTLRLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ANTLRParser p = new ANTLRParser(tokens);
p.setTreeAdaptor(new GrammarASTAdaptor(in));
ParserRuleReturnScope r = p.grammarSpec();
ast = (GrammarRootAST)r.getTree();
this.name = ((GrammarAST)ast.getChild(0)).getText();
this.fileName = fileName;
this.fileName = fileName;
ANTLRStringStream in = new ANTLRStringStream(grammarText);
in.name = fileName;
ANTLRLexer lexer = new ANTLRLexer(in);
CommonTokenStream tokens = new CommonTokenStream(lexer);
ANTLRParser p = new ANTLRParser(tokens);
p.setTreeAdaptor(new GrammarASTAdaptor(in));
ParserRuleReturnScope r = p.grammarSpec();
if ( r.getTree() instanceof GrammarRootAST ) {
this.ast = (GrammarRootAST)r.getTree();
this.name = ((GrammarAST)ast.getChild(0)).getText();
}
}
public void loadImportedGrammars() {
if ( ast==null ) return;
GrammarAST i = (GrammarAST)ast.getFirstChildWithType(ANTLRParser.IMPORT);
if ( i==null ) return;
importedGrammars = new ArrayList<Grammar>();
@ -98,7 +111,9 @@ public class Grammar implements AttributeResolver {
System.out.println("import "+t.getText());
}
try {
GrammarRootAST ast = tool.load(importedGrammarName+".g");
GrammarAST root = tool.load(importedGrammarName+".g");
if ( root instanceof GrammarASTErrorNode ) return; // came back as error node
GrammarRootAST ast = (GrammarRootAST)root;
Grammar g = new Grammar(tool, ast);
g.parent = this;
importedGrammars.add(g);
@ -232,6 +247,19 @@ public class Grammar implements AttributeResolver {
return null;
}
public int getTokenType(String tokenName) {
Integer I = null;
if ( tokenName.charAt(0)=='\'') {
I = stringLiteralToTypeMap.get(tokenName);
}
else { // must be a label like ID
I = tokenNameToTypeMap.get(tokenName);
}
int i = (I!=null)?I.intValue(): Label.INVALID;
//System.out.println("grammar type "+type+" "+tokenName+"->"+i);
return i;
}
// no isolated attr at grammar action level
public Attribute resolveToAttribute(String x, ActionAST node) {
return null;

View File

@ -12,6 +12,7 @@ public class GrammarSemanticsMessage extends Message {
*/
public Token offendingToken;
/*
public GrammarSemanticsMessage(ErrorType etype,
Grammar g,
Token offendingToken,
@ -26,7 +27,7 @@ public class GrammarSemanticsMessage extends Message {
charPosition = offendingToken.getCharPositionInLine();
}
}
*/
public GrammarSemanticsMessage(ErrorType etype,
String fileName,
Token offendingToken,

View File

@ -0,0 +1,30 @@
package org.antlr.v4.tool;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.Token;
/** A problem with the syntax of your antlr grammar such as
* "The '{' came as a complete surprise to me at this point in your program"
*/
public class GrammarSyntaxMessage extends Message {
public Grammar g;
/** Most of the time, we'll have a token and so this will be set. */
public Token offendingToken;
public RecognitionException antlrException;
public GrammarSyntaxMessage(ErrorType etype,
String fileName,
Token offendingToken,
RecognitionException antlrException,
Object... args)
{
super(etype,args);
this.fileName = fileName;
this.offendingToken = offendingToken;
this.antlrException = antlrException;
if ( offendingToken!=null ) {
line = offendingToken.getLine();
charPosition = offendingToken.getCharPositionInLine();
}
}
}

View File

@ -136,11 +136,15 @@ public class Rule implements AttributeResolver {
}
/** $x Attribute: rule arguments, return values, predefined rule prop,
* or a token/rule list label.
* or a token/rule list label.
*/
public Attribute resolveToAttribute(String x, ActionAST node) {
Attribute a = args.get(x); if ( a!=null ) return a;
a = retvals.get(x); if ( a!=null ) return a;
if ( args!=null ) {
Attribute a = args.get(x); if ( a!=null ) return a;
}
if ( retvals!=null ) {
Attribute a = retvals.get(x); if ( a!=null ) return a;
}
AttributeDict properties = getPredefinedScope(LabelType.RULE_LABEL);
return properties.get(x);
}

View File

@ -418,7 +418,7 @@ public abstract class BaseTest {
return null;
}
public void testErrors(String[] pairs) {
public void testErrors(String[] pairs, boolean printTree) {
for (int i = 0; i < pairs.length; i+=2) {
String input = pairs[i];
String expect = pairs[i+1];
@ -427,14 +427,19 @@ public abstract class BaseTest {
try {
String[] lines = input.split("\n");
String fileName = "<string>";
int grIndex = lines[0].indexOf("grammar");
if ( grIndex>=0 ) {
int grIndex = lines[0].lastIndexOf("grammar");
int semi = lines[0].lastIndexOf(';');
if ( grIndex>=0 && semi>=0 ) {
int space = lines[0].indexOf(' ', grIndex);
int semi = lines[0].lastIndexOf(';');
fileName = lines[0].substring(space+1, semi)+".g";
}
if ( fileName.length()==".g".length() ) fileName = "<string>";
Grammar g = new Grammar(fileName, input);
g.loadImportedGrammars();
if ( printTree ) {
if ( g.ast!=null ) System.out.println(g.ast.toStringTree());
else System.out.println("null tree");
}
SemanticPipeline sem = new SemanticPipeline();
sem.process(g);
}
@ -442,7 +447,11 @@ public abstract class BaseTest {
re.printStackTrace(System.err);
}
String actual = equeue.toString();
assertEquals(expect,actual);
String msg = input;
msg = msg.replaceAll("\n","\\\\n");
msg = msg.replaceAll("\r","\\\\r");
msg = msg.replaceAll("\t","\\\\t");
assertEquals("error in: "+msg,expect,actual);
}
}

View File

@ -0,0 +1,57 @@
package org.antlr.v4.test;
import org.antlr.runtime.Token;
import org.antlr.v4.parse.ActionSplitterListener;
public class BlankActionSplitterListener implements ActionSplitterListener {
public void setQualifiedAttr(String expr, Token x, Token y, Token rhs) {
}
public void qualifiedAttr(String expr, Token x, Token y) {
}
public void setAttr(String expr, Token x, Token rhs) {
}
public void attr(String expr, Token x) {
}
public void setDynamicScopeAttr(String expr, Token x, Token y, Token rhs) {
}
public void dynamicScopeAttr(String expr, Token x, Token y) {
}
public void setDynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs) {
}
public void dynamicNegativeIndexedScopeAttr(String expr, Token x, Token y, Token index) {
}
public void setDynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index, Token rhs) {
}
public void dynamicAbsoluteIndexedScopeAttr(String expr, Token x, Token y, Token index) {
}
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) {
}
public void unknownSyntax(Token t) {
}
public void text(String text) {
}
}

View File

@ -10,23 +10,23 @@ import java.util.List;
public class TestActionSplitter extends BaseTest {
static String[] exprs = {
"foo", "['foo'<26>]",
"$x", "['$x'<16>]",
"\\$x", "['\\$x'<26>]",
"$x.y", "['$x.y'<8>]",
"$ID.text", "['$ID.text'<8>]",
"$ID", "['$ID'<16>]",
"$ID.getText()", "['$ID'<16>, '.getText()'<26>]",
"$ID.text = \"test\";", "['$ID.text = \"test\";'<7>]",
"$a.line == $b.line", "['$a.line'<8>, ' == '<26>, '$b.line'<8>]",
"$r.tree", "['$r.tree'<8>]",
"foo $a::n bar", "['foo '<26>, '$a::n'<10>, ' bar'<26>]",
"$Symbols[-1]::names.add($id.text);", "['$Symbols[-1]::names'<12>, '.add('<26>, '$id.text'<8>, ');'<26>]",
"$Symbols[0]::names.add($id.text);", "['$Symbols[0]::names'<14>, '.add('<26>, '$id.text'<8>, ');'<26>]",
"$Symbols::x;", "['$Symbols::x'<10>, ';'<26>]",
"$Symbols.size()>0", "['$Symbols'<16>, '.size()>0'<26>]",
"$field::x = $field.st;", "['$field::x = $field.st;'<9>]",
"$foo.get(\"ick\");", "['$foo'<16>, '.get(\"ick\");'<26>]",
"foo", "['foo'<29>]",
"$x", "['$x'<20>]",
"\\$x", "['\\$'<6>, 'x'<29>]",
"$x.y", "['$x.y'<11>]",
"$ID.text", "['$ID.text'<11>]",
"$ID", "['$ID'<20>]",
"$ID.getText()", "['$ID'<20>, '.getText()'<29>]",
"$ID.text = \"test\";", "['$ID.text = \"test\";'<10>]",
"$a.line == $b.line", "['$a.line'<11>, ' == '<29>, '$b.line'<11>]",
"$r.tree", "['$r.tree'<11>]",
"foo $a::n bar", "['foo '<29>, '$a::n'<13>, ' bar'<29>]",
"$Symbols[-1]::names.add($id.text);", "['$Symbols[-1]::names'<16>, '.add('<29>, '$id.text'<11>, ');'<29>]",
"$Symbols[0]::names.add($id.text);", "['$Symbols[0]::names'<18>, '.add('<29>, '$id.text'<11>, ');'<29>]",
"$Symbols::x;", "['$Symbols::x'<13>, ';'<29>]",
"$Symbols.size()>0", "['$Symbols'<20>, '.size()>0'<29>]",
"$field::x = $field.st;", "['$field::x = $field.st;'<12>]",
"$foo.get(\"ick\");", "['$foo'<20>, '.get(\"ick\");'<29>]",
};
@Test public void testExprs() {
@ -34,13 +34,14 @@ public class TestActionSplitter extends BaseTest {
String input = exprs[i];
String expect = exprs[i+1];
List<String> chunks = getActionChunks(input);
assertEquals(expect, chunks.toString());
assertEquals("input: "+input, expect, chunks.toString());
}
}
public static List<String> getActionChunks(String a) {
List<String> chunks = new ArrayList<String>();
ActionSplitter splitter = new ActionSplitter(new ANTLRStringStream(a));
ActionSplitter splitter = new ActionSplitter(new ANTLRStringStream(a),
new BlankActionSplitterListener());
Token t = splitter.nextToken();
while ( t.getType()!=Token.EOF ) {
chunks.add("'"+t.getText()+"'<"+t.getType()+">");

View File

@ -240,7 +240,7 @@ public class TestAttributeChecks extends BaseTest {
ST st = new ST(template);
st.add(location, action);
String grammar = st.render();
testErrors(new String[] {grammar, expected});
testErrors(new String[] {grammar, expected}, false);
}
}
}

View File

@ -15,10 +15,10 @@ public class TestBasicSemanticErrors extends BaseTest {
"\n" +
"b : A^ | ((B!|C)) -> C;",
// YIELDS
"error(67): A.g:7:7: alts with rewrites can't use heterogeneous types left of ->\n" +
"error(76): A.g:9:4: AST operator with non-AST output option: ^\n" +
"error(76): A.g:9:11: AST operator with non-AST output option: !\n" +
"error(77): A.g:9:11: rule b alt 2 uses rewrite syntax and also an AST operator",
"error(68): A.g:7:7: alts with rewrites can't use heterogeneous types left of ->\n" +
"error(77): A.g:9:4: AST operator with non-AST output option: ^\n" +
"error(77): A.g:9:11: AST operator with non-AST output option: !\n" +
"error(78): A.g:9:11: rule b alt 2 uses rewrite syntax and also an AST operator",
// INPUT
"tree grammar B;\n" +
@ -32,9 +32,9 @@ public class TestBasicSemanticErrors extends BaseTest {
"\n" +
"b : ^(. A) ;",
// YIELDS
"error(78): B.g:10:6: Wildcard invalid as root; wildcard can itself be a tree\n" +
"error(79): B.g:1:5: option backtrack=false conflicts with tree grammar filter mode\n" +
"error(79): B.g:1:5: option output=template conflicts with tree grammar filter mode"
"error(79): B.g:10:6: Wildcard invalid as root; wildcard can itself be a tree\n" +
"error(80): B.g:1:5: option backtrack=false conflicts with tree grammar filter mode\n" +
"error(80): B.g:1:5: option output=template conflicts with tree grammar filter mode"
};
static String[] U = {
@ -56,13 +56,13 @@ public class TestBasicSemanticErrors extends BaseTest {
"c : ID<blue> ID<x=y> ;",
// YIELDS
"error(21): U.g:8:0: repeated grammar prequel spec (option, token, or import); please merge\n" +
"error(21): U.g:7:0: repeated grammar prequel spec (option, token, or import); please merge\n" +
"error(48): U.g:2:10: illegal option foo\n" +
"error(26): U.g:4:8: token names must start with an uppercase letter: f\n" +
"error(48): U.g:8:10: illegal option x\n" +
"error(48): U.g:11:10: illegal option blech\n" +
"error(48): U.g:14:16: illegal option ick\n" +
"error(48): U.g:15:16: illegal option x",
"error(21): U.g:7:0: repeated grammar prequel spec (option, token, or import); please merge\n" +
"error(49): U.g:2:10: illegal option foo\n" +
"error(26): U.g:4:8: token names must start with an uppercase letter: f\n" +
"error(49): U.g:8:10: illegal option x\n" +
"error(49): U.g:11:10: illegal option blech\n" +
"error(49): U.g:14:16: illegal option ick\n" +
"error(49): U.g:15:16: illegal option x",
// INPUT
"tree grammar V;\n" +
@ -74,7 +74,7 @@ public class TestBasicSemanticErrors extends BaseTest {
" | A B -> template() \"kjsfdkdsj\" \n" +
" ;",
// YIELDS
"error(65): V.g:7:4: with rewrite=true, alt 2 not simple node or obvious tree element; text attribute for rule not guaranteed to be correct",
"error(66): V.g:7:4: with rewrite=true, alt 2 not simple node or obvious tree element; text attribute for rule not guaranteed to be correct",
// INPUT
"tree grammar V;\n" +
@ -83,9 +83,19 @@ public class TestBasicSemanticErrors extends BaseTest {
" | A B -> template() \"kjsfdkdsj\" \n" +
" ;",
// YIELDS
"error(61): V.g:4:8: rule a uses rewrite syntax or operator with no output option",
"error(62): V.g:4:8: rule a uses rewrite syntax or operator with no output option",
};
@Test public void testA() { super.testErrors(A); }
@Test public void testU() { super.testErrors(U); }
static String[] C = {
"parser grammar C;\n" +
"options {output=AST;}\n" +
"tokens { A; B; C; }\n" +
"a : A -> B $a A ;", // no problem with or $a.
""
};
@Test public void testA() { super.testErrors(A, false); }
@Test public void testU() { super.testErrors(U, false); }
@Test public void testE() { super.testErrors(C, false); }
}

View File

@ -24,17 +24,17 @@ public class TestSymbolIssues extends BaseTest {
"\n" +
"ID : 'a'..'z'+ ID ;",
// YIELDS
"error(48): A.g:2:10: illegal option opt\n" +
"error(58): A.g:11:6: scope Blort redefinition\n" +
"error(18): A.g:15:0: rule a redefinition\n" +
"error(57): A.g:7:1: redefinition of members action\n" +
"error(57): A.g:9:1: redefinition of header action\n" +
"error(71): A.g:3:19: cannot alias X; token name already defined\n" +
"error(71): A.g:3:26: cannot alias Y; token name already assigned to 'y'\n" +
"error(71): A.g:3:36: cannot alias Z; token name already defined\n" +
"error(45): A.g:13:37: rule b has no defined parameters\n" +
"error(23): A.g:13:43: reference to undefined rule: q\n" +
"error(44): A.g:14:31: missing parameter(s) on rule reference: a"
"error(49): A.g:2:10: illegal option opt\n" +
"error(59): A.g:11:6: scope Blort redefinition\n" +
"error(18): A.g:15:0: rule a redefinition\n" +
"error(58): A.g:7:1: redefinition of members action\n" +
"error(58): A.g:9:1: redefinition of header action\n" +
"error(72): A.g:3:19: cannot alias X; token name already defined\n" +
"error(72): A.g:3:26: cannot alias Y; token name already assigned to 'y'\n" +
"error(72): A.g:3:36: cannot alias Z; token name already defined\n" +
"error(46): A.g:13:32: rule a has no defined parameters\n" +
"error(46): A.g:13:37: rule b has no defined parameters\n" +
"error(23): A.g:13:43: reference to undefined rule: q"
};
static String[] B = {
@ -49,11 +49,11 @@ public class TestSymbolIssues extends BaseTest {
"\n" +
"s : FOO ;",
// YIELDS
"error(33): B.g:9:0: symbol s conflicts with global dynamic scope with same name\n" +
"error(34): B.g:5:9: label b conflicts with rule with same name\n" +
"error(33): B.g:5:4: symbol s conflicts with global dynamic scope with same name\n" +
"error(35): B.g:5:15: label X conflicts with token with same name\n" +
"error(40): B.g:7:9: label x type mismatch with previous definition: TOKEN_LIST_LABEL!=TOKEN_LABEL"
"error(34): B.g:9:0: symbol s conflicts with global dynamic scope with same name\n" +
"error(35): B.g:5:9: label b conflicts with rule with same name\n" +
"error(34): B.g:5:4: symbol s conflicts with global dynamic scope with same name\n" +
"error(36): B.g:5:15: label X conflicts with token with same name\n" +
"error(41): B.g:7:9: label x type mismatch with previous definition: TOKEN_LIST_LABEL!=TOKEN_LABEL"
};
static String[] C = {
@ -66,12 +66,12 @@ public class TestSymbolIssues extends BaseTest {
"b : B ;\n"+
"A : 'a';",
// YIELDS
"error(50): C.g:3:23: reference to rewrite element ID not found to left of ->\n" +
"error(50): C.g:3:28: reference to rewrite element r not found to left of ->\n" +
"error(50): C.g:3:30: reference to rewrite element foo not found to left of ->\n" +
"error(50): C.g:3:49: reference to rewrite element 'eh?' not found to left of ->\n" +
"error(50): C.g:4:10: reference to rewrite element x not found to left of ->\n" +
"error(50): C.g:4:13: reference to rewrite element A not found to left of ->"
"error(51): C.g:3:23: reference to rewrite element ID not found to left of ->\n" +
"error(51): C.g:3:28: reference to rewrite element r not found to left of ->\n" +
"error(51): C.g:3:30: reference to rewrite element foo not found to left of ->\n" +
"error(51): C.g:3:49: reference to rewrite element 'eh?' not found to left of ->\n" +
"error(51): C.g:4:10: reference to rewrite element x not found to left of ->\n" +
"error(51): C.g:4:13: reference to rewrite element A not found to left of ->"
};
static String[] D = {
@ -88,16 +88,16 @@ public class TestSymbolIssues extends BaseTest {
" : ID ;",
// YIELDS
"error(37): D.g:4:21: label j conflicts with rule a's return value or parameter with same name\n" +
"error(36): D.g:4:16: label i conflicts with rule a's dynamically-scoped attribute with same name\n" +
"error(41): D.g:6:0: rule b's argument i conflicts a return value with same name\n" +
"error(39): D.g:9:6: rule c's dynamically-scoped attribute i conflicts with c's return value or parameter with same name\n" +
"error(38): D.g:9:6: rule c's dynamically-scoped attribute c conflicts with the rule name\n" +
"error(39): D.g:9:6: rule c's dynamically-scoped attribute k conflicts with c's return value or parameter with same name"
"error(38): D.g:4:21: label j conflicts with rule a's return value or parameter with same name\n" +
"error(37): D.g:4:16: label i conflicts with rule a's dynamically-scoped attribute with same name\n" +
"error(42): D.g:6:0: rule b's argument i conflicts a return value with same name\n" +
"error(40): D.g:9:6: rule c's dynamically-scoped attribute i conflicts with c's return value or parameter with same name\n" +
"error(39): D.g:9:6: rule c's dynamically-scoped attribute c conflicts with the rule name\n" +
"error(40): D.g:9:6: rule c's dynamically-scoped attribute k conflicts with c's return value or parameter with same name"
};
@Test public void testA() { super.testErrors(A); }
@Test public void testB() { super.testErrors(B); }
@Test public void testC() { super.testErrors(C); }
@Test public void testD() { super.testErrors(D); }
@Test public void testA() { super.testErrors(A, false); }
@Test public void testB() { super.testErrors(B, false); }
@Test public void testC() { super.testErrors(C, false); }
@Test public void testD() { super.testErrors(D, false); }
}

View File

@ -0,0 +1,129 @@
package org.antlr.v4.test;
import org.junit.Test;
public class TestSyntaxErrors extends BaseTest {
static String[] A = {
// INPUT
"grammar A;\n" +
"",
// YIELDS
"error(63): A.g::: grammar A has no rules",
"A;",
"error(17): <string>:1:0: 'A'<TOKEN_REF> came as a complete surprise to me",
"grammar ;",
"error(17): <string>:1:8: ';'<SEMI> came as a complete surprise to me",
"grammar A\n" +
"a : ID ;\n",
"error(17): <string>:2:0: missing SEMI at 'a'",
"grammar A;\n" +
"a : ID ;;\n"+
"b : B ;",
"error(17): A.g:2:8: ';'<SEMI> came as a complete surprise to me",
"grammar A;;\n" +
"a : ID ;\n",
"error(17): A;.g:1:10: ';'<SEMI> came as a complete surprise to me",
"grammar A;\n" +
"a @init : ID ;\n",
"error(17): A.g:2:8: missing ACTION at ':' while matching a rule",
"grammar A;\n" +
"a ( A | B ) D ;\n" +
"b : B ;",
"error(17): A.g:2:3: missing COLON at '(' while matching a rule",
};
@Test public void testA() { super.testErrors(A, true); }
@Test public void testExtraColon() {
String[] pair = new String[] {
"grammar A;\n" +
"a : : A ;\n" +
"b : B ;",
"error(17): A.g:2:4: ':'<COLON> came as a complete surprise to me while matching alternative",
};
super.testErrors(pair, true);
}
@Test public void testMissingRuleSemi() {
String[] pair = new String[] {
"grammar A;\n" +
"a : A \n" +
"b : B ;",
"error(17): A.g:3:0: unterminated rule (missing ';') detected at 'b :' while looking for rule element",
};
super.testErrors(pair, true);
}
@Test public void testMissingRuleSemi2() {
String[] pair = new String[] {
"lexer grammar A;\n" +
"A : 'a' \n" +
"B : 'b' ;",
"error(17): A.g:3:0: unterminated rule (missing ';') detected at 'B :' while looking for rule element",
};
super.testErrors(pair, true);
}
@Test public void testMissingRuleSemi3() {
String[] pair = new String[] {
"grammar A;\n" +
"a : A \n" +
"b[int i] returns [int y] : B ;",
"error(17): A.g:3:9: unterminated rule (missing ';') detected at 'returns int y' while looking for rule element"
};
super.testErrors(pair, true);
}
@Test public void testMissingRuleSemi4() {
String[] pair = new String[] {
"grammar A;\n" +
"a : b \n" +
" catch [Exception e] {...}\n" +
"b : B ;\n",
"error(17): A.g:2:4: unterminated rule (missing ';') detected at 'b catch' while looking for rule element"
};
super.testErrors(pair, true);
}
@Test public void testMissingRuleSemi5() {
String[] pair = new String[] {
"grammar A;\n" +
"a : A \n" +
" catch [Exception e] {...}\n",
"error(17): A.g:2:4: unterminated rule (missing ';') detected at 'A catch' while looking for rule element"
};
super.testErrors(pair, true);
}
@Test public void testBadRulePrequelStart() {
String[] pair = new String[] {
"grammar A;\n" +
"a @ options {k=1;} : A ;\n" +
"b : B ;",
"error(17): A.g:2:4: 'options {' came as a complete surprise to me while looking for an identifier"
};
super.testErrors(pair, true);
}
@Test public void testBadRulePrequelStart2() {
String[] pair = new String[] {
"grammar A;\n" +
"a } : A ;\n" +
"b : B ;",
"error(17): A.g:2:2: '}' came as a complete surprise to me while matching rule preamble"
};
super.testErrors(pair, true);
}
}