public void DoNotBacktrack(int xi_token_type) { if (!NoBacktrackingTokens.Contains(xi_token_type)) { NoBacktrackingTokens.Add(xi_token_type, xi_token_type); } }
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); } } }