예제 #1
0
 public void DoNotBacktrack(int xi_token_type)
 {
     if (!NoBacktrackingTokens.Contains(xi_token_type))
     {
         NoBacktrackingTokens.Add(xi_token_type, xi_token_type);
     }
 }
예제 #2
0
        private void GenerateStateCodeWalker(ail.net.parser.Fsa xi_fsa, ail.net.parser.FsaState xi_state, int xi_token_type, StringBuilder xio_code)
        {
            ail.net.framework.Assert.NonNullReference(xi_state, "xi_state");

            if (xi_state.Id != xi_fsa.StartState.Id) //  start state was generated earley with switch/case code
            {
                xi_state.Marked = true;

                xio_code.Append(Environment.NewLine);
                xio_code.Append(@"_q");
                xio_code.Append(xi_state.Id.ToString());
                xio_code.Append(@":");

                bool finalstate = xi_state.Papa.FinalStates.Contains(xi_state.Id);

                if (finalstate && xi_state.Token != (object)null)
                {
                    xio_code.Append(Environment.NewLine);
                    xio_code.Append(kTab3);
                    xio_code.Append(@"PushState((int)");
                    xio_code.Append(Token.GetClassName());
                    xio_code.Append(@".EType.");
                    xio_code.Append(Token.GetTokenName(xi_state.Token.Type));
                    xio_code.Append(@"); // save accepted state for backtracking");
                    xio_code.Append(Environment.NewLine);
                }

                xio_code.Append(Environment.NewLine);
                xio_code.Append(kTab3);
                xio_code.Append(@"Next();");
                xio_code.Append(Environment.NewLine);

                for (int rank = 0, i = 0; ; rank++) // fix point
                {
                    int length = xio_code.Length;

                    foreach (ail.net.parser.FsaTransition transition in xi_state.Transitions.Values)
                    {
                        ail.net.framework.Assert.NonNullReference(transition, "transition");

                        if (transition.Predicate.Rank == rank)
                        {
                            xio_code.Append(Environment.NewLine);
                            xio_code.Append(kTab3);

                            if (i > 0)
                            {
                                xio_code.Append(@"else ");
                            }
                            else
                            {
                                i++;
                            }

                            xio_code.Append(@"if(");

                            if (transition.Predicate.Context.Length != 0)
                            {
                                xio_code.Append("xi_context == ");
                                xio_code.Append(transition.Predicate.Context);
                                xio_code.Append(" && ");
                            }

                            xio_code.Append(transition.Predicate.Text);
                            xio_code.Append(@"(Current))");
                            xio_code.Append(Environment.NewLine);
                            xio_code.Append(kTab3);
                            xio_code.Append(@"{");
                            xio_code.Append(Environment.NewLine);
                            xio_code.Append(kTab4);
                            xio_code.Append(@"goto _q");
                            xio_code.Append(transition.End.ToString());
                            xio_code.Append(@";");
                            xio_code.Append(Environment.NewLine);
                            xio_code.Append(kTab3);
                            xio_code.Append(@"}");
                        }
                    }

                    if (xio_code.Length == length && rank > ail.net.parser.FsaTransition.kMaxRankValue)
                    {
                        break;
                    }
                }

                if (!finalstate && HasBacktracking && !NoBacktrackingTokens.Contains(xi_token_type))
                {
                    if (xi_state.Transitions.Values.Count > 0)
                    {
                        xio_code.Append(Environment.NewLine);
                        xio_code.Append(kTab3);
                        xio_code.Append(@"else");
                        xio_code.Append(Environment.NewLine);
                        xio_code.Append(kTab3);
                        xio_code.Append(@"{");
                        xio_code.Append(Environment.NewLine);
                        xio_code.Append(kTab4);
                    }
                    else
                    {
                        xio_code.Append(kTab3);
                    }

                    xio_code.Append(@"PopState(); // restore the last accepted state, backtracking");

                    if (xi_state.Transitions.Values.Count > 0)
                    {
                        xio_code.Append(Environment.NewLine);
                        xio_code.Append(kTab3);
                        xio_code.Append(@"}");
                    }
                }

                xio_code.Append(Environment.NewLine);
                xio_code.Append(kTab3);
                xio_code.Append(@"goto _exit;");
            }

            int token_type = xi_token_type;

            if (xi_state.Token != (object)null)
            {
                token_type = xi_state.Token.Type;
            }

            foreach (ail.net.parser.FsaTransition transition in xi_state.Transitions.Values)
            {
                ail.net.framework.Assert.NonNullReference(transition, "transition");

                ail.net.parser.FsaState state = (ail.net.parser.FsaState)xi_fsa.States[transition.End];
                ail.net.framework.Assert.NonNullReference(state, "state");

                if (!state.Marked)
                {
                    GenerateStateCodeWalker(xi_fsa, state, token_type, xio_code);
                }
            }
        }