using Implab; using System; using System.Linq; namespace Implab.Automaton.RegularExpressions { public abstract class Token { public abstract void Accept(IVisitor visitor); public Token Extend() { return Cat(new EndToken()); } public Token Tag(T tag) where T : IConvertible { return Cat(new EndToken(tag)); } public Token Cat(Token right) { return new CatToken(this, right); } public Token Or(Token right) { return new AltToken(this, right); } public Token Optional() { return Or(new EmptyToken()); } public Token EClosure() { return new StarToken(this); } public Token Closure() { return Cat(new StarToken(this)); } public Token Repeat(int count) { Token token = null; for (int i = 0; i < count; i++) token = token != null ? token.Cat(this) : this; return token ?? new EmptyToken(); } public Token Repeat(int min, int max) { if (min > max || min < 1) throw new ArgumentOutOfRangeException(); var token = Repeat(min); for (int i = min; i < max; i++) token = token.Cat( this.Optional() ); return token; } public static Token New(params T[] set) where T : struct, IConvertible { Safe.ArgumentNotNull(set, "set"); Token token = null; foreach(var c in set.Distinct()) token = token == null ? new SymbolToken(c) : token.Or(new SymbolToken(c)); return token; } } }