removed state stuff

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 8726]
This commit is contained in:
parrt 2011-06-22 14:45:28 -08:00
parent 981aff4132
commit 4e3fd8446d
23 changed files with 236 additions and 373 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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;
}

View File

@ -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();
}
}

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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() {

View File

@ -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() {

View File

@ -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() {

View File

@ -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();
}

View File

@ -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));
}
}

View File

@ -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);
// }
// }
}

View File

@ -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);
}

View File

@ -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.

View File

@ -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]+":");

View File

@ -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;

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -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" +

View File

@ -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";

View File

@ -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();} ;";