예제 #1
0
 private static PredictionContext AppendContext(PredictionContext context, PredictionContext suffix, PredictionContext.IdentityHashMap visited)
 {
     if (suffix.IsEmpty)
     {
         if (IsEmptyLocal(suffix))
         {
             if (context.HasEmpty)
             {
                 return EmptyLocal;
             }
             throw new NotSupportedException("what to do here?");
         }
         return context;
     }
     if (suffix.Size != 1)
     {
         throw new NotSupportedException("Appending a tree suffix is not yet supported.");
     }
     PredictionContext result;
     if (!visited.TryGetValue(context, out result))
     {
         if (context.IsEmpty)
         {
             result = suffix;
         }
         else
         {
             int parentCount = context.Size;
             if (context.HasEmpty)
             {
                 parentCount--;
             }
             PredictionContext[] updatedParents = new PredictionContext[parentCount];
             int[] updatedReturnStates = new int[parentCount];
             for (int i = 0; i < parentCount; i++)
             {
                 updatedReturnStates[i] = context.GetReturnState(i);
             }
             for (int i_1 = 0; i_1 < parentCount; i_1++)
             {
                 updatedParents[i_1] = AppendContext(context.GetParent(i_1), suffix, visited);
             }
             if (updatedParents.Length == 1)
             {
                 result = new SingletonPredictionContext(updatedParents[0], updatedReturnStates[0]);
             }
             else
             {
                 System.Diagnostics.Debug.Assert(updatedParents.Length > 1);
                 result = new Antlr4.Runtime.Atn.ArrayPredictionContext(updatedParents, updatedReturnStates);
             }
             if (context.HasEmpty)
             {
                 result = PredictionContext.Join(result, suffix);
             }
         }
         visited[context] = result;
     }
     return result;
 }
