view Implab/Parsing/Token.cs @ 89:ce0171cacec4 v2

improved performance of a chained map operation
author cin
date Wed, 08 Oct 2014 02:19:45 +0400
parents c0bf853aa04f
children
line wrap: on
line source

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>(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<T>(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;
        }
    }
}