using Implab; using System; using System.Collections.Generic; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; namespace Implab.Parsing { public abstract class Token { public abstract void Accept(IVisitor visitor); public Token Extend() { return new CatToken(this, new EndToken()); } public Token Tag(T tag) where T : IConvertible { return new CatToken(this, new EndToken(tag.ToInt32(CultureInfo.InvariantCulture))); } 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 new CatToken(this, 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.ToInt32(CultureInfo.InvariantCulture)) : token.Or(new SymbolToken(c.ToInt32(CultureInfo.InvariantCulture))); return token; } } }