114 lines
3.0 KiB
C#
114 lines
3.0 KiB
C#
using System;
|
|
|
|
namespace Flee.Parsing
|
|
{
|
|
internal class Automaton
|
|
{
|
|
private object _value;
|
|
private readonly AutomatonTree _tree = new AutomatonTree();
|
|
|
|
public Automaton()
|
|
{
|
|
}
|
|
|
|
public void AddMatch(string str, bool caseInsensitive, object value)
|
|
{
|
|
if (str.Length == 0)
|
|
{
|
|
this._value = value;
|
|
}
|
|
else
|
|
{
|
|
var state = _tree.Find(str[0], caseInsensitive);
|
|
if (state == null)
|
|
{
|
|
state = new Automaton();
|
|
state.AddMatch(str.Substring(1), caseInsensitive, value);
|
|
_tree.Add(str[0], caseInsensitive, state);
|
|
}
|
|
else
|
|
{
|
|
state.AddMatch(str.Substring(1), caseInsensitive, value);
|
|
}
|
|
}
|
|
}
|
|
|
|
public object MatchFrom(LookAheadReader input, int pos, bool caseInsensitive)
|
|
{
|
|
|
|
object result = null;
|
|
Automaton state = null;
|
|
int c = 0;
|
|
|
|
c = input.Peek(pos);
|
|
if (_tree != null && c >= 0)
|
|
{
|
|
state = _tree.Find(Convert.ToChar(c), caseInsensitive);
|
|
if (state != null)
|
|
{
|
|
result = state.MatchFrom(input, pos + 1, caseInsensitive);
|
|
}
|
|
}
|
|
return result ?? _value;
|
|
}
|
|
}
|
|
|
|
// * An automaton state transition tree. This class contains a
|
|
// * binary search tree for the automaton transitions from one state
|
|
// * to another. All transitions are linked to a single character.
|
|
internal class AutomatonTree
|
|
{
|
|
private char _value;
|
|
private Automaton _state;
|
|
private AutomatonTree _left;
|
|
private AutomatonTree _right;
|
|
|
|
public AutomatonTree()
|
|
{
|
|
}
|
|
|
|
public Automaton Find(char c, bool lowerCase)
|
|
{
|
|
if (lowerCase)
|
|
{
|
|
c = Char.ToLower(c);
|
|
}
|
|
if (_value == (char)0 || _value == c)
|
|
{
|
|
return _state;
|
|
}
|
|
else if (_value > c)
|
|
{
|
|
return _left.Find(c, false);
|
|
}
|
|
else
|
|
{
|
|
return _right.Find(c, false);
|
|
}
|
|
}
|
|
|
|
public void Add(char c, bool lowerCase, Automaton state)
|
|
{
|
|
if (lowerCase)
|
|
{
|
|
c = Char.ToLower(c);
|
|
}
|
|
if (_value == (char)0)
|
|
{
|
|
this._value = c;
|
|
this._state = state;
|
|
this._left = new AutomatonTree();
|
|
this._right = new AutomatonTree();
|
|
}
|
|
else if (_value > c)
|
|
{
|
|
_left.Add(c, false, state);
|
|
}
|
|
else
|
|
{
|
|
_right.Add(c, false, state);
|
|
}
|
|
}
|
|
}
|
|
}
|