示例#1
0
        // 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);
        }
示例#2
0
        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);
        }
示例#3
0
        // 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);
        }