Exemplo n.º 1
0
        private Path BacktrackingFindMatches(
            Edge e,
            IParseTree current,
            out bool match
            )
        {
            // Variable "input" can be either one of three types:
            // AstParserParser.DeclContext
            // AstParserParser.AttrContext
            // terminal
            // Go through all children and match.
            var state = e.To;

            if (Piggy._debug_information)
            {
                System.Console.Error.WriteLine(
                    "BacktrackingFindMatches"
                    + " state " + state
                    + " input " + (current == null ? "''" : current.GetText().Truncate(30) + " " + current.GetType()));
            }

            if (current == null)
            {
                if (state.Owner.IsFinalState(state))
                {
                    var p = new Path(e, current);
                    match = true;
                    return(p);
                }
                if (e.IsEmpty || e.IsCode || e.IsText)
                {
                    var r = BacktrackingFindMatches(e.To, current, out match);
                    if (match)
                    {
                        if (r == null)
                        {
                            r = new Path(e, current);
                        }
                        else
                        {
                            var p = new Path(e, current, r);
                        }
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
            }
            else if (current as AstParserParser.NodeContext != null ||
                     current as AstParserParser.AttrContext != null)
            {
                if (e.IsEmpty || e.IsCode || e.IsText)
                {
                    var r = BacktrackingFindMatches(e.To, current, out match);
                    if (match)
                    {
                        if (r == null)
                        {
                            r = new Path(e, current);
                        }
                        else
                        {
                            var p = new Path(e, current, r);
                        }
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
                else if (e.IsNot)
                {
                    // To match this, go up to parent and scan all children
                    IParseTree parent = current.Parent;
                    bool       found  = false;
                    foreach (var child in parent.ChildrenForward())
                    {
                        if (child as AstParserParser.AttrContext != null)
                        {
                            if (child.GetChild(0).GetText() == e.Input)
                            {
                                found = true;
                                break;
                            }
                        }
                    }
                    if (!found)
                    {
                        IParseTree n = current;
                        var        r = BacktrackingFindMatches(e.To, n, out match);
                        if (match)
                        {
                            if (r == null)
                            {
                                r = new Path(e, current);
                            }
                            else
                            {
                                var p = new Path(e, current, r);
                            }
                            if (Piggy._debug_information)
                            {
                                System.Console.Error.WriteLine("returning " + r);
                            }
                            return(r);
                        }
                    }
                }
                else if (e.IsAny)
                {
                    IParseTree n = NextSibling(current);
                    var        r = BacktrackingFindMatches(e.To, n, out match);
                    if (match)
                    {
                        if (r == null)
                        {
                            r = new Path(e, current);
                        }
                        else
                        {
                            var p = new Path(e, current, r);
                        }
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
                else
                {
                    // Delve down into child and step through
                    // all siblings.
                    IParseTree n = current.GetChild(0);
                    var        r = BacktrackingFindMatches(e, n, out match);
                    if (match)
                    {
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
            }
            else
            {
                // Terminal.
                if (e.IsEmpty || e.IsCode || e.IsText)
                {
                    var r = BacktrackingFindMatches(e.To, current, out match);
                    if (match)
                    {
                        if (r == null)
                        {
                            r = new Path(e, current);
                        }
                        else
                        {
                            var p = new Path(e, current, r);
                        }
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
                else if (e.IsAny)
                {
                }
                else if (e.IsNot)
                {
                    // To match this, go up to parent and scan all children
                    IParseTree parent = current.Parent;
                    bool       found  = false;
                    foreach (var child in parent.ChildrenForward())
                    {
                        if (child as AstParserParser.AttrContext != null)
                        {
                            if (child.GetChild(0).GetText() == e.Input)
                            {
                                found = true;
                                break;
                            }
                        }
                    }
                    if (!found)
                    {
                        IParseTree n = current;
                        var        r = BacktrackingFindMatches(e.To, n, out match);
                        if (match)
                        {
                            if (r == null)
                            {
                                r = new Path(e, current);
                            }
                            else
                            {
                                var p = new Path(e, current, r);
                            }
                            if (Piggy._debug_information)
                            {
                                System.Console.Error.WriteLine("returning " + r);
                            }
                            return(r);
                        }
                    }
                }
                else if (e.Input == current.GetText())
                {
                    IParseTree n = Next(current);
                    var        r = BacktrackingFindMatches(e.To, n, out match);
                    if (match)
                    {
                        if (r == null)
                        {
                            r = new Path(e, current);
                        }
                        else
                        {
                            var p = new Path(e, current, r);
                        }
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
                else if (e.Input == "<" && "(" == current.GetText())
                {
                    IParseTree n = Next(current);
                    var        r = BacktrackingFindMatches(e.To, n, out match);
                    if (match)
                    {
                        if (r == null)
                        {
                            r = new Path(e, current);
                        }
                        else
                        {
                            var p = new Path(e, current, r);
                        }
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
                else if (e.Input == ">" && ")" == current.GetText())
                {
                    IParseTree n = Next(current);
                    var        r = BacktrackingFindMatches(e.To, n, out match);
                    if (match)
                    {
                        if (r == null)
                        {
                            r = new Path(e, current);
                        }
                        else
                        {
                            var p = new Path(e, current, r);
                        }
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
                else if (e.Input == "*")
                {
                    IParseTree n = Next(current);
                    var        r = BacktrackingFindMatches(e.To, n, out match);
                    if (match)
                    {
                        if (r == null)
                        {
                            r = new Path(e, current);
                        }
                        else
                        {
                            var p = new Path(e, current, r);
                        }
                        if (Piggy._debug_information)
                        {
                            System.Console.Error.WriteLine("returning " + r);
                        }
                        return(r);
                    }
                }
                else if (e.Input.StartsWith("$\""))
                {
                    var pattern = e.Input.Substring(2);
                    pattern = pattern.Substring(0, pattern.Length - 1);
                    try
                    {
                        var ch = e.Input;
                        if (e.AstList.Count() > 1)
                        {
                            ;
                        }
                        //throw new Exception("Cannot compute interpolated pattern because there are multiple paths through the DFA with this edge.");
                        var attr = e.AstList.First();
                        pattern = ReplaceMacro(attr);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Cannot perform substitution in pattern with string.");
                        Console.WriteLine("Pattern " + pattern);
                        Console.WriteLine(ex.Message);
                        throw ex;
                    }

                    pattern = pattern.Replace("\\", "\\\\");
                    var re       = new Regex(pattern);
                    var tvaltext = current.GetText();
                    tvaltext = tvaltext.Substring(1);
                    tvaltext = tvaltext.Substring(0, tvaltext.Length - 1);
                    var matched = re.Match(tvaltext);
                    var result  = matched.Success;
                    if (result)
                    {
                        IParseTree n = Next(current);
                        var        r = BacktrackingFindMatches(e.To, n, out match);
                        if (match)
                        {
                            if (r == null)
                            {
                                r = new Path(e, current);
                            }
                            else
                            {
                                var p = new Path(e, current, r);
                            }
                            if (Piggy._debug_information)
                            {
                                System.Console.Error.WriteLine("returning " + r);
                            }
                            return(r);
                        }
                    }
                }
            }
            if (Piggy._debug_information)
            {
                System.Console.Error.WriteLine("fail");
            }
            match = false;
            return(null);
        }