ln.lexer/SharpLexer/match/Matchable.cs

99 lines
2.1 KiB
C#

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<string, Matchable> namedMatchables = new Dictionary<string, Matchable>();
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);
}
}
}
}