update the comments.
This commit is contained in:
parent
94bef386cb
commit
11726e072e
|
@ -321,6 +321,10 @@ public class ParserInterpreter extends Parser {
|
|||
setState(transition.target.stateNumber);
|
||||
}
|
||||
|
||||
/** Method visitDecisionState() is called when the interpreter reaches
|
||||
* a decision state (instance of DecisionState). It gives an opportunity
|
||||
* for subclasses to track interesting things.
|
||||
*/
|
||||
protected int visitDecisionState(DecisionState p) {
|
||||
int predictedAlt = 1;
|
||||
if ( p.getNumberOfTransitions()>1 ) {
|
||||
|
@ -339,7 +343,9 @@ public class ParserInterpreter extends Parser {
|
|||
return predictedAlt;
|
||||
}
|
||||
|
||||
/** Provide simple "factory" for InterpreterRuleContext's. */
|
||||
/** Provide simple "factory" for InterpreterRuleContext's.
|
||||
* @since 4.5.1
|
||||
*/
|
||||
protected InterpreterRuleContext createInterpreterRuleContext(
|
||||
ParserRuleContext parent,
|
||||
int invokingStateNumber,
|
||||
|
@ -451,6 +457,14 @@ public class ParserInterpreter extends Parser {
|
|||
return _errHandler.recoverInline(this);
|
||||
}
|
||||
|
||||
/** Return the root of the parse, which can be useful if the parser
|
||||
* bails out. You still can access the top node. Note that,
|
||||
* because of the way left recursive rules add children, it's possible
|
||||
* that the root will not have any children if the start rule immediately
|
||||
* called and left recursive rule that fails.
|
||||
*
|
||||
* @since 4.5.1
|
||||
*/
|
||||
public InterpreterRuleContext getRootContext() {
|
||||
return rootContext;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,10 @@ package org.antlr.v4.tool;
|
|||
import org.antlr.v4.runtime.InterpreterRuleContext;
|
||||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
|
||||
/**
|
||||
/** An {@link InterpreterRuleContext} that knows which alternative
|
||||
* for a rule was matched.
|
||||
*
|
||||
* @see GrammarParserInterpreter
|
||||
* @since 4.5.1
|
||||
*/
|
||||
public class GrammarInterpreterRuleContext extends InterpreterRuleContext {
|
||||
|
@ -14,7 +17,7 @@ public class GrammarInterpreterRuleContext extends InterpreterRuleContext {
|
|||
}
|
||||
|
||||
/** The predicted outermost alternative for the rule associated
|
||||
* with this context object. If left recursive, the true original
|
||||
* with this context object. If this node left recursive, the true original
|
||||
* outermost alternative is returned.
|
||||
*/
|
||||
public int getOuterAltNum() { return outerAltNum; }
|
||||
|
|
|
@ -7,7 +7,6 @@ import org.antlr.v4.runtime.ParserInterpreter;
|
|||
import org.antlr.v4.runtime.ParserRuleContext;
|
||||
import org.antlr.v4.runtime.RecognitionException;
|
||||
import org.antlr.v4.runtime.TokenStream;
|
||||
import org.antlr.v4.runtime.UnbufferedTokenStream;
|
||||
import org.antlr.v4.runtime.Vocabulary;
|
||||
import org.antlr.v4.runtime.atn.ATN;
|
||||
import org.antlr.v4.runtime.atn.ATNDeserializer;
|
||||
|
@ -27,6 +26,12 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/** A heavier weight {@link ParserInterpreter} that creates parse trees
|
||||
* that track alternative numbers for subtree roots.
|
||||
*
|
||||
* @since 4.5.1
|
||||
*
|
||||
*/
|
||||
public class GrammarParserInterpreter extends ParserInterpreter {
|
||||
/** The grammar associated with this interpreter. Unlike the
|
||||
* {@link ParserInterpreter} from the standard distribution,
|
||||
|
@ -108,45 +113,51 @@ public class GrammarParserInterpreter extends ParserInterpreter {
|
|||
return track;
|
||||
}
|
||||
|
||||
/**In the case of left-recursive rules,
|
||||
* there is typically a decision for the primary alternatives and a
|
||||
* decision to choose between the recursive operator alternatives.
|
||||
* For example, the following left recursive rule has two primary and 2
|
||||
* recursive alternatives.</p>
|
||||
/** Override this method so that we can record which alternative
|
||||
* was taken at each decision point. For non-left recursive rules,
|
||||
* it's simple. Set decisionStatesThatSetOuterAltNumInContext
|
||||
* indicates which decision states should set the outer alternative number.
|
||||
*
|
||||
e : e '*' e
|
||||
| '-' INT
|
||||
| e '+' e
|
||||
| ID
|
||||
;
|
||||
* Left recursive rules are much more complicated to deal with:
|
||||
* there is typically a decision for the primary alternatives and a
|
||||
* decision to choose between the recursive operator alternatives.
|
||||
* For example, the following left recursive rule has two primary and 2
|
||||
* recursive alternatives.</p>
|
||||
*
|
||||
e : e '*' e
|
||||
| '-' INT
|
||||
| e '+' e
|
||||
| ID
|
||||
;
|
||||
|
||||
* <p>ANTLR rewrites that rule to be</p>
|
||||
* <p>ANTLR rewrites that rule to be</p>
|
||||
|
||||
e[int precedence]
|
||||
: ('-' INT | ID)
|
||||
( {...}? '*' e[5]
|
||||
| {...}? '+' e[3]
|
||||
)*
|
||||
;
|
||||
e[int precedence]
|
||||
: ('-' INT | ID)
|
||||
( {...}? '*' e[5]
|
||||
| {...}? '+' e[3]
|
||||
)*
|
||||
;
|
||||
|
||||
*
|
||||
* <p>So, there are two decisions associated with picking the outermost alt.
|
||||
* This complicates our tracking significantly. The outermost alternative number
|
||||
* is a function of the decision (ATN state) within a left recursive rule and the
|
||||
* predicted alternative coming back from adaptivePredict().
|
||||
* <p>So, there are two decisions associated with picking the outermost alt.
|
||||
* This complicates our tracking significantly. The outermost alternative number
|
||||
* is a function of the decision (ATN state) within a left recursive rule and the
|
||||
* predicted alternative coming back from adaptivePredict().
|
||||
*
|
||||
* We use stateToAltsMap as a cache to avoid expensive calls to
|
||||
* getRecursiveOpAlts().
|
||||
*/
|
||||
@Override
|
||||
protected int visitDecisionState(DecisionState p) {
|
||||
int predictedAlt = super.visitDecisionState(p);
|
||||
if( p.getNumberOfTransitions() > 1) {
|
||||
// System.out.print("decision "+p.decision+": "+predictedAlt);
|
||||
// System.out.println("decision "+p.decision+": "+predictedAlt);
|
||||
if( p.decision == this.overrideDecision &&
|
||||
this._input.index() == this.overrideDecisionInputIndex)
|
||||
this._input.index() == this.overrideDecisionInputIndex )
|
||||
{
|
||||
// System.out.print(" OVERRIDE");
|
||||
overrideDecisionRoot = (GrammarInterpreterRuleContext)getContext();
|
||||
}
|
||||
// System.out.println();
|
||||
}
|
||||
|
||||
GrammarInterpreterRuleContext ctx = (GrammarInterpreterRuleContext)_ctx;
|
||||
|
@ -162,7 +173,7 @@ public class GrammarParserInterpreter extends ParserInterpreter {
|
|||
stateToAltsMap.put(p, alts); // cache it
|
||||
}
|
||||
}
|
||||
else if (p.getStateType() == ATNState.STAR_BLOCK_START) {
|
||||
else if ( p.getStateType() == ATNState.STAR_BLOCK_START ) {
|
||||
if ( alts==null ) {
|
||||
alts = lr.getRecursiveOpAlts();
|
||||
stateToAltsMap.put(p, alts); // cache it
|
||||
|
@ -175,8 +186,7 @@ public class GrammarParserInterpreter extends ParserInterpreter {
|
|||
return predictedAlt;
|
||||
}
|
||||
|
||||
/** Given an AmbiguityInfo object that contains information about an
|
||||
* ambiguous decision event, return the list of ambiguous parse trees.
|
||||
/** Given an ambiguous parse information, return the list of ambiguous parse trees.
|
||||
* An ambiguity occurs when a specific token sequence can be recognized
|
||||
* in more than one way by the grammar. These ambiguities are detected only
|
||||
* at decision points.
|
||||
|
@ -188,14 +198,12 @@ public class GrammarParserInterpreter extends ParserInterpreter {
|
|||
* This method reuses the same physical input token stream used to
|
||||
* detect the ambiguity by the original parser in the first place.
|
||||
* This method resets/seeks within but does not alter originalParser.
|
||||
* The input position is restored upon exit from this method.
|
||||
* Parsers using a {@link UnbufferedTokenStream} may not be able to
|
||||
* perform the necessary save index() / seek(saved_index) operation.
|
||||
*
|
||||
* The trees are rooted at the node whose start..stop token indices
|
||||
* include the start and stop indices of this ambiguity event. That is,
|
||||
* the trees returns will always include the complete ambiguous subphrase
|
||||
* identified by the ambiguity event.
|
||||
* the trees returned will always include the complete ambiguous subphrase
|
||||
* identified by the ambiguity event. The subtrees returned will
|
||||
* also always contain the node associated with the overridden decision.
|
||||
*
|
||||
* Be aware that this method does NOT notify error or parse listeners as
|
||||
* it would trigger duplicate or otherwise unwanted events.
|
||||
|
@ -211,12 +219,29 @@ public class GrammarParserInterpreter extends ParserInterpreter {
|
|||
*
|
||||
* @since 4.5.1
|
||||
*
|
||||
* @param g From which grammar should we drive alternative
|
||||
* numbers and alternative labels.
|
||||
*
|
||||
* @param originalParser The parser used to create ambiguityInfo; it
|
||||
* is not modified by this routine and can be either
|
||||
* a generated or interpreted parser. It's token
|
||||
* stream *is* reset/seek()'d.
|
||||
* @param ambiguityInfo The information about an ambiguous decision event
|
||||
* for which you want ambiguous parse trees.
|
||||
* @param tokens A stream of tokens to use with the temporary parser.
|
||||
* This will often be just the token stream within the
|
||||
* original parser but here it is for flexibility.
|
||||
*
|
||||
* @param decision Which decision to try different alternatives for.
|
||||
*
|
||||
* @param alts The set of alternatives to try while re-parsing.
|
||||
*
|
||||
* @param startIndex The index of the first token of the ambiguous
|
||||
* input or other input of interest.
|
||||
*
|
||||
* @param stopIndex The index of the last token of the ambiguous input.
|
||||
* The start and stop indexes are used primarily to
|
||||
* identify how much of the resulting parse tree
|
||||
* to return.
|
||||
*
|
||||
* @param startRuleIndex The start rule for the entire grammar, not
|
||||
* the ambiguous decision. We re-parse the entire input
|
||||
* and so we need the original start rule.
|
||||
|
@ -228,18 +253,19 @@ public class GrammarParserInterpreter extends ParserInterpreter {
|
|||
* retests the input in alternative order and
|
||||
* ANTLR always resolves ambiguities by choosing
|
||||
* the first alternative that matches the input.
|
||||
* The subtree returned
|
||||
*
|
||||
* @throws RecognitionException Throws upon syntax error while matching
|
||||
* ambig input.
|
||||
*/
|
||||
public static List<ParserRuleContext> getAllPossibleParseTrees(Grammar g,
|
||||
Parser originalParser,
|
||||
TokenStream tokens,
|
||||
int decision,
|
||||
BitSet alts,
|
||||
int startIndex,
|
||||
int stopIndex,
|
||||
int startRuleIndex)
|
||||
public static List<ParserRuleContext> getAllPossibleParseTrees(Grammar g,
|
||||
Parser originalParser,
|
||||
TokenStream tokens,
|
||||
int decision,
|
||||
BitSet alts,
|
||||
int startIndex,
|
||||
int stopIndex,
|
||||
int startRuleIndex)
|
||||
throws RecognitionException
|
||||
{
|
||||
List<ParserRuleContext> trees = new ArrayList<ParserRuleContext>();
|
||||
|
@ -248,7 +274,7 @@ public class GrammarParserInterpreter extends ParserInterpreter {
|
|||
if (originalParser instanceof ParserInterpreter) {
|
||||
parser = new GrammarParserInterpreter(g, originalParser.getATN(), originalParser.getTokenStream());
|
||||
}
|
||||
else {
|
||||
else { // must've been a generated parser
|
||||
char[] serializedAtn = ATNSerializer.getSerializedAsChars(originalParser.getATN());
|
||||
ATN deserialized = new ATNDeserializer().deserialize(serializedAtn);
|
||||
parser = new ParserInterpreter(originalParser.getGrammarFileName(),
|
||||
|
|
Loading…
Reference in New Issue