Exemplo n.º 1
0
 /** identify the ATN states where we need to set the outer alt number.
  *  For regular rules, that's the block at the target to rule start state.
  *  For left-recursive rules, we track the primary block, which looks just
  *  like a regular rule's outer block, and the star loop block (always
  *  there even if 1 alt).
  */
 public virtual BitSet FindOuterMostDecisionStates()
 {
     BitSet track = new BitSet(atn.states.Count);
     int numberOfDecisions = atn.NumberOfDecisions;
     for (int i = 0; i < numberOfDecisions; i++)
     {
         DecisionState decisionState = atn.GetDecisionState(i);
         RuleStartState startState = atn.ruleToStartState[decisionState.ruleIndex];
         // Look for StarLoopEntryState that is in any left recursive rule
         if (decisionState is StarLoopEntryState)
         {
             StarLoopEntryState loopEntry = (StarLoopEntryState)decisionState;
             if (loopEntry.precedenceRuleDecision)
             {
                 // Recursive alts always result in a (...)* in the transformed
                 // left recursive rule and that always has a BasicBlockStartState
                 // even if just 1 recursive alt exists.
                 ATNState blockStart = loopEntry.Transition(0).target;
                 // track the StarBlockStartState associated with the recursive alternatives
                 track.Set(blockStart.stateNumber);
             }
         }
         else if (startState.Transition(0).target == decisionState)
         {
             // always track outermost block for any rule if it exists
             track.Set(decisionState.stateNumber);
         }
     }
     return track;
 }
Exemplo n.º 2
0
        /** identify the ATN states where we need to set the outer alt number.
         *  For regular rules, that's the block at the target to rule start state.
         *  For left-recursive rules, we track the primary block, which looks just
         *  like a regular rule's outer block, and the star loop block (always
         *  there even if 1 alt).
         */
        public virtual BitSet FindOuterMostDecisionStates()
        {
            BitSet track             = new BitSet(atn.states.Count);
            int    numberOfDecisions = atn.NumberOfDecisions;

            for (int i = 0; i < numberOfDecisions; i++)
            {
                DecisionState  decisionState = atn.GetDecisionState(i);
                RuleStartState startState    = atn.ruleToStartState[decisionState.ruleIndex];
                // Look for StarLoopEntryState that is in any left recursive rule
                if (decisionState is StarLoopEntryState)
                {
                    StarLoopEntryState loopEntry = (StarLoopEntryState)decisionState;
                    if (loopEntry.precedenceRuleDecision)
                    {
                        // Recursive alts always result in a (...)* in the transformed
                        // left recursive rule and that always has a BasicBlockStartState
                        // even if just 1 recursive alt exists.
                        ATNState blockStart = loopEntry.Transition(0).target;
                        // track the StarBlockStartState associated with the recursive alternatives
                        track.Set(blockStart.stateNumber);
                    }
                }
                else if (startState.Transition(0).target == decisionState)
                {
                    // always track outermost block for any rule if it exists
                    track.Set(decisionState.stateNumber);
                }
            }
            return(track);
        }
Exemplo n.º 3
0
 public GrammarParserInterpreter(Grammar g, ATN atn, ITokenStream input)
     : base(g.fileName, g.GetVocabulary(),
           g.GetRuleNames(),
           atn, // must run ATN through serializer to set some state flags
           input)
 {
     this.g = g;
     decisionStatesThatSetOuterAltNumInContext = FindOuterMostDecisionStates();
     stateToAltsMap = new int[g.atn.states.Count][];
 }
Exemplo n.º 4
0
 public GrammarParserInterpreter(Grammar g, ATN atn, ITokenStream input)
     : base(g.fileName, g.GetVocabulary(),
            g.GetRuleNames(),
            atn, // must run ATN through serializer to set some state flags
            input)
 {
     this.g = g;
     decisionStatesThatSetOuterAltNumInContext = FindOuterMostDecisionStates();
     stateToAltsMap = new int[g.atn.states.Count][];
 }
Exemplo n.º 5
0
        /** 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 IList <ParserRuleContext> GetAllPossibleParseTrees(Grammar g,
                                                                         Parser originalParser,
                                                                         ITokenStream tokens,
                                                                         int decision,
                                                                         BitSet alts,
                                                                         int startIndex,
                                                                         int stopIndex,
                                                                         int startRuleIndex)
        {
            IList <ParserRuleContext> trees = new List <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.OverrideDecisionRoot, ambigSubTree))
                {
                    ambigSubTree = (GrammarInterpreterRuleContext)parser.OverrideDecisionRoot;
                }
                trees.Add(ambigSubTree);
                alt = alts.NextSetBit(alt + 1);
            }

            return(trees);
        }
Exemplo n.º 6
0
        /** 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 IList<ParserRuleContext> GetAllPossibleParseTrees(Grammar g,
                                                                       Parser originalParser,
                                                                       ITokenStream tokens,
                                                                       int decision,
                                                                       BitSet alts,
                                                                       int startIndex,
                                                                       int stopIndex,
                                                                       int startRuleIndex)
        {
            IList<ParserRuleContext> trees = new List<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.OverrideDecisionRoot, ambigSubTree))
                {
                    ambigSubTree = (GrammarInterpreterRuleContext)parser.OverrideDecisionRoot;
                }
                trees.Add(ambigSubTree);
                alt = alts.NextSetBit(alt + 1);
            }

            return trees;
        }