예제 #2
0
 /// <summary>
 /// Compute set of tokens that can follow
 /// <code>s</code>
 /// in the ATN in the
 /// specified
 /// <code>ctx</code>
 /// .
 /// <p/>
 /// If
 /// <code>ctx</code>
 /// is
 /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
 /// and
 /// <code>stopState</code>
 /// or the end of the rule containing
 /// <code>s</code>
 /// is reached,
 /// <see cref="TokenConstants.Epsilon"/>
 /// is added to the result set. If
 /// <code>ctx</code>
 /// is not
 /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
 /// and
 /// <code>addEOF</code>
 /// is
 /// <code>true</code>
 /// and
 /// <code>stopState</code>
 /// or the end of the outermost rule is reached,
 /// <see cref="TokenConstants.Eof"/>
 /// is added to the result set.
 /// </summary>
 /// <param name="s">the ATN state.</param>
 /// <param name="stopState">
 /// the ATN state to stop at. This can be a
 /// <see cref="BlockEndState">BlockEndState</see>
 /// to detect epsilon paths through a closure.
 /// </param>
 /// <param name="ctx">
 /// The outer context, or
 /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
 /// if
 /// the outer context should not be used.
 /// </param>
 /// <param name="look">The result lookahead set.</param>
 /// <param name="lookBusy">
 /// A set used for preventing epsilon closures in the ATN
 /// from causing a stack overflow. Outside code should pass
 /// <code>new HashSet&lt;ATNConfig&gt;</code>
 /// for this argument.
 /// </param>
 /// <param name="calledRuleStack">
 /// A set used for preventing left recursion in the
 /// ATN from causing a stack overflow. Outside code should pass
 /// <code>new BitSet()</code>
 /// for this argument.
 /// </param>
 /// <param name="seeThruPreds">
 /// 
 /// <code>true</code>
 /// to true semantic predicates as
 /// implicitly
 /// <code>true</code>
 /// and "see through them", otherwise
 /// <code>false</code>
 /// to treat semantic predicates as opaque and add
 /// <see cref="HitPred">HitPred</see>
 /// to the
 /// result if one is encountered.
 /// </param>
 /// <param name="addEOF">
 /// Add
 /// <see cref="TokenConstants.Eof"/>
 /// to the result if the end of the
 /// outermost context is reached. This parameter has no effect if
 /// <code>ctx</code>
 /// is
 /// <see cref="PredictionContext.EmptyLocal">PredictionContext.EmptyLocal</see>
 /// .
 /// </param>
 protected internal virtual void Look(ATNState s, ATNState stopState, PredictionContext
      ctx, IntervalSet look, HashSet<ATNConfig> lookBusy, BitSet calledRuleStack, 
     bool seeThruPreds, bool addEOF)
 {
     //		System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx);
     ATNConfig c = ATNConfig.Create(s, 0, ctx);
     if (!lookBusy.Add(c))
     {
         return;
     }
     if (s == stopState)
     {
         if (PredictionContext.IsEmptyLocal(ctx))
         {
             look.Add(TokenConstants.Epsilon);
             return;
         }
         else
         {
             if (ctx.IsEmpty && addEOF)
             {
                 look.Add(TokenConstants.Eof);
                 return;
             }
         }
     }
     if (s is RuleStopState)
     {
         if (PredictionContext.IsEmptyLocal(ctx))
         {
             look.Add(TokenConstants.Epsilon);
             return;
         }
         else
         {
             if (ctx.IsEmpty && addEOF)
             {
                 look.Add(TokenConstants.Eof);
                 return;
             }
         }
         for (int i = 0; i < ctx.Size; i++)
         {
             if (ctx.GetReturnState(i) != PredictionContext.EmptyFullStateKey)
             {
                 ATNState returnState = atn.states[ctx.GetReturnState(i)];
                 //					System.out.println("popping back to "+retState);
                 for (int j = 0; j < ctx.Size; j++)
                 {
                     bool removed = calledRuleStack.Get(returnState.ruleIndex);
                     try
                     {
                         calledRuleStack.Clear(returnState.ruleIndex);
                         Look(returnState, stopState, ctx.GetParent(j), look, lookBusy, calledRuleStack, seeThruPreds
                             , addEOF);
                     }
                     finally
                     {
                         if (removed)
                         {
                             calledRuleStack.Set(returnState.ruleIndex);
                         }
                     }
                 }
                 return;
             }
         }
     }
     int n = s.NumberOfTransitions;
     for (int i_1 = 0; i_1 < n; i_1++)
     {
         Transition t = s.Transition(i_1);
         if (t.GetType() == typeof(RuleTransition))
         {
             if (calledRuleStack.Get(((RuleTransition)t).target.ruleIndex))
             {
                 continue;
             }
             PredictionContext newContext = ctx.GetChild(((RuleTransition)t).followState.stateNumber
                 );
             try
             {
                 calledRuleStack.Set(((RuleTransition)t).target.ruleIndex);
                 Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds
                     , addEOF);
             }
             finally
             {
                 calledRuleStack.Clear(((RuleTransition)t).target.ruleIndex);
             }
         }
         else
         {
             if (t is AbstractPredicateTransition)
             {
                 if (seeThruPreds)
                 {
                     Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF
                         );
                 }
                 else
                 {
                     look.Add(HitPred);
                 }
             }
             else
             {
                 if (t.IsEpsilon)
                 {
                     Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF
                         );
                 }
                 else
                 {
                     if (t.GetType() == typeof(WildcardTransition))
                     {
                         look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                     }
                     else
                     {
                         //				System.out.println("adding "+ t);
                         IntervalSet set = t.Label;
                         if (set != null)
                         {
                             if (t is NotSetTransition)
                             {
                                 set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType
                                     ));
                             }
                             look.AddAll(set);
                         }
                     }
                 }
             }
         }
     }
 }
예제 #3
0
        private static String ToDotString(PredictionContext context)
        {
            StringBuilder nodes = new StringBuilder();
            StringBuilder edges = new StringBuilder();
            IDictionary <PredictionContext, PredictionContext> visited = new IdentityHashMap <PredictionContext, PredictionContext>();
            IDictionary <PredictionContext, int> contextIds            = new IdentityHashMap <PredictionContext, int>();
            Stack <PredictionContext>            workList = new Stack <PredictionContext>();

            visited[context]    = context;
            contextIds[context] = contextIds.Count;
            workList.Push(context);
            while (workList.Count > 0)
            {
                PredictionContext current = workList.Pop();
                nodes.Append("  s").Append(contextIds[current]).Append('[');

                if (current.Size > 1)
                {
                    nodes.Append("shape=record, ");
                }

                nodes.Append("label=\"");

                if (current.IsEmpty)
                {
                    nodes.Append(PredictionContext.IsEmptyLocal(current) ? '*' : '$');
                }
                else if (current.Size > 1)
                {
                    for (int i = 0; i < current.Size; i++)
                    {
                        if (i > 0)
                        {
                            nodes.Append('|');
                        }

                        nodes.Append("<p").Append(i).Append('>');
                        if (current.GetReturnState(i) == PredictionContext.EmptyFullStateKey)
                        {
                            nodes.Append('$');
                        }
                        else if (current.GetReturnState(i) == PredictionContext.EmptyLocalStateKey)
                        {
                            nodes.Append('*');
                        }
                    }
                }
                else
                {
                    nodes.Append(contextIds[current]);
                }

                nodes.AppendLine("\"];");

                for (int i = 0; i < current.Size; i++)
                {
                    if (current.GetReturnState(i) == PredictionContext.EmptyFullStateKey ||
                        current.GetReturnState(i) == PredictionContext.EmptyLocalStateKey)
                    {
                        continue;
                    }

                    if (!visited.ContainsKey(current.GetParent(i)))
                    {
                        visited[current.GetParent(i)]    = current.GetParent(i);
                        contextIds[current.GetParent(i)] = contextIds.Count;
                        workList.Push(current.GetParent(i));
                    }

                    edges.Append("  s").Append(contextIds[current]);
                    if (current.Size > 1)
                    {
                        edges.Append(":p").Append(i);
                    }

                    edges.Append("->");
                    edges.Append('s').Append(contextIds[current.GetParent(i)]);
                    edges.Append("[label=\"").Append(current.GetReturnState(i)).Append("\"]");
                    edges.AppendLine(";");
                }
            }

            StringBuilder builder = new StringBuilder();

            builder.AppendLine("digraph G {");
            builder.AppendLine("rankdir=LR;");
            builder.Append(nodes);
            builder.Append(edges);
            builder.AppendLine("}");
            return(builder.ToString());
        }
예제 #4
0
파일: LL1Analyzer.cs 프로젝트: antlr/antlr4
 /// <summary>
 /// Compute set of tokens that can follow
 /// <paramref name="s"/>
 /// in the ATN in the
 /// specified
 /// <paramref name="ctx"/>
 /// .
 /// <p/>
 /// If
 /// <paramref name="ctx"/>
 /// is
 /// <see cref="PredictionContext.EmptyLocal"/>
 /// and
 /// <paramref name="stopState"/>
 /// or the end of the rule containing
 /// <paramref name="s"/>
 /// is reached,
 /// <see cref="TokenConstants.EPSILON"/>
 /// is added to the result set. If
 /// <paramref name="ctx"/>
 /// is not
 /// <see cref="PredictionContext.EmptyLocal"/>
 /// and
 /// <paramref name="addEOF"/>
 /// is
 /// <see langword="true"/>
 /// and
 /// <paramref name="stopState"/>
 /// or the end of the outermost rule is reached,
 /// <see cref="TokenConstants.EOF"/>
 /// is added to the result set.
 /// </summary>
 /// <param name="s">the ATN state.</param>
 /// <param name="stopState">
 /// the ATN state to stop at. This can be a
 /// <see cref="BlockEndState"/>
 /// to detect epsilon paths through a closure.
 /// </param>
 /// <param name="ctx">
 /// The outer context, or
 /// <see cref="PredictionContext.EmptyLocal"/>
 /// if
 /// the outer context should not be used.
 /// </param>
 /// <param name="look">The result lookahead set.</param>
 /// <param name="lookBusy">
 /// A set used for preventing epsilon closures in the ATN
 /// from causing a stack overflow. Outside code should pass
 /// <c>new HashSet&lt;ATNConfig&gt;</c>
 /// for this argument.
 /// </param>
 /// <param name="calledRuleStack">
 /// A set used for preventing left recursion in the
 /// ATN from causing a stack overflow. Outside code should pass
 /// <c>new BitSet()</c>
 /// for this argument.
 /// </param>
 /// <param name="seeThruPreds">
 ///
 /// <see langword="true"/>
 /// to true semantic predicates as
 /// implicitly
 /// <see langword="true"/>
 /// and "see through them", otherwise
 /// <see langword="false"/>
 /// to treat semantic predicates as opaque and add
 /// <see cref="HitPred"/>
 /// to the
 /// result if one is encountered.
 /// </param>
 /// <param name="addEOF">
 /// Add
 /// <see cref="TokenConstants.EOF"/>
 /// to the result if the end of the
 /// outermost context is reached. This parameter has no effect if
 /// <paramref name="ctx"/>
 /// is
 /// <see cref="PredictionContext.EmptyLocal"/>
 /// .
 /// </param>
 protected internal virtual void Look(ATNState s, ATNState stopState, PredictionContext ctx, IntervalSet look, HashSet<ATNConfig> lookBusy, BitSet calledRuleStack, bool seeThruPreds, bool addEOF)
 {
     //		System.out.println("_LOOK("+s.stateNumber+", ctx="+ctx);
     ATNConfig c = new ATNConfig(s, 0, ctx);
     if (!lookBusy.Add(c))
     {
         return;
     }
     if (s == stopState)
     {
         if (ctx == null)
         {
             look.Add(TokenConstants.EPSILON);
             return;
         }
         else if (ctx.IsEmpty && addEOF) {
             look.Add(TokenConstants.EOF);
            return;
         }
     }
     if (s is RuleStopState)
     {
         if (ctx == null)
         {
             look.Add(TokenConstants.EPSILON);
             return;
         }
         else if (ctx.IsEmpty && addEOF)
         {
             look.Add(TokenConstants.EOF);
             return;
         }
         if (ctx != PredictionContext.EMPTY)
         {
             for (int i = 0; i < ctx.Size; i++)
             {
                 ATNState returnState = atn.states[ctx.GetReturnState(i)];
                 bool removed = calledRuleStack.Get(returnState.ruleIndex);
                 try
                 {
                     calledRuleStack.Clear(returnState.ruleIndex);
                     Look(returnState, stopState, ctx.GetParent(i), look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                 }
                 finally
                 {
                     if (removed)
                     {
                         calledRuleStack.Set(returnState.ruleIndex);
                     }
                 }
             }
             return;
         }
     }
     int n = s.NumberOfTransitions;
     for (int i_1 = 0; i_1 < n; i_1++)
     {
         Transition t = s.Transition(i_1);
         if (t is RuleTransition)
         {
             RuleTransition ruleTransition = (RuleTransition)t;
             if (calledRuleStack.Get(ruleTransition.ruleIndex))
             {
                 continue;
             }
             PredictionContext newContext = SingletonPredictionContext.Create(ctx, ruleTransition.followState.stateNumber);
             try
             {
                 calledRuleStack.Set(ruleTransition.target.ruleIndex);
                 Look(t.target, stopState, newContext, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
             }
             finally
             {
                 calledRuleStack.Clear(ruleTransition.target.ruleIndex);
             }
         }
         else
         {
             if (t is AbstractPredicateTransition)
             {
                 if (seeThruPreds)
                 {
                     Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                 }
                 else
                 {
                     look.Add(HitPred);
                 }
             }
             else
             {
                 if (t.IsEpsilon)
                 {
                     Look(t.target, stopState, ctx, look, lookBusy, calledRuleStack, seeThruPreds, addEOF);
                 }
                 else
                 {
                     if (t is WildcardTransition)
                     {
                         look.AddAll(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                     }
                     else
                     {
                         IntervalSet set = t.Label;
                         if (set != null)
                         {
                             if (t is NotSetTransition)
                             {
                                 set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, atn.maxTokenType));
                             }
                             look.AddAll(set);
                         }
                     }
                 }
             }
         }
     }
 }