XmlGraphNode IExprVisitor <XmlGraphNode> .VisitChars(CharsExpr charsExpr) { return(this.Graph.CreateNode()); }
Expr ParseImpl(Token[] tokens, int from, int to) { var items = new LinkedList <Expr>(); var makeOr = false; var makeCheck = false; var makeCheckNot = false; for (int i = from; i <= to; i++) { var t = tokens[i]; switch (t.kind) { case TokenKind.openGroup: var nextPos = this.SkipBraces(tokens, i + 1, to); var groupNode = this.ParseImpl(tokens, i + 1, nextPos - 1); if (groupNode == null) { return(null); } i = nextPos; items.AddLast(groupNode); break; case TokenKind.closeGroup: return(null); case TokenKind.checkOp: makeCheck = true; continue; case TokenKind.checkNotOp: makeCheckNot = true; continue; case TokenKind.orOp: makeOr = true; continue; case TokenKind.quantor: int minNum = -1, maxNum = -1; this.ParseQuantifier(t.str, ref minNum, ref maxNum); Expr lastExprPart; if (items.Last.Value is CharsExpr chars) { lastExprPart = new CharsExpr(chars.Chars.Last().ToString()); items.RemoveLast(); items.AddLast(new CharsExpr(chars.Chars.Substring(0, chars.Chars.Length - 1))); } else { lastExprPart = items.Last.Value; items.RemoveLast(); } items.AddLast(Expr.Number(lastExprPart, minNum, maxNum)); break; case TokenKind.charClass: var classAlts = this.ParseCharClass(tokens, ref i); items.AddLast(classAlts); break; case TokenKind.anyChar: items.AddLast(Expr.AnyChar()); break; case TokenKind.ch: items.AddLast(Expr.Characters(t.str)); break; case TokenKind.escapedChar: items.AddLast(GiveEscape(t)); break; case TokenKind.rangeOp: return(null); default: throw new NotImplementedException(""); } if (makeOr) { if (makeCheck || makeCheckNot) { return(null); } if (items.Count < 2) { return(null); } var nextPos = i + 1; if (nextPos <= to) { if (tokens[nextPos].Check(TokenKind.quantor)) { continue; } } var lastItemIfAlts = items.Last.Previous.Value as AlternativesExpr; var newAltesChildren = lastItemIfAlts == null ? new[] { items.Last.Previous.Value, items.Last.Value } : lastItemIfAlts.Items.Concat(new[] { items.Last.Value }).ToArray(); var newAltsNode = Expr.Alternatives(newAltesChildren); items.RemoveLast(); items.RemoveLast(); items.AddLast(newAltsNode); makeOr = false; } else if (makeCheck) { if (makeOr || makeCheckNot) { return(null); } var lastExprPart = items.Last.Value; items.RemoveLast(); items.AddLast(Expr.Check(lastExprPart)); makeCheck = false; } else if (makeCheckNot) { if (makeCheck || makeOr) { return(null); } var lastExprPart = items.Last.Value; items.RemoveLast(); items.AddLast(Expr.CheckNot(lastExprPart)); makeCheckNot = false; } } return(Expr.Sequence(items.ToArray())); }