Search in sources :

Example 1 with AmbiguityInfo

use of org.antlr.v4.runtime.atn.AmbiguityInfo in project antlr4 by antlr.

the class GrammarParserInterpreter method getAllPossibleParseTrees.

/** 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.
	 *
	 *  The list of trees includes the actual interpretation (that for
	 *  the minimum alternative number) and all ambiguous alternatives.
	 *  The actual interpretation is always first.
	 *
	 *  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 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 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.
	 *
	 *  This uses a temporary ParserATNSimulator and a ParserInterpreter
	 *  so we don't mess up any statistics, event lists, etc...
	 *  The parse tree constructed while identifying/making ambiguityInfo is
	 *  not affected by this method as it creates a new parser interp to
	 *  get the ambiguous interpretations.
	 *
	 *  Nodes in the returned ambig trees are independent of the original parse
	 *  tree (constructed while identifying/creating ambiguityInfo).
	 *
	 *  @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 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.
	 *
	 *  @return               The list of all possible interpretations of
	 *                        the input for the decision in ambiguityInfo.
	 *                        The actual interpretation chosen by the parser
	 *                        is always given first because this method
	 *                        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) throws RecognitionException {
    List<ParserRuleContext> trees = new ArrayList<ParserRuleContext>();
    // Create a new parser interpreter to parse the ambiguous subphrase
    ParserInterpreter parser = deriveTempParserInterpreter(g, originalParser, tokens);
    if (stopIndex >= (tokens.size() - 1)) {
        // if we are pointing at EOF token
        // EOF is not in tree, so must be 1 less than last non-EOF token
        stopIndex = tokens.size() - 2;
    }
    // get ambig trees
    int alt = alts.nextSetBit(0);
    while (alt >= 0) {
        // re-parse entire input for all ambiguous alternatives
        // (don't have to do first as it's been parsed, but do again for simplicity
        //  using this temp parser.)
        parser.reset();
        parser.addDecisionOverride(decision, startIndex, alt);
        ParserRuleContext t = parser.parse(startRuleIndex);
        GrammarInterpreterRuleContext ambigSubTree = (GrammarInterpreterRuleContext) Trees.getRootOfSubtreeEnclosingRegion(t, startIndex, stopIndex);
        // Use higher of overridden decision tree or tree enclosing all tokens
        if (Trees.isAncestorOf(parser.getOverrideDecisionRoot(), ambigSubTree)) {
            ambigSubTree = (GrammarInterpreterRuleContext) parser.getOverrideDecisionRoot();
        }
        trees.add(ambigSubTree);
        alt = alts.nextSetBit(alt + 1);
    }
    return trees;
}
Also used : ParserRuleContext(org.antlr.v4.runtime.ParserRuleContext) ParserInterpreter(org.antlr.v4.runtime.ParserInterpreter) ArrayList(java.util.ArrayList)

Example 2 with AmbiguityInfo

use of org.antlr.v4.runtime.atn.AmbiguityInfo in project antlr4 by antlr.

the class TestAmbigParseTrees method testAmbiguousTrees.

public void testAmbiguousTrees(LexerGrammar lg, Grammar g, String startRule, String input, int decision, String expectedAmbigAlts, String overallTree, String[] expectedParseTrees) {
    InterpreterTreeTextProvider nodeTextProvider = new InterpreterTreeTextProvider(g.getRuleNames());
    LexerInterpreter lexEngine = lg.createLexerInterpreter(new ANTLRInputStream(input));
    CommonTokenStream tokens = new CommonTokenStream(lexEngine);
    final GrammarParserInterpreter parser = g.createGrammarParserInterpreter(tokens);
    parser.setProfile(true);
    parser.getInterpreter().setPredictionMode(PredictionMode.LL_EXACT_AMBIG_DETECTION);
    // PARSE
    int ruleIndex = g.rules.get(startRule).index;
    ParserRuleContext parseTree = parser.parse(ruleIndex);
    assertEquals(overallTree, Trees.toStringTree(parseTree, nodeTextProvider));
    System.out.println();
    DecisionInfo[] decisionInfo = parser.getParseInfo().getDecisionInfo();
    List<AmbiguityInfo> ambiguities = decisionInfo[decision].ambiguities;
    assertEquals(1, ambiguities.size());
    AmbiguityInfo ambiguityInfo = ambiguities.get(0);
    List<ParserRuleContext> ambiguousParseTrees = GrammarParserInterpreter.getAllPossibleParseTrees(g, parser, tokens, decision, ambiguityInfo.ambigAlts, ambiguityInfo.startIndex, ambiguityInfo.stopIndex, ruleIndex);
    assertEquals(expectedAmbigAlts, ambiguityInfo.ambigAlts.toString());
    assertEquals(ambiguityInfo.ambigAlts.cardinality(), ambiguousParseTrees.size());
    for (int i = 0; i < ambiguousParseTrees.size(); i++) {
        ParserRuleContext t = ambiguousParseTrees.get(i);
        assertEquals(expectedParseTrees[i], Trees.toStringTree(t, nodeTextProvider));
    }
}
Also used : CommonTokenStream(org.antlr.v4.runtime.CommonTokenStream) ParserRuleContext(org.antlr.v4.runtime.ParserRuleContext) LexerInterpreter(org.antlr.v4.runtime.LexerInterpreter) GrammarParserInterpreter(org.antlr.v4.tool.GrammarParserInterpreter) DecisionInfo(org.antlr.v4.runtime.atn.DecisionInfo) AmbiguityInfo(org.antlr.v4.runtime.atn.AmbiguityInfo) ANTLRInputStream(org.antlr.v4.runtime.ANTLRInputStream)

Aggregations

ParserRuleContext (org.antlr.v4.runtime.ParserRuleContext)2 ArrayList (java.util.ArrayList)1 ANTLRInputStream (org.antlr.v4.runtime.ANTLRInputStream)1 CommonTokenStream (org.antlr.v4.runtime.CommonTokenStream)1 LexerInterpreter (org.antlr.v4.runtime.LexerInterpreter)1 ParserInterpreter (org.antlr.v4.runtime.ParserInterpreter)1 AmbiguityInfo (org.antlr.v4.runtime.atn.AmbiguityInfo)1 DecisionInfo (org.antlr.v4.runtime.atn.DecisionInfo)1 GrammarParserInterpreter (org.antlr.v4.tool.GrammarParserInterpreter)1