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); }