using System; using lexer.buffer; using System.Collections.Generic; namespace lexer.match { public abstract class Matchable { public event MatchedDelegate OnMatched; public String Name { get; private set; } public bool Grouping { get; set; } public bool Notice { get; set; } protected Matchable(String name = null) { this.Name = name; if (name != null) { namedMatchables.Add(name, this); } } public MatchedPart[] MatchNoticeable(CharacterBuffer chbuffer){ MatchedPart[] mparts = Match(chbuffer); if (Grouping && (mparts != null)){ MatchedPart mp = new MatchedPart(this, mparts.MatchingCharacters()); return new MatchedPart[] { mp }; } return mparts; } /** * Match() match this Matchable starting at current position of CharacterBuffer * * if an successfull Match is found, return the matched characters as char[] * returns null if no match is found * **/ public abstract MatchedPart[] Match(CharacterBuffer chbuffer); public override string ToString() { return ToString(false); } public virtual String ToString(bool useSymbol) { if (useSymbol && (this.Name != null)) { return this.Name; } return ToString(); } static Dictionary namedMatchables = new Dictionary(); public static Matchable getNamedMatchable(String name) { if (!namedMatchables.ContainsKey(name)){ return null; } return namedMatchables[name]; } public static Matchable getNamedMatchable(char[] name) { return getNamedMatchable(new String(name)); } public class DeferredMatchable : Matchable{ Matchable matchable; public DeferredMatchable(char[] name) :this(new String(name)){} public DeferredMatchable(String name) :base(){ Name = name; matchable = null; } public override MatchedPart[] Match(CharacterBuffer chbuffer) { if (matchable == null){ matchable = getNamedMatchable(Name); } if (matchable == null) { throw new KeyNotFoundException(String.Format("Deferred matchable '{0}' was not found", Name)); } return matchable.Match(chbuffer); } } } }