forked from jasder/antlr
removed state stuff
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8726]
This commit is contained in:
parent
981aff4132
commit
4e3fd8446d
|
@ -39,28 +39,50 @@ import java.util.*;
|
|||
*
|
||||
* TODO: rename since lexer not under. or reorg parser/treeparser; treeparser under parser?
|
||||
*/
|
||||
public abstract class BaseRecognizer extends Recognizer<ParserSharedState, ParserInterpreter> {
|
||||
public abstract class BaseRecognizer extends Recognizer<ParserInterpreter> {
|
||||
|
||||
public static final int MEMO_RULE_FAILED = -2;
|
||||
public static final int MEMO_RULE_UNKNOWN = -1;
|
||||
|
||||
public static final String NEXT_TOKEN_RULE_NAME = "nextToken";
|
||||
|
||||
public TokenStream input;
|
||||
|
||||
public ParserRuleContext _ctx; // current _ctx of executing rule
|
||||
|
||||
/** This is true when we see an error and before having successfully
|
||||
* matched a token. Prevents generation of more than one error message
|
||||
* per error.
|
||||
*/
|
||||
public boolean errorRecovery = false;
|
||||
|
||||
/** The index into the input stream where the last error occurred.
|
||||
* This is used to prevent infinite loops where an error is found
|
||||
* but no token is consumed during recovery...another error is found,
|
||||
* ad naseum. This is a failsafe mechanism to guarantee that at least
|
||||
* one token/tree node is consumed for two errors.
|
||||
*/
|
||||
public int lastErrorIndex = -1;
|
||||
|
||||
/** In lieu of a return value, this indicates that a rule or token
|
||||
* has failed to match. Reset to false upon valid token match.
|
||||
*/
|
||||
public boolean failed = false;
|
||||
|
||||
/** Did the recognizer encounter a syntax error? Track how many. */
|
||||
public int syntaxErrors = 0;
|
||||
|
||||
public BaseRecognizer(TokenStream input) {
|
||||
this(input, new ParserSharedState());
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public BaseRecognizer(TokenStream input, ParserSharedState state) {
|
||||
if ( state==null ) {
|
||||
state = new ParserSharedState();
|
||||
}
|
||||
this.state = state;
|
||||
state.input = input;
|
||||
}
|
||||
|
||||
/** reset the parser's state; subclasses must rewinds the input stream */
|
||||
/** reset the parser's state */
|
||||
public void reset() {
|
||||
state = new ParserSharedState();
|
||||
input.seek(0);
|
||||
errorRecovery = false;
|
||||
_ctx = null;
|
||||
lastErrorIndex = -1;
|
||||
failed = false;
|
||||
}
|
||||
|
||||
/** Match current input symbol against ttype. Attempt
|
||||
|
@ -75,17 +97,17 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
* to the set of symbols that can follow rule ref.
|
||||
*/
|
||||
public Object match(int ttype) throws RecognitionException {
|
||||
// System.out.println("match "+((TokenStream)state.input).LT(1)+" vs expected "+ttype);
|
||||
// System.out.println("match "+((TokenStream)input).LT(1)+" vs expected "+ttype);
|
||||
Object matchedSymbol = getCurrentInputSymbol();
|
||||
if ( state.input.LA(1)==ttype ) {
|
||||
state.input.consume();
|
||||
state.errorRecovery = false;
|
||||
state.failed = false;
|
||||
if ( input.LA(1)==ttype ) {
|
||||
input.consume();
|
||||
errorRecovery = false;
|
||||
failed = false;
|
||||
return matchedSymbol;
|
||||
}
|
||||
System.out.println("MATCH failure at state "+state.ctx.s+
|
||||
", ctx="+state.ctx.toString(this));
|
||||
IntervalSet expecting = _interp.atn.nextTokens(state.ctx);
|
||||
System.out.println("MATCH failure at state "+_ctx.s+
|
||||
", ctx="+_ctx.toString(this));
|
||||
IntervalSet expecting = _interp.atn.nextTokens(_ctx);
|
||||
System.out.println("could match "+expecting);
|
||||
|
||||
matchedSymbol = recoverFromMismatchedToken(ttype, expecting);
|
||||
|
@ -95,23 +117,23 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
|
||||
// like matchSet but w/o consume; error checking routine.
|
||||
public void sync(IntervalSet expecting) {
|
||||
if ( expecting.member(state.input.LA(1)) ) return;
|
||||
if ( expecting.member(input.LA(1)) ) return;
|
||||
System.out.println("failed sync to "+expecting);
|
||||
IntervalSet followSet = computeErrorRecoverySet();
|
||||
followSet.addAll(expecting);
|
||||
NoViableAltException e = new NoViableAltException(this, state.ctx);
|
||||
NoViableAltException e = new NoViableAltException(this, _ctx);
|
||||
recoverFromMismatchedSet(e, followSet);
|
||||
}
|
||||
|
||||
/** Match the wildcard: in a symbol */
|
||||
public void matchAny() {
|
||||
state.errorRecovery = false;
|
||||
state.failed = false;
|
||||
state.input.consume();
|
||||
errorRecovery = false;
|
||||
failed = false;
|
||||
input.consume();
|
||||
}
|
||||
|
||||
public boolean mismatchIsUnwantedToken(int ttype) {
|
||||
return state.input.LA(2)==ttype;
|
||||
return input.LA(2)==ttype;
|
||||
}
|
||||
|
||||
public boolean mismatchIsMissingToken(IntervalSet follow) {
|
||||
|
@ -126,7 +148,7 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
if ( follow.member(Token.EOR_TOKEN_TYPE) ) {
|
||||
IntervalSet viableTokensFollowingThisRule = computeNextViableTokenSet();
|
||||
follow = follow.or(viableTokensFollowingThisRule);
|
||||
if ( state.ctx.sp>=0 ) { // remove EOR if we're not the start symbol
|
||||
if ( ctx.sp>=0 ) { // remove EOR if we're not the start symbol
|
||||
follow.remove(Token.EOR_TOKEN_TYPE);
|
||||
}
|
||||
}
|
||||
|
@ -135,13 +157,13 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
// "insert" the missing token
|
||||
|
||||
//System.out.println("viable tokens="+follow.toString(getTokenNames()));
|
||||
//System.out.println("LT(1)="+((TokenStream)state.input).LT(1));
|
||||
//System.out.println("LT(1)="+((TokenStream)input).LT(1));
|
||||
|
||||
// IntervalSet cannot handle negative numbers like -1 (EOF) so I leave EOR
|
||||
// in follow set to indicate that the fall of the start symbol is
|
||||
// in the set (EOF can follow).
|
||||
if ( follow.member(state.input.LA(1)) || follow.member(Token.EOR_TOKEN_TYPE) ) {
|
||||
//System.out.println("LT(1)=="+((TokenStream)state.input).LT(1)+" is consistent with what follows; inserting...");
|
||||
if ( follow.member(input.LA(1)) || follow.member(Token.EOR_TOKEN_TYPE) ) {
|
||||
//System.out.println("LT(1)=="+((TokenStream)input).LT(1)+" is consistent with what follows; inserting...");
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -164,12 +186,12 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
public void reportError(RecognitionException e) {
|
||||
// if we've already reported an error and have not matched a token
|
||||
// yet successfully, don't report any errors.
|
||||
if ( state.errorRecovery ) {
|
||||
if ( errorRecovery ) {
|
||||
//System.err.print("[SPURIOUS] ");
|
||||
return;
|
||||
}
|
||||
state.syntaxErrors++; // don't count spurious
|
||||
state.errorRecovery = true;
|
||||
syntaxErrors++; // don't count spurious
|
||||
errorRecovery = true;
|
||||
|
||||
notifyListeners(e);
|
||||
}
|
||||
|
@ -183,7 +205,7 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
* See also reportError()
|
||||
*/
|
||||
public int getNumberOfSyntaxErrors() {
|
||||
return state.syntaxErrors;
|
||||
return syntaxErrors;
|
||||
}
|
||||
|
||||
|
||||
|
@ -194,16 +216,16 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
* token that the match() routine could not recover from.
|
||||
*/
|
||||
public void recover() {
|
||||
state.input.consume();
|
||||
input.consume();
|
||||
/*
|
||||
if ( state.lastErrorIndex==state.input.index() ) {
|
||||
if ( lastErrorIndex==input.index() ) {
|
||||
// uh oh, another error at same token index; must be a case
|
||||
// where LT(1) is in the recovery token set so nothing is
|
||||
// consumed; consume a single token so at least to prevent
|
||||
// an infinite loop; this is a failsafe.
|
||||
state.input.consume();
|
||||
input.consume();
|
||||
}
|
||||
state.lastErrorIndex = state.input.index();
|
||||
lastErrorIndex = input.index();
|
||||
IntervalSet followSet = computeErrorRecoverySet();
|
||||
beginResync();
|
||||
consumeUntil(followSet);
|
||||
|
@ -314,10 +336,10 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
*/
|
||||
protected IntervalSet computeErrorRecoverySet() {
|
||||
return null;
|
||||
// int top = state.ctx.sp;
|
||||
// int top = ctx.sp;
|
||||
// IntervalSet followSet = new IntervalSet();
|
||||
// for (int i=top; i>=0; i--) { // i==0 is EOF context for start rule invocation
|
||||
// IntervalSet f = (IntervalSet)state.ctx.get(i).follow;
|
||||
// IntervalSet f = (IntervalSet)ctx.get(i).follow;
|
||||
// followSet.orInPlace(f);
|
||||
// }
|
||||
// return followSet;
|
||||
|
@ -377,10 +399,10 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
*/
|
||||
public IntervalSet computeNextViableTokenSet() {
|
||||
return null;
|
||||
// int top = state.ctx.sp;
|
||||
// int top = ctx.sp;
|
||||
// IntervalSet followSet = new IntervalSet();
|
||||
// for (int i=top; i>=0; i--) { // i==0 is EOF context for start rule invocation
|
||||
// IntervalSet f = (IntervalSet)state.ctx.get(i).follow;
|
||||
// IntervalSet f = (IntervalSet)ctx.get(i).follow;
|
||||
// followSet.orInPlace(f);
|
||||
// // can we see end of rule? if not, don't include follow of this rule
|
||||
// if ( !f.member(Token.EOR_TOKEN_TYPE) ) break;
|
||||
|
@ -426,30 +448,30 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
RecognitionException e = null;
|
||||
// if next token is what we are looking for then "delete" this token
|
||||
if ( mismatchIsUnwantedToken(ttype) ) {
|
||||
e = new UnwantedTokenException(this, state.input, ttype);
|
||||
e = new UnwantedTokenException(this, input, ttype);
|
||||
/*
|
||||
System.err.println("recoverFromMismatchedToken deleting "+
|
||||
((TokenStream)state.input).LT(1)+
|
||||
" since "+((TokenStream)state.input).LT(2)+" is what we want");
|
||||
((TokenStream)input).LT(1)+
|
||||
" since "+((TokenStream)input).LT(2)+" is what we want");
|
||||
*/
|
||||
beginResync();
|
||||
state.input.consume(); // simply delete extra token
|
||||
input.consume(); // simply delete extra token
|
||||
endResync();
|
||||
reportError(e); // report after consuming so AW sees the token in the exception
|
||||
// we want to return the token we're actually matching
|
||||
Object matchedSymbol = getCurrentInputSymbol();
|
||||
state.input.consume(); // move past ttype token as if all were ok
|
||||
input.consume(); // move past ttype token as if all were ok
|
||||
return matchedSymbol;
|
||||
}
|
||||
// can't recover with single token deletion, try insertion
|
||||
if ( mismatchIsMissingToken(follow) ) {
|
||||
Object inserted = getMissingSymbol(e, ttype, follow);
|
||||
e = new MissingTokenException(this, state.input, ttype, inserted);
|
||||
e = new MissingTokenException(this, input, ttype, inserted);
|
||||
reportError(e); // report after inserting so AW sees the token in the exception
|
||||
return inserted;
|
||||
}
|
||||
// even that didn't work; must throw the exception
|
||||
e = new MismatchedTokenException(this, state.input, ttype);
|
||||
e = new MismatchedTokenException(this, input, ttype);
|
||||
throw e;
|
||||
}
|
||||
|
||||
|
@ -504,21 +526,21 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
|
||||
public void consumeUntil(int tokenType) {
|
||||
//System.out.println("consumeUntil "+tokenType);
|
||||
int ttype = state.input.LA(1);
|
||||
int ttype = input.LA(1);
|
||||
while (ttype != Token.EOF && ttype != tokenType) {
|
||||
state.input.consume();
|
||||
ttype = state.input.LA(1);
|
||||
input.consume();
|
||||
ttype = input.LA(1);
|
||||
}
|
||||
}
|
||||
|
||||
/** Consume tokens until one matches the given token set */
|
||||
public void consumeUntil(IntervalSet set) {
|
||||
//System.out.println("consumeUntil("+set.toString(getTokenNames())+")");
|
||||
int ttype = state.input.LA(1);
|
||||
int ttype = input.LA(1);
|
||||
while (ttype != Token.EOF && !set.member(ttype) ) {
|
||||
//System.out.println("consume during recover LA(1)="+getTokenNames()[state.input.LA(1)]);
|
||||
state.input.consume();
|
||||
ttype = state.input.LA(1);
|
||||
//System.out.println("consume during recover LA(1)="+getTokenNames()[input.LA(1)]);
|
||||
input.consume();
|
||||
ttype = input.LA(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -565,7 +587,7 @@ public abstract class BaseRecognizer extends Recognizer<ParserSharedState, Parse
|
|||
}
|
||||
|
||||
/** Return whether or not a backtracking attempt failed. */
|
||||
public boolean failed() { return state.failed; }
|
||||
public boolean failed() { return failed; }
|
||||
|
||||
/** For debugging and other purposes, might want the grammar name.
|
||||
* Have ANTLR generate an implementation for this method.
|
||||
|
|
|
@ -129,8 +129,8 @@ public class BufferedTokenStream implements TokenStream {
|
|||
protected void fetch(int n) {
|
||||
for (int i=1; i<=n; i++) {
|
||||
Token t = tokenSource.nextToken();
|
||||
// System.out.println("adding "+t+" at index "+tokens.size());
|
||||
t.setTokenIndex(tokens.size());
|
||||
//System.out.println("adding "+t+" at index "+tokens.size());
|
||||
tokens.add(t);
|
||||
if ( t.getType()==Token.EOF ) break;
|
||||
}
|
||||
|
|
|
@ -33,6 +33,6 @@ public class EarlyExitException extends RecognitionException {
|
|||
public EarlyExitException() {;}
|
||||
|
||||
public EarlyExitException(BaseRecognizer recognizer, IntStream input) {
|
||||
super(recognizer, input, recognizer.state.ctx);
|
||||
super(recognizer, input, recognizer._ctx);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,7 +44,7 @@ public class FailedPredicateException extends RecognitionException {
|
|||
String ruleName,
|
||||
String predicateText)
|
||||
{
|
||||
super(recognizer, input, recognizer.state.ctx);
|
||||
super(recognizer, input, recognizer._ctx);
|
||||
this.ruleName = ruleName;
|
||||
this.predicateText = predicateText;
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ import java.util.EmptyStackException;
|
|||
* uses simplified match() and error recovery mechanisms in the interest
|
||||
* of speed.
|
||||
*/
|
||||
public abstract class Lexer extends Recognizer<LexerSharedState, LexerInterpreter>
|
||||
public abstract class Lexer extends Recognizer<LexerInterpreter>
|
||||
implements TokenSource
|
||||
{
|
||||
public static final int DEFAULT_MODE = 0;
|
||||
|
@ -47,35 +47,60 @@ public abstract class Lexer extends Recognizer<LexerSharedState, LexerInterprete
|
|||
public static final int DEFAULT_TOKEN_CHANNEL = Token.DEFAULT_CHANNEL;
|
||||
public static final int HIDDEN = Token.HIDDEN_CHANNEL;
|
||||
|
||||
public LexerSharedState state;
|
||||
public CharStream input;
|
||||
|
||||
/** The goal of all lexer rules/methods is to create a token object.
|
||||
* This is an instance variable as multiple rules may collaborate to
|
||||
* create a single token. nextToken will return this object after
|
||||
* matching lexer rule(s). If you subclass to allow multiple token
|
||||
* emissions, then set this to the last token to be matched or
|
||||
* something nonnull so that the auto token emit mechanism will not
|
||||
* emit another token.
|
||||
*/
|
||||
public Token token;
|
||||
|
||||
/** What character index in the stream did the current token start at?
|
||||
* Needed, for example, to get the text for current token. Set at
|
||||
* the start of nextToken.
|
||||
*/
|
||||
public int tokenStartCharIndex = -1;
|
||||
|
||||
/** The line on which the first character of the token resides */
|
||||
public int tokenStartLine;
|
||||
|
||||
/** The character position of first character within the line */
|
||||
public int tokenStartCharPositionInLine;
|
||||
|
||||
/** The channel number for the current token */
|
||||
public int channel;
|
||||
|
||||
/** The token type for the current token */
|
||||
public int type;
|
||||
|
||||
public QStack<Integer> modeStack;
|
||||
public int mode = Lexer.DEFAULT_MODE;
|
||||
|
||||
/** You can set the text for the current token to override what is in
|
||||
* the input char buffer. Use setText() or can set this instance var.
|
||||
*/
|
||||
public String text;
|
||||
|
||||
public Lexer(CharStream input) {
|
||||
this(input, new LexerSharedState());
|
||||
}
|
||||
|
||||
public Lexer(CharStream input, LexerSharedState state) {
|
||||
if ( state==null ) {
|
||||
state = new LexerSharedState();
|
||||
}
|
||||
this.state = state;
|
||||
state.input = input;
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
// wack Lexer state variables
|
||||
if ( state.input!=null ) {
|
||||
state.input.seek(0); // rewind the input
|
||||
if ( input!=null ) {
|
||||
input.seek(0); // rewind the input
|
||||
}
|
||||
if ( state==null ) {
|
||||
return; // no shared state work to do
|
||||
}
|
||||
state.token = null;
|
||||
state.type = Token.INVALID_TYPE;
|
||||
state.channel = Token.DEFAULT_CHANNEL;
|
||||
state.tokenStartCharIndex = -1;
|
||||
state.tokenStartCharPositionInLine = -1;
|
||||
state.tokenStartLine = -1;
|
||||
state.text = null;
|
||||
token = null;
|
||||
type = Token.INVALID_TYPE;
|
||||
channel = Token.DEFAULT_CHANNEL;
|
||||
tokenStartCharIndex = -1;
|
||||
tokenStartCharPositionInLine = -1;
|
||||
tokenStartLine = -1;
|
||||
text = null;
|
||||
}
|
||||
|
||||
/** Return a token from this source; i.e., match a token on the char
|
||||
|
@ -84,34 +109,34 @@ public abstract class Lexer extends Recognizer<LexerSharedState, LexerInterprete
|
|||
public Token nextToken() {
|
||||
outer:
|
||||
while (true) {
|
||||
state.token = null;
|
||||
state.channel = Token.DEFAULT_CHANNEL;
|
||||
state.tokenStartCharIndex = state.input.index();
|
||||
state.tokenStartCharPositionInLine = state.input.getCharPositionInLine();
|
||||
state.tokenStartLine = state.input.getLine();
|
||||
state.text = null;
|
||||
token = null;
|
||||
channel = Token.DEFAULT_CHANNEL;
|
||||
tokenStartCharIndex = input.index();
|
||||
tokenStartCharPositionInLine = input.getCharPositionInLine();
|
||||
tokenStartLine = input.getLine();
|
||||
text = null;
|
||||
do {
|
||||
state.type = Token.INVALID_TYPE;
|
||||
if ( state.input.LA(1)==CharStream.EOF ) {
|
||||
Token eof = new CommonToken(state.input,Token.EOF,
|
||||
type = Token.INVALID_TYPE;
|
||||
if ( input.LA(1)==CharStream.EOF ) {
|
||||
Token eof = new CommonToken(input,Token.EOF,
|
||||
Token.DEFAULT_CHANNEL,
|
||||
state.input.index(),state.input.index());
|
||||
input.index(),input.index());
|
||||
eof.setLine(getLine());
|
||||
eof.setCharPositionInLine(getCharPositionInLine());
|
||||
return eof;
|
||||
}
|
||||
// System.out.println("nextToken at "+((char)state.input.LA(1))+
|
||||
// " in mode "+state.mode+
|
||||
// " at index "+state.input.index());
|
||||
int ttype = _interp.match(state.input, state.mode);
|
||||
// System.out.println("nextToken at "+((char)input.LA(1))+
|
||||
// " in mode "+mode+
|
||||
// " at index "+input.index());
|
||||
int ttype = _interp.match(input, mode);
|
||||
// System.out.println("accepted ttype "+ttype);
|
||||
if ( state.type == Token.INVALID_TYPE) state.type = ttype;
|
||||
if ( state.type==SKIP ) {
|
||||
if ( type == Token.INVALID_TYPE) type = ttype;
|
||||
if ( type==SKIP ) {
|
||||
continue outer;
|
||||
}
|
||||
} while ( state.type==MORE );
|
||||
if ( state.token==null ) emit();
|
||||
return state.token;
|
||||
} while ( type==MORE );
|
||||
if ( token==null ) emit();
|
||||
return token;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,44 +147,44 @@ public abstract class Lexer extends Recognizer<LexerSharedState, LexerInterprete
|
|||
* and emits it.
|
||||
*/
|
||||
public void skip() {
|
||||
state.type = SKIP;
|
||||
type = SKIP;
|
||||
}
|
||||
|
||||
public void more() {
|
||||
state.type = MORE;
|
||||
type = MORE;
|
||||
}
|
||||
|
||||
public void mode(int m) {
|
||||
state.mode = m;
|
||||
mode = m;
|
||||
}
|
||||
|
||||
public void pushMode(int m) {
|
||||
// System.out.println("pushMode "+m);
|
||||
if ( state.modeStack==null ) state.modeStack = new QStack<Integer>();
|
||||
state.modeStack.push(state.mode);
|
||||
if ( modeStack==null ) modeStack = new QStack<Integer>();
|
||||
modeStack.push(mode);
|
||||
mode(m);
|
||||
}
|
||||
|
||||
public int popMode() {
|
||||
if ( state.modeStack==null ) throw new EmptyStackException();
|
||||
// System.out.println("popMode back to "+state.modeStack.peek());
|
||||
mode( state.modeStack.pop() );
|
||||
return state.mode;
|
||||
if ( modeStack==null ) throw new EmptyStackException();
|
||||
// System.out.println("popMode back to "+modeStack.peek());
|
||||
mode( modeStack.pop() );
|
||||
return mode;
|
||||
}
|
||||
|
||||
/** Set the char stream and reset the lexer */
|
||||
public void setCharStream(CharStream input) {
|
||||
this.state.input = null;
|
||||
this.input = null;
|
||||
reset();
|
||||
this.state.input = input;
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public CharStream getCharStream() {
|
||||
return ((CharStream)state.input);
|
||||
return ((CharStream)input);
|
||||
}
|
||||
|
||||
public String getSourceName() {
|
||||
return state.input.getSourceName();
|
||||
return input.getSourceName();
|
||||
}
|
||||
|
||||
/** Currently does not support multiple emits per nextToken invocation
|
||||
|
@ -169,7 +194,7 @@ public abstract class Lexer extends Recognizer<LexerSharedState, LexerInterprete
|
|||
*/
|
||||
public void emit(Token token) {
|
||||
//System.err.println("emit "+token);
|
||||
state.token = token;
|
||||
this.token = token;
|
||||
}
|
||||
|
||||
/** The standard method called to automatically emit a token at the
|
||||
|
@ -182,44 +207,44 @@ public abstract class Lexer extends Recognizer<LexerSharedState, LexerInterprete
|
|||
* Parser or TreeParser.getMissingSymbol().
|
||||
*/
|
||||
public Token emit() {
|
||||
Token t = new CommonToken(((CharStream)state.input), state.type,
|
||||
state.channel, state.tokenStartCharIndex,
|
||||
Token t = new CommonToken(((CharStream)input), type,
|
||||
channel, tokenStartCharIndex,
|
||||
getCharIndex()-1);
|
||||
t.setLine(state.tokenStartLine);
|
||||
t.setText(state.text);
|
||||
t.setCharPositionInLine(state.tokenStartCharPositionInLine);
|
||||
t.setLine(tokenStartLine);
|
||||
t.setText(text);
|
||||
t.setCharPositionInLine(tokenStartCharPositionInLine);
|
||||
emit(t);
|
||||
return t;
|
||||
}
|
||||
|
||||
public int getLine() {
|
||||
return ((CharStream)state.input).getLine();
|
||||
return ((CharStream)input).getLine();
|
||||
}
|
||||
|
||||
public int getCharPositionInLine() {
|
||||
return ((CharStream)state.input).getCharPositionInLine();
|
||||
return ((CharStream)input).getCharPositionInLine();
|
||||
}
|
||||
|
||||
/** What is the index of the current character of lookahead? */
|
||||
public int getCharIndex() {
|
||||
return state.input.index();
|
||||
return input.index();
|
||||
}
|
||||
|
||||
/** Return the text matched so far for the current token or any
|
||||
* text override.
|
||||
*/
|
||||
public String getText() {
|
||||
if ( state.text!=null ) {
|
||||
return state.text;
|
||||
if ( text!=null ) {
|
||||
return text;
|
||||
}
|
||||
return ((CharStream)state.input).substring(state.tokenStartCharIndex,getCharIndex()-1);
|
||||
return ((CharStream)input).substring(tokenStartCharIndex,getCharIndex()-1);
|
||||
}
|
||||
|
||||
/** Set the complete text of this token; it wipes any previous
|
||||
* changes to the text.
|
||||
*/
|
||||
public void setText(String text) {
|
||||
state.text = text;
|
||||
text = text;
|
||||
}
|
||||
|
||||
public void reportError(RecognitionException e) {
|
||||
|
@ -308,8 +333,8 @@ public abstract class Lexer extends Recognizer<LexerSharedState, LexerInterprete
|
|||
* to do sophisticated error recovery if you are in a fragment rule.
|
||||
*/
|
||||
public void recover(RecognitionException re) {
|
||||
//System.out.println("consuming char "+(char)state.input.LA(1)+" during recovery");
|
||||
//System.out.println("consuming char "+(char)input.LA(1)+" during recovery");
|
||||
//re.printStackTrace();
|
||||
state.input.consume();
|
||||
input.consume();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,56 +0,0 @@
|
|||
package org.antlr.v4.runtime;
|
||||
|
||||
import org.antlr.v4.runtime.misc.QStack;
|
||||
|
||||
public class LexerSharedState extends RecognizerSharedState<CharStream> {
|
||||
//public CharStream input;
|
||||
|
||||
/** The goal of all lexer rules/methods is to create a token object.
|
||||
* This is an instance variable as multiple rules may collaborate to
|
||||
* create a single token. nextToken will return this object after
|
||||
* matching lexer rule(s). If you subclass to allow multiple token
|
||||
* emissions, then set this to the last token to be matched or
|
||||
* something nonnull so that the auto token emit mechanism will not
|
||||
* emit another token.
|
||||
*/
|
||||
public Token token;
|
||||
|
||||
/** What character index in the stream did the current token start at?
|
||||
* Needed, for example, to get the text for current token. Set at
|
||||
* the start of nextToken.
|
||||
*/
|
||||
public int tokenStartCharIndex = -1;
|
||||
|
||||
/** The line on which the first character of the token resides */
|
||||
public int tokenStartLine;
|
||||
|
||||
/** The character position of first character within the line */
|
||||
public int tokenStartCharPositionInLine;
|
||||
|
||||
/** The channel number for the current token */
|
||||
public int channel;
|
||||
|
||||
/** The token type for the current token */
|
||||
public int type;
|
||||
|
||||
public QStack<Integer> modeStack;
|
||||
public int mode = Lexer.DEFAULT_MODE;
|
||||
|
||||
/** You can set the text for the current token to override what is in
|
||||
* the input char buffer. Use setText() or can set this instance var.
|
||||
*/
|
||||
public String text;
|
||||
|
||||
public LexerSharedState() {
|
||||
}
|
||||
|
||||
public LexerSharedState(LexerSharedState state) {
|
||||
this.token = state.token;
|
||||
this.tokenStartCharIndex = state.tokenStartCharIndex;
|
||||
this.tokenStartLine = state.tokenStartLine;
|
||||
this.tokenStartCharPositionInLine = state.tokenStartCharPositionInLine;
|
||||
this.channel = state.channel;
|
||||
this.type = state.type;
|
||||
this.text = state.text;
|
||||
}
|
||||
}
|
|
@ -34,7 +34,7 @@ public class MismatchedRangeException extends RecognitionException {
|
|||
public MismatchedRangeException() {;}
|
||||
|
||||
public MismatchedRangeException(BaseRecognizer recognizer, IntStream input, int a, int b) {
|
||||
super(recognizer, input, recognizer.state.ctx);
|
||||
super(recognizer, input, recognizer._ctx);
|
||||
this.a = a;
|
||||
this.b = b;
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ public class MismatchedSetException extends RecognitionException {
|
|||
public MismatchedSetException() {;}
|
||||
|
||||
public MismatchedSetException(BaseRecognizer recognizer, IntStream input) {
|
||||
super(recognizer, input, recognizer.state.ctx);
|
||||
super(recognizer, input, recognizer._ctx);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
|
|
@ -33,7 +33,7 @@ public class MismatchedTokenException extends RecognitionException {
|
|||
public MismatchedTokenException() {;}
|
||||
|
||||
public MismatchedTokenException(BaseRecognizer recognizer, IntStream input, int expecting) {
|
||||
super(recognizer, input, recognizer.state.ctx);
|
||||
super(recognizer, input, recognizer._ctx);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
|
|
@ -36,7 +36,7 @@ public class MismatchedTreeNodeException extends RecognitionException {
|
|||
public MismatchedTreeNodeException(BaseRecognizer recognizer,
|
||||
IntStream input, int firstSet)
|
||||
{
|
||||
super(recognizer, input, recognizer.state.ctx);
|
||||
super(recognizer, input, recognizer._ctx);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
|
|
|
@ -41,7 +41,7 @@ public class NoViableAltException extends RecognitionException {
|
|||
public NoViableAltException() {;}
|
||||
|
||||
public NoViableAltException(BaseRecognizer recognizer, RuleContext ctx) { // LL(1) error
|
||||
super(recognizer, recognizer.state.input, ctx);
|
||||
super(recognizer, recognizer.input, ctx);
|
||||
}
|
||||
|
||||
public NoViableAltException(BaseRecognizer recognizer, IntStream input,
|
||||
|
@ -54,7 +54,7 @@ public class NoViableAltException extends RecognitionException {
|
|||
|
||||
public String toString() {
|
||||
if ( recognizer!=null ) {
|
||||
TokenStream tokens = recognizer.state.input;
|
||||
TokenStream tokens = recognizer.input;
|
||||
String bad = tokens.toString(startIndex, index);
|
||||
return "NoViableAltException(input=\""+bad+"\" last token type is "+getUnexpectedType();
|
||||
}
|
||||
|
|
|
@ -32,23 +32,20 @@ package org.antlr.v4.runtime;
|
|||
* of this.
|
||||
*/
|
||||
public class Parser extends BaseRecognizer {
|
||||
|
||||
public Parser(TokenStream input) {
|
||||
super(input);
|
||||
}
|
||||
|
||||
public Parser(TokenStream input, ParserSharedState state) {
|
||||
super(input, state); // share the state object with another parser
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
super.reset(); // reset all recognizer state variables
|
||||
if ( state.input!=null ) {
|
||||
state.input.seek(0); // rewind the input
|
||||
if ( input!=null ) {
|
||||
input.seek(0); // rewind the input
|
||||
}
|
||||
}
|
||||
|
||||
protected Object getCurrentInputSymbol() {
|
||||
return ((TokenStream)state.input).LT(1);
|
||||
return input.LT(1);
|
||||
}
|
||||
|
||||
protected Object getMissingSymbol(RecognitionException e,
|
||||
|
@ -58,9 +55,9 @@ public class Parser extends BaseRecognizer {
|
|||
if ( expectedTokenType== Token.EOF ) tokenText = "<missing EOF>";
|
||||
else tokenText = "<missing "+getTokenNames()[expectedTokenType]+">";
|
||||
CommonToken t = new CommonToken(expectedTokenType, tokenText);
|
||||
Token current = ((TokenStream)state.input).LT(1);
|
||||
Token current = input.LT(1);
|
||||
if ( current.getType() == Token.EOF ) {
|
||||
current = ((TokenStream)state.input).LT(-1);
|
||||
current = input.LT(-1);
|
||||
}
|
||||
t.line = current.getLine();
|
||||
t.charPositionInLine = current.getCharPositionInLine();
|
||||
|
@ -71,24 +68,24 @@ public class Parser extends BaseRecognizer {
|
|||
|
||||
/** Set the token stream and reset the parser */
|
||||
public void setTokenStream(TokenStream input) {
|
||||
this.state.input = null;
|
||||
this.input = null;
|
||||
reset();
|
||||
this.state.input = input;
|
||||
this.input = input;
|
||||
}
|
||||
|
||||
public TokenStream getTokenStream() {
|
||||
return (TokenStream)state.input;
|
||||
return (TokenStream)input;
|
||||
}
|
||||
|
||||
public String getSourceName() {
|
||||
return state.input.getSourceName();
|
||||
return input.getSourceName();
|
||||
}
|
||||
|
||||
public void traceIn(String ruleName, int ruleIndex) {
|
||||
super.traceIn(ruleName, ruleIndex, ((TokenStream)state.input).LT(1));
|
||||
super.traceIn(ruleName, ruleIndex, input.LT(1));
|
||||
}
|
||||
|
||||
public void traceOut(String ruleName, int ruleIndex) {
|
||||
super.traceOut(ruleName, ruleIndex, ((TokenStream)state.input).LT(1));
|
||||
super.traceOut(ruleName, ruleIndex, input.LT(1));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,98 +0,0 @@
|
|||
/*
|
||||
[The "BSD license"]
|
||||
Copyright (c) 2005-2009 Terence Parr
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The name of the author may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
|
||||
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
|
||||
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package org.antlr.v4.runtime;
|
||||
|
||||
/** The set of fields needed by an abstract recognizer to recognize input
|
||||
* and recover from errors etc... As a separate state object, it can be
|
||||
* shared among multiple grammars; e.g., when one grammar imports another.
|
||||
*/
|
||||
public class ParserSharedState extends RecognizerSharedState<TokenStream> {
|
||||
/** First on stack is fake a call to start rule from S' : S EOF ;
|
||||
* Generated start rule does this.
|
||||
*/
|
||||
// public QStack<RuleContext> ctx;
|
||||
public ParserRuleContext ctx; // tracks local _ctx var to see from outside
|
||||
|
||||
/** This is true when we see an error and before having successfully
|
||||
* matched a token. Prevents generation of more than one error message
|
||||
* per error.
|
||||
*/
|
||||
public boolean errorRecovery = false;
|
||||
|
||||
/** The index into the input stream where the last error occurred.
|
||||
* This is used to prevent infinite loops where an error is found
|
||||
* but no token is consumed during recovery...another error is found,
|
||||
* ad naseum. This is a failsafe mechanism to guarantee that at least
|
||||
* one token/tree node is consumed for two errors.
|
||||
*/
|
||||
public int lastErrorIndex = -1;
|
||||
|
||||
/** In lieu of a return value, this indicates that a rule or token
|
||||
* has failed to match. Reset to false upon valid token match.
|
||||
*/
|
||||
public boolean failed = false;
|
||||
|
||||
/** Did the recognizer encounter a syntax error? Track how many. */
|
||||
public int syntaxErrors = 0;
|
||||
|
||||
/** If 0, no backtracking is going on. Safe to exec actions etc...
|
||||
* If >0 then it's the level of backtracking.
|
||||
*/
|
||||
// public int backtracking = 0;
|
||||
|
||||
/** An array[size num rules] of Map<Integer,Integer> that tracks
|
||||
* the stop token index for each rule. ruleMemo[ruleIndex] is
|
||||
* the memoization table for ruleIndex. For key ruleStartIndex, you
|
||||
* get back the stop token for associated rule or MEMO_RULE_FAILED.
|
||||
*
|
||||
* This is only used if rule memoization is on (which it is by default).
|
||||
*/
|
||||
// public Map[] ruleMemo;
|
||||
|
||||
public ParserSharedState() {
|
||||
// ctx = new RuleContext(); // implicit call to start rule
|
||||
}
|
||||
|
||||
@Override
|
||||
public ParserRuleContext getContext() {
|
||||
return ctx;
|
||||
}
|
||||
|
||||
// public RecognizerSharedState(RecognizerSharedState state) {
|
||||
// this.ctx = state.ctx;
|
||||
// this.errorRecovery = state.errorRecovery;
|
||||
// this.lastErrorIndex = state.lastErrorIndex;
|
||||
// this.failed = state.failed;
|
||||
// this.syntaxErrors = state.syntaxErrors;
|
||||
// this.backtracking = state.backtracking;
|
||||
// if ( state.ruleMemo!=null ) {
|
||||
// this.ruleMemo = new Map[state.ruleMemo.length];
|
||||
// System.arraycopy(state.ruleMemo, 0, this.ruleMemo, 0, state.ruleMemo.length);
|
||||
// }
|
||||
// }
|
||||
}
|
|
@ -27,9 +27,8 @@
|
|||
*/
|
||||
package org.antlr.v4.runtime;
|
||||
|
||||
import org.antlr.runtime.CharStream;
|
||||
import org.antlr.runtime.tree.*;
|
||||
import org.antlr.v4.misc.IntervalSet;
|
||||
import org.antlr.v4.runtime.tree.*;
|
||||
|
||||
/** The root of the ANTLR exception hierarchy.
|
||||
*
|
||||
|
@ -187,11 +186,11 @@ public class RecognitionException extends RuntimeException {
|
|||
/** Return the token type or char of the unexpected input element */
|
||||
public int getUnexpectedType() {
|
||||
if ( recognizer==null ) return token.getType();
|
||||
if ( recognizer.state.input instanceof TokenStream) {
|
||||
if ( recognizer.input instanceof TokenStream) {
|
||||
return token.getType();
|
||||
}
|
||||
else if ( recognizer.state.input instanceof TreeNodeStream ) {
|
||||
TreeNodeStream nodes = (TreeNodeStream)recognizer.state.input;
|
||||
else if ( recognizer.input instanceof TreeNodeStream) {
|
||||
TreeNodeStream nodes = (TreeNodeStream)recognizer.input;
|
||||
TreeAdaptor adaptor = nodes.getTreeAdaptor();
|
||||
return adaptor.getType(node);
|
||||
}
|
||||
|
|
|
@ -4,21 +4,13 @@ import org.antlr.v4.runtime.atn.ATN;
|
|||
|
||||
import java.util.*;
|
||||
|
||||
public class Recognizer<SharedState extends RecognizerSharedState, ATNInterpreter> {
|
||||
public class Recognizer<ATNInterpreter> {
|
||||
public static final int EOF=-1;
|
||||
|
||||
protected List<ANTLRParserListener> listeners;
|
||||
|
||||
protected ATNInterpreter _interp;
|
||||
|
||||
/** State of a lexer, parser, or tree parser are collected into a state
|
||||
* object so the state can be shared. This sharing is needed to
|
||||
* have one grammar import others and share same error variables
|
||||
* and other state variables. It's a kind of explicit multiple
|
||||
* inheritance via delegation of methods and shared state.
|
||||
*/
|
||||
public SharedState state;
|
||||
|
||||
/** Used to print out token names like ID during debugging and
|
||||
* error reporting. The generated parsers implement a method
|
||||
* that overrides this to point to their String[] tokenNames.
|
||||
|
|
|
@ -98,7 +98,7 @@ public class ATNConfig {
|
|||
return toString(null, true);
|
||||
}
|
||||
|
||||
public String toString(Recognizer<?,?> recog, boolean showAlt) {
|
||||
public String toString(Recognizer<?> recog, boolean showAlt) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
if ( state.ruleIndex>0 ) {
|
||||
if ( recog!=null ) buf.append(recog.getRuleNames()[state.ruleIndex]+":");
|
||||
|
|
|
@ -54,7 +54,7 @@ public class LexerInterpreter extends ATNInterpreter {
|
|||
}
|
||||
|
||||
public int exec(CharStream input, DFAState s0) {
|
||||
if ( dfa_debug ) System.out.println("DFA[mode "+(recog==null?0:recog.state.mode)+"] exec LA(1)=="+
|
||||
if ( dfa_debug ) System.out.println("DFA[mode "+(recog==null?0:recog.mode)+"] exec LA(1)=="+
|
||||
(char)input.LA(1));
|
||||
//System.out.println("DFA start of execDFA: "+dfa[mode].toLexerString());
|
||||
int prevAcceptMarker = -1;
|
||||
|
|
|
@ -27,10 +27,7 @@
|
|||
*/
|
||||
package org.antlr.v4.runtime.tree;
|
||||
|
||||
import org.antlr.v4.runtime.ParserSharedState;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.RecognizerSharedState;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
/**
|
||||
Cut-n-paste from material I'm not using in the book anymore (edit later
|
||||
|
@ -97,7 +94,6 @@ public class TreeFilter extends TreeParser {
|
|||
if ( t==null ) return;
|
||||
try {
|
||||
// share TreeParser object but not parsing-related state
|
||||
state = new ParserSharedState();
|
||||
input = new CommonTreeNodeStream(originalAdaptor, t);
|
||||
((CommonTreeNodeStream)input).setTokenStream(originalTokenStream);
|
||||
whichRule.rule();
|
||||
|
|
|
@ -27,11 +27,9 @@
|
|||
*/
|
||||
package org.antlr.v4.runtime.tree;
|
||||
|
||||
import org.antlr.runtime.BitSet;
|
||||
import org.antlr.v4.runtime.*;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.*;
|
||||
|
||||
/** A parser for a stream of tree nodes. "tree grammars" result in a subclass
|
||||
* of this. All the error reporting and recovery is shared with Parser via
|
||||
|
@ -85,8 +83,7 @@ public class TreeParser extends BaseRecognizer {
|
|||
|
||||
protected Object getMissingSymbol(IntStream input,
|
||||
RecognitionException e,
|
||||
int expectedTokenType,
|
||||
BitSet follow)
|
||||
int expectedTokenType)
|
||||
{
|
||||
String tokenText =
|
||||
"<missing "+getTokenNames()[expectedTokenType]+">";
|
||||
|
@ -99,8 +96,8 @@ public class TreeParser extends BaseRecognizer {
|
|||
* corresponding UP node.
|
||||
*/
|
||||
public void matchAny(IntStream ignore) { // ignore stream, copy of input
|
||||
state.errorRecovery = false;
|
||||
state.failed = false;
|
||||
errorRecovery = false;
|
||||
failed = false;
|
||||
Object look = input.LT(1);
|
||||
if ( input.getTreeAdaptor().getChildCount(look)==0 ) {
|
||||
input.consume(); // not subtree, consume 1 node and return
|
||||
|
@ -129,8 +126,7 @@ public class TreeParser extends BaseRecognizer {
|
|||
* from tree parser errors inline...
|
||||
*/
|
||||
protected Object recoverFromMismatchedToken(IntStream input,
|
||||
int ttype,
|
||||
BitSet follow)
|
||||
int ttype)
|
||||
throws RecognitionException
|
||||
{
|
||||
//throw new MismatchedTreeNodeException(ttype, (TreeNodeStream)input);
|
||||
|
|
|
@ -19,7 +19,6 @@ import org.antlr.v4.runtime.NoViableAltException;
|
|||
import org.antlr.v4.runtime.Parser;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.EarlyExitException;
|
||||
import org.antlr.v4.runtime.ParserSharedState;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.FailedPredicateException;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
@ -28,7 +27,6 @@ import org.antlr.v4.runtime.atn.*;
|
|||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
import org.antlr.runtime.*;
|
||||
|
||||
<parser>
|
||||
>>
|
||||
|
@ -84,10 +82,7 @@ case <index> : <actions.(index)> break;}; separator="\n">
|
|||
|
||||
ctor(p) ::= <<
|
||||
public <p.name>(TokenStream input) {
|
||||
this(input, new ParserSharedState());
|
||||
}
|
||||
public <p.name>(TokenStream input, ParserSharedState state) {
|
||||
super(input, state);
|
||||
super(input);
|
||||
_interp = new ParserInterpreter(this,_ATN);
|
||||
}
|
||||
>>
|
||||
|
@ -103,9 +98,9 @@ RuleFunction(currentRule,code,decls,context,scope,namedActions,finallyAction) ::
|
|||
<context>
|
||||
<scope>
|
||||
|
||||
<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>(ParserRuleContext _ctx) throws RecognitionException {
|
||||
<if(currentRule.modifiers)><currentRule.modifiers:{f | <f> }><else>public final <endif><currentRule.ctxType> <currentRule.name>() throws RecognitionException {
|
||||
_ctx = new ParserRuleContext(_ctx, <currentRule.startState>);
|
||||
state.ctx = _ctx;
|
||||
ParserRuleContext _thisctx = _ctx;
|
||||
<if(currentRule.scope)>
|
||||
<currentRule.scope.name>_stack.push(new <currentRule.scope.name>());
|
||||
<endif>
|
||||
|
@ -125,10 +120,10 @@ RuleFunction(currentRule,code,decls,context,scope,namedActions,finallyAction) ::
|
|||
<currentRule.globalScopesUsed:{s | <s>_stack.pop();}; separator="\n">
|
||||
<if(currentRule.scope)><currentRule.scope.name>_stack.pop();<endif>
|
||||
<finallyAction>
|
||||
state.ctx = (ParserRuleContext)_ctx.parent;
|
||||
_ctx = (ParserRuleContext)_ctx.parent;
|
||||
//System.out.println("exit "+ruleNames[<currentRule.index>]);
|
||||
}
|
||||
return _ctx;
|
||||
return _thisctx;
|
||||
}
|
||||
>>
|
||||
|
||||
|
@ -137,7 +132,7 @@ CodeBlock(c, ops) ::= <<
|
|||
>>
|
||||
|
||||
LL1AltBlock(choice, alts, error) ::= <<
|
||||
switch ( state.input.LA(1) ) {
|
||||
switch ( input.LA(1) ) {
|
||||
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
|
@ -147,7 +142,7 @@ switch ( state.input.LA(1) ) {
|
|||
>>
|
||||
|
||||
LL1OptionalBlock(choice, alts, error) ::= <<
|
||||
switch ( state.input.LA(1) ) {
|
||||
switch ( input.LA(1) ) {
|
||||
<choice.altLook,alts:{look,alt| <cases(ttypes=look)>
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
|
@ -167,7 +162,7 @@ if ( <expr> ) {
|
|||
LL1StarBlock(choice, alts, sync) ::= <<
|
||||
<choice.loopLabel>:
|
||||
while (true) {
|
||||
switch ( state.input.LA(1) ) {
|
||||
switch ( input.LA(1) ) {
|
||||
<choice.altLook,alts:{look,alt| <cases(look)>
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
|
@ -190,7 +185,7 @@ while ( <loopExpr> ) {
|
|||
LL1PlusBlock(choice, alts, iteration, loopExpr, sync, error, iterationSync) ::= <<
|
||||
//<sync>
|
||||
do {
|
||||
switch ( state.input.LA(1) ) {
|
||||
switch ( input.LA(1) ) {
|
||||
<choice.altLook,alts:{look,alt| <cases(look)>
|
||||
<alt>
|
||||
break;}; separator="\n">
|
||||
|
@ -217,7 +212,7 @@ do {
|
|||
// LL(*) stuff
|
||||
|
||||
AltBlock(choice, alts, error) ::= <<
|
||||
switch ( _interp.adaptivePredict(state.input,<choice.decision>,_ctx) ) {
|
||||
switch ( _interp.adaptivePredict(input,<choice.decision>,_ctx) ) {
|
||||
<alts:{alt |
|
||||
case <i>:
|
||||
<alt>
|
||||
|
@ -228,7 +223,7 @@ case <i>:
|
|||
>>
|
||||
|
||||
OptionalBlock(choice, alts, error) ::= <<
|
||||
switch ( _interp.adaptivePredict(state.input,<choice.decision>,_ctx) ) {
|
||||
switch ( _interp.adaptivePredict(input,<choice.decision>,_ctx) ) {
|
||||
<alts:{alt |
|
||||
case <i>:
|
||||
<alt>
|
||||
|
@ -237,7 +232,7 @@ case <i>:
|
|||
>>
|
||||
|
||||
StarBlock(choice, alts, sync) ::= <<
|
||||
int _alt<choice.uniqueID> = _interp.adaptivePredict(state.input,<choice.decision>,_ctx);
|
||||
int _alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
|
||||
while ( _alt<choice.uniqueID>!=<choice.exitAlt> ) {
|
||||
switch ( _alt<choice.uniqueID> ) {
|
||||
<alts:{alt|
|
||||
|
@ -245,12 +240,12 @@ case <i>:
|
|||
<alt>
|
||||
break;}; separator="\n">
|
||||
}
|
||||
_alt<choice.uniqueID> = _interp.adaptivePredict(state.input,<choice.decision>,_ctx);
|
||||
_alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
|
||||
}
|
||||
>>
|
||||
|
||||
PlusBlock(choice, alts, error) ::= <<
|
||||
int _alt<choice.uniqueID> = _interp.adaptivePredict(state.input,<choice.decision>,_ctx);
|
||||
int _alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
|
||||
do {
|
||||
switch ( _alt<choice.uniqueID> ) {
|
||||
<alts:{alt|
|
||||
|
@ -260,7 +255,7 @@ case <i>:
|
|||
default :
|
||||
<error>
|
||||
}
|
||||
_alt<choice.uniqueID> = _interp.adaptivePredict(state.input,<choice.decision>,_ctx);
|
||||
_alt<choice.uniqueID> = _interp.adaptivePredict(input,<choice.decision>,_ctx);
|
||||
} while ( _alt<choice.uniqueID>!=<choice.exitAlt> );
|
||||
>>
|
||||
|
||||
|
@ -278,7 +273,7 @@ cases(ttypes) ::= <<
|
|||
|
||||
InvokeRule(r) ::= <<
|
||||
_ctx.s = <r.stateNumber>;
|
||||
<if(r.labels)><r.labels:{l | <l> = }><endif><r.name>(_ctx<r.argExprs:{e| ,<e>}>);
|
||||
<if(r.labels)><r.labels:{l | <l> = }><endif><r.name>(<r.argExprs:{e| ,<e>}>);
|
||||
>>
|
||||
|
||||
MatchToken(m) ::= <<
|
||||
|
@ -293,7 +288,7 @@ Action(a, chunks) ::= "<chunks>"
|
|||
ForcedAction(a, chunks) ::= "<chunks>"
|
||||
|
||||
SemPred(p, chunks) ::= <<
|
||||
if (!(<chunks>)) throw new FailedPredicateException(this, state.input, "<currentRule.name>", ""<!"<chunks>"!>);
|
||||
if (!(<chunks>)) throw new FailedPredicateException(this, input, "<currentRule.name>", ""<!"<chunks>"!>);
|
||||
>>
|
||||
|
||||
ActionText(t) ::= "<t.text>"
|
||||
|
@ -317,7 +312,7 @@ TokenPropertyRef_int(t) ::= "(<t.label>!=null?Integer.valueOf(<t.label>.getText(
|
|||
RulePropertyRef_start(r) ::= "(<r.label>!=null?((<file.TokenLabelType>)<r.label>.start):null)"
|
||||
RulePropertyRef_stop(r) ::= "(<r.label>!=null?((<file.TokenLabelType>)<r.label>.stop):null)"
|
||||
RulePropertyRef_tree(r) ::= "(<r.label>!=null?((<file.ASTLabelType>)<r.label>.tree):null)"
|
||||
RulePropertyRef_text(r) ::= "(<r.label>!=null?((TokenStream)state.input).toString(<r.label>.start,<r.label>.stop):null)"
|
||||
RulePropertyRef_text(r) ::= "(<r.label>!=null?((TokenStream)input).toString(<r.label>.start,<r.label>.stop):null)"
|
||||
RulePropertyRef_st(r) ::= "(<r.label>!=null?<r.label>.st:null)"
|
||||
|
||||
DynScopeRef(s) ::= "<s.scope>_stack"
|
||||
|
@ -340,8 +335,8 @@ TokenTypeDecl(t) ::= "int <t.name>;"
|
|||
TokenListDecl(t) ::= "List\<Token> <t.name> = new ArrayList\<Token>();"
|
||||
RuleContextDecl(r) ::= "<r.ctxName> <r.name>;"
|
||||
|
||||
CaptureNextToken(d) ::= "<d.varName> = state.input.LT(1);"
|
||||
CaptureNextTokenType(d) ::= "<d.varName> = state.input.LA(1);"
|
||||
CaptureNextToken(d) ::= "<d.varName> = input.LT(1);"
|
||||
CaptureNextTokenType(d) ::= "<d.varName> = input.LA(1);"
|
||||
|
||||
StructDecl(s,attrs) ::= <<
|
||||
public static class <s.name> extends ParserRuleContext {
|
||||
|
@ -377,14 +372,12 @@ LexerFile(lexerFile, lexer, namedActions) ::= <<
|
|||
<namedActions.header>
|
||||
import org.antlr.v4.runtime.Lexer;
|
||||
import org.antlr.v4.runtime.CharStream;
|
||||
import org.antlr.v4.runtime.LexerSharedState;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.*;
|
||||
import org.antlr.v4.runtime.atn.*;
|
||||
import org.antlr.v4.runtime.dfa.DFA;
|
||||
import org.antlr.v4.runtime.misc.*;
|
||||
import org.antlr.runtime.*;
|
||||
|
||||
<lexer>
|
||||
>>
|
||||
|
@ -407,10 +400,7 @@ public class <lexer.name> extends Lexer {
|
|||
<namedActions.members>
|
||||
|
||||
public <lexer.name>(CharStream input) {
|
||||
this(input, new LexerSharedState());
|
||||
}
|
||||
public <lexer.name>(CharStream input, LexerSharedState state) {
|
||||
super(input,state);
|
||||
super(input);
|
||||
_interp = new LexerInterpreter(this,_ATN);
|
||||
}
|
||||
|
||||
|
|
|
@ -742,7 +742,7 @@ public abstract class BaseTest {
|
|||
" <lexerName> lex = new <lexerName>(input);\n" +
|
||||
" CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
|
||||
" <createParser>\n"+
|
||||
" parser.<parserStartRuleName>(null);\n" +
|
||||
" parser.<parserStartRuleName>();\n" +
|
||||
" }\n" +
|
||||
"}"
|
||||
);
|
||||
|
@ -804,7 +804,7 @@ public abstract class BaseTest {
|
|||
" <lexerName> lex = new <lexerName>(input);\n" +
|
||||
" TokenRewriteStream tokens = new TokenRewriteStream(lex);\n" +
|
||||
" <createParser>\n"+
|
||||
" ParserRuleContext r = parser.<parserStartRuleName>(null);\n" +
|
||||
" ParserRuleContext r = parser.<parserStartRuleName>();\n" +
|
||||
" <if(!treeParserStartRuleName)>\n" +
|
||||
" if ( r.tree!=null ) {\n" +
|
||||
" System.out.println(((Tree)r.tree).toStringTree());\n" +
|
||||
|
@ -860,7 +860,7 @@ public abstract class BaseTest {
|
|||
" <lexerName> lex = new <lexerName>(input);\n" +
|
||||
" TokenRewriteStream tokens = new TokenRewriteStream(lex);\n" +
|
||||
" <createParser>\n"+
|
||||
" ParserRuleContext r = parser.<parserStartRuleName>(null);\n" +
|
||||
" ParserRuleContext r = parser.<parserStartRuleName>();\n" +
|
||||
" ((CommonTree)r.tree).sanityCheckParentAndChildIndexes();\n" +
|
||||
" CommonTreeNodeStream nodes = new CommonTreeNodeStream((Tree)r.tree);\n" +
|
||||
" nodes.setTokenStream(tokens);\n" +
|
||||
|
@ -918,7 +918,7 @@ public abstract class BaseTest {
|
|||
" CommonTokenStream tokens = new CommonTokenStream(lex);\n" +
|
||||
" <createParser>\n"+
|
||||
" parser.setTemplateLib(group);\n"+
|
||||
" ParserRuleContext r = parser.<parserStartRuleName>(null);\n" +
|
||||
" ParserRuleContext r = parser.<parserStartRuleName>();\n" +
|
||||
" if ( r.st!=null )\n" +
|
||||
" System.out.print(r.st.toString());\n" +
|
||||
" else\n" +
|
||||
|
|
|
@ -7,7 +7,7 @@ public class TestParserExec extends BaseTest {
|
|||
@Test public void testBasic() throws Exception {
|
||||
String grammar =
|
||||
"grammar T;\n" +
|
||||
"a : ID INT {System.out.println(state.input);} ;\n" +
|
||||
"a : ID INT {System.out.println(input);} ;\n" +
|
||||
"ID : 'a'..'z'+ ;\n" +
|
||||
"INT : '0'..'9'+;\n" +
|
||||
"WS : (' '|'\\n') {skip();} ;\n";
|
||||
|
|
|
@ -138,7 +138,7 @@ public class TestTokenTypeAssignment extends BaseTest {
|
|||
String grammar =
|
||||
"grammar P;\n" +
|
||||
"tokens { B='}'; }\n"+
|
||||
"a : A B {System.out.println(state.input);} ;\n"+
|
||||
"a : A B {System.out.println(input);} ;\n"+
|
||||
"A : 'a' ;\n" +
|
||||
"B : '}' ;\n"+
|
||||
"WS : (' '|'\\n') {skip();} ;";
|
||||
|
@ -153,7 +153,7 @@ public class TestTokenTypeAssignment extends BaseTest {
|
|||
String grammar =
|
||||
"grammar P;\n" +
|
||||
"tokens { B='}'; }\n"+
|
||||
"a : A '}' {System.out.println(state.input);} ;\n"+
|
||||
"a : A '}' {System.out.println(input);} ;\n"+
|
||||
"A : 'a' ;\n" +
|
||||
"B : '}' {/* */} ;\n"+
|
||||
"WS : (' '|'\\n') {skip();} ;";
|
||||
|
|
Loading…
Reference in New Issue