// Step to state and continue parsing input. // Returns a list of transitions leading to a state that accepts input. private List <List <Edge> > EnterState(Edge t) { int here = ++entry_value; int index_on_transition = t._index_at_transition; int token_index = t._index; ATNState state = t._to; IToken input_token = _input[token_index]; if (_log_parse) { System.Console.Error.WriteLine("Entry " + here + " State " + state + " tokenIndex " + token_index + " " + input_token.Text ); } // Upon reaching the cursor, return match. bool at_match = input_token.TokenIndex >= _cursor; if (at_match) { if (_log_parse) { System.Console.Error.Write("Entry " + here + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine(str); } return(res); } if (_visited.ContainsKey(new Pair <ATNState, int>(state, token_index))) { return(null); } _visited[new Pair <ATNState, int>(state, token_index)] = true; List <List <Edge> > result = new List <List <Edge> >(); if (_stop_states.Contains(state)) { if (_log_parse) { System.Console.Error.Write("Entry " + here + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine(str); } return(res); } // Search all transitions from state. foreach (Transition transition in state.TransitionsArray) { List <List <Edge> > matches = null; switch (transition.TransitionType) { case TransitionType.RULE: { RuleTransition rule = (RuleTransition)transition; ATNState sub_state = rule.target; matches = EnterState(new Edge() { _from = state, _to = rule.target, _follow = rule.followState, _label = rule.Label, _type = rule.TransitionType, _index = token_index, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } if (matches != null) { List <List <Edge> > new_matches = new List <List <Edge> >(); foreach (List <Edge> match in matches) { Edge f = match.First(); // "to" is possibly final state of submachine. Edge l = match.Last(); // "to" is start state of submachine. bool is_final = _stop_states.Contains(f._to); bool is_at_caret = f._index >= _cursor; if (!is_final) { new_matches.Add(match); } else { List <List <Edge> > xxx = EnterState(new Edge() { _from = f._to, _to = rule.followState, _label = null, _type = TransitionType.EPSILON, _index = f._index, _index_at_transition = f._index }); if (xxx != null && xxx.Count == 0) { throw new Exception(); } if (xxx != null) { foreach (List <Edge> y in xxx) { List <Edge> copy = y.ToList(); foreach (Edge q in match) { copy.Add(q); } new_matches.Add(copy); } } } } matches = new_matches; } } break; case TransitionType.PREDICATE: if (CheckPredicate((PredicateTransition)transition)) { matches = EnterState(new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } } break; case TransitionType.WILDCARD: matches = EnterState(new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index + 1, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } break; default: if (transition.IsEpsilon) { matches = EnterState(new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } } else { IntervalSet set = transition.Label; if (set != null && set.Count > 0) { if (transition.TransitionType == TransitionType.NOT_SET) { set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, _parser.Atn.maxTokenType)); } if (set.Contains(input_token.Type)) { matches = EnterState(new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index + 1, _index_at_transition = token_index }); if (matches != null && matches.Count == 0) { throw new Exception(); } } } } break; } if (matches != null) { foreach (List <Edge> match in matches) { List <Edge> x = match.ToList(); if (t != null) { x.Add(t); Edge prev = null; foreach (Edge z in x) { ATNState ff = z._to; if (prev != null) { if (prev._from != ff) { System.Console.Error.WriteLine("Fail " + PrintSingle(x)); Debug.Assert(false); } } prev = z; } } result.Add(x); } } } if (result.Count == 0) { return(null); } if (_log_parse) { System.Console.Error.Write("Entry " + here + " return "); string str = PrintResult(result); System.Console.Error.WriteLine(str); } return(result); }
private HashSet <ATNState> closure(ATNState start) { if (start == null) { throw new Exception(); } HashSet <ATNState> visited = new HashSet <ATNState>(); Stack <ATNState> stack = new Stack <ATNState>(); stack.Push(start); while (stack.Any()) { ATNState state = stack.Pop(); if (visited.Contains(state)) { continue; } visited.Add(state); foreach (Transition transition in state.TransitionsArray) { switch (transition.TransitionType) { case TransitionType.RULE: { RuleTransition rule = (RuleTransition)transition; ATNState sub_state = rule.target; HashSet <ATNState> cl = closure(sub_state); if (cl.Where(s => _stop_states.Contains(s) && s.atn == sub_state.atn).Any()) { HashSet <ATNState> cl2 = closure(rule.followState); cl.UnionWith(cl2); } foreach (ATNState c in cl) { visited.Add(c); } } break; case TransitionType.PREDICATE: if (CheckPredicate((PredicateTransition)transition)) { if (transition.target == null) { throw new Exception(); } stack.Push(transition.target); } break; case TransitionType.WILDCARD: break; default: if (transition.IsEpsilon) { if (transition.target == null) { throw new Exception(); } stack.Push(transition.target); } break; } } } return(visited); }
// Step to state and continue parsing input. // Returns a list of transitions leading to a state that accepts input. private List <List <Edge> > EnterState(List <int> p, Edge t, int indent) { int here = ++entry_value; int index_on_transition = t._index_at_transition; int token_index = t._index; ATNState state = t._to; var rule_match = _parser.Atn.ruleToStartState.Where(v => v.stateNumber == state.stateNumber); var start_rule = rule_match.Any() ? rule_match.FirstOrDefault().ruleIndex : -1; var q = p.ToList(); if (start_rule >= 0) { q.Add(start_rule); } // Upon reaching the cursor, return match. bool at_match = token_index == _cursor; if (at_match) { if (_log_parse) { System.Console.Error.Write( new String(' ', indent * 2) + "Entry " + here + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine( str); } return(res); } IToken input_token = _input[token_index]; if (_log_parse) { var name = (start_rule >= 0) ? (" " + _parser.RuleNames[start_rule]) : ""; System.Console.Error.WriteLine( new String(' ', indent * 2) + "Entry " + here + " State " + state + name + " tokenIndex " + token_index + " " + input_token.Text ); } bool at_match2 = input_token.TokenIndex >= _cursor; if (at_match2) { if (_log_parse) { System.Console.Error.Write( new String(' ', indent * 2) + "Entry " + here + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine( str); } return(res); } if (_visited.ContainsKey(new Tuple <ATNState, int, int>(state, token_index, indent))) { if (_visited_extra.ContainsKey(new Tuple <ATNState, int, int, List <int> >( state, token_index, indent, p))) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "already visited."); } return(null); } } _visited_extra[new Tuple <ATNState, int, int, List <int> >(state, token_index, indent, q)] = true; _visited[new Tuple <ATNState, int, int>(state, token_index, indent)] = true; List <List <Edge> > result = new List <List <Edge> >(); if (_stop_states.Contains(state)) { if (_log_parse) { var n = _parser.Atn.ruleToStartState.Where(v => v.stateNumber == state.stateNumber); var r = n.Any() ? n.FirstOrDefault().ruleIndex : -1; var name = (r >= 0) ? (" " + _parser.RuleNames[r]) : ""; System.Console.Error.Write( new String(' ', indent * 2) + "Entry " + here + " State " + state + name + " tokenIndex " + token_index + " " + input_token.Text + " return "); } List <List <Edge> > res = new List <List <Edge> >() { new List <Edge>() { t } }; if (_log_parse) { string str = PrintResult(res); System.Console.Error.WriteLine( str); } return(res); } // Search all transitions from state. foreach (Transition transition in state.TransitionsArray) { List <List <Edge> > matches = null; switch (transition.TransitionType) { case TransitionType.RULE: { RuleTransition rule = (RuleTransition)transition; ATNState sub_state = rule.target; matches = EnterState(q, new Edge() { _from = state, _to = rule.target, _follow = rule.followState, _label = rule.Label, _type = rule.TransitionType, _index = token_index, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } if (matches != null) { List <List <Edge> > new_matches = new List <List <Edge> >(); foreach (List <Edge> match in matches) { Edge f = match.First(); // "to" is possibly final state of submachine. Edge l = match.Last(); // "to" is start state of submachine. bool is_final = _stop_states.Contains(f._to); bool is_at_caret = f._index >= _cursor; if (!is_final) { new_matches.Add(match); } else { List <List <Edge> > xxx = EnterState(q, new Edge() { _from = f._to, _to = rule.followState, _label = null, _type = TransitionType.EPSILON, _index = f._index, _index_at_transition = f._index }, indent + 1); if (xxx != null && xxx.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } if (xxx != null) { foreach (List <Edge> y in xxx) { List <Edge> copy = y.ToList(); foreach (Edge g in match) { copy.Add(g); } new_matches.Add(copy); } } } } matches = new_matches; } } break; case TransitionType.PREDICATE: if (CheckPredicate((PredicateTransition)transition)) { matches = EnterState(q, new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } } break; case TransitionType.WILDCARD: matches = EnterState(q, new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index + 1, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } break; default: if (transition.IsEpsilon) { matches = EnterState(q, new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } } else { IntervalSet set = transition.Label; if (set != null && set.Count > 0) { if (transition.TransitionType == TransitionType.NOT_SET) { set = set.Complement(IntervalSet.Of(TokenConstants.MinUserTokenType, _parser.Atn.maxTokenType)); } if (set.Contains(input_token.Type)) { matches = EnterState(q, new Edge() { _from = state, _to = transition.target, _label = transition.Label, _type = transition.TransitionType, _index = token_index + 1, _index_at_transition = token_index }, indent + 1); if (matches != null && matches.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "throwing exception."); } throw new Exception(); } } } } break; } if (matches != null) { foreach (List <Edge> match in matches) { List <Edge> x = match.ToList(); if (t != null) { x.Add(t); Edge prev = null; foreach (Edge z in x) { ATNState ff = z._to; if (prev != null) { if (prev._from != ff) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "Fail " + PrintSingle(x)); Debug.Assert(false); } } prev = z; } } result.Add(x); } } } if (result.Count == 0) { if (_log_parse) { System.Console.Error.WriteLine( new String(' ', indent * 2) + "result empty."); } return(null); } if (_log_parse) { var n = _parser.Atn.ruleToStartState.Where(v => v.stateNumber == state.stateNumber); var r = n.Any() ? n.FirstOrDefault().ruleIndex : -1; var name = (r >= 0) ? (" " + _parser.RuleNames[r]) : ""; System.Console.Error.Write( new String(' ', indent * 2) + "Entry " + here + " State " + state + name + " tokenIndex " + token_index + " " + input_token.Text + " return "); string str = PrintResult(result); System.Console.Error.WriteLine( str); } return(result); }