204 lines
3.8 KiB
C#
204 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using lexer.buffer;
|
|
using System.Threading;
|
|
using System.Runtime.Remoting.Messaging;
|
|
using System.Text;
|
|
namespace lexer.match
|
|
{
|
|
|
|
public class CharacterGroup : Matchable
|
|
{
|
|
struct chinterval
|
|
{
|
|
public char first;
|
|
public char last;
|
|
|
|
public chinterval(char first, char last)
|
|
{
|
|
this.first = first;
|
|
this.last = last;
|
|
}
|
|
|
|
public bool Match(char ch)
|
|
{
|
|
return (ch >= first) && (ch <= last);
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return string.Format("[chinterval min=0x{0:X4} max=0x{1:X4}]", (int)this.first, (int)this.last);
|
|
}
|
|
}
|
|
|
|
List<char> includeCharacters = new List<char>();
|
|
List<chinterval> includeIntervals = new List<chinterval>();
|
|
List<char> excludeCharacters = new List<char>();
|
|
List<chinterval> excludeIntervals = new List<chinterval>();
|
|
|
|
|
|
public CharacterGroup(CharacterBuffer chbuffer)
|
|
{
|
|
if (chbuffer.Current != '[')
|
|
{
|
|
throw new FormatException("CharacterGroup Definition must start with '['");
|
|
}
|
|
|
|
chbuffer.MoveNext();
|
|
|
|
char[] idef = chbuffer.findUnescaped(new char[] { ']', '/' });
|
|
char[] edef = null;
|
|
|
|
if (chbuffer.Last == '/')
|
|
{
|
|
edef = chbuffer.findUnescaped(']');
|
|
}
|
|
|
|
#if DEBUG
|
|
Console.WriteLine("CharacterGroup: include = {0}", new String(idef));
|
|
Console.WriteLine("CharacterGroup: exclude = {0}", new String(edef));
|
|
#endif
|
|
parseComponents(includeCharacters, includeIntervals, idef);
|
|
if (edef != null)
|
|
{
|
|
parseComponents(excludeCharacters, excludeIntervals, edef);
|
|
}
|
|
}
|
|
|
|
private void parseComponents(List<char> cList, List<chinterval> iList, char[] def)
|
|
{
|
|
DefinitionReader dr = new DefinitionReader(def);
|
|
while (dr.Current != DefinitionReader.OP_EOB)
|
|
{
|
|
if (dr.Current == DefinitionReader.OP_INTERVAL)
|
|
{
|
|
char min = (char)0;
|
|
char max = (char)0xffff;
|
|
|
|
if (cList.Count > 0)
|
|
{
|
|
min = cList.Last();
|
|
cList.RemoveAt(cList.Count - 1);
|
|
}
|
|
|
|
dr.MoveNext();
|
|
|
|
if (dr.Current != DefinitionReader.OP_EOB)
|
|
{
|
|
max = (char)dr.Current;
|
|
}
|
|
iList.Add(new chinterval(min, max));
|
|
}
|
|
else
|
|
{
|
|
cList.Add((char)dr.Current);
|
|
}
|
|
dr.MoveNext();
|
|
}
|
|
}
|
|
|
|
public bool Match(char ch)
|
|
{
|
|
foreach (chinterval i in excludeIntervals)
|
|
{
|
|
if (i.Match(ch))
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
foreach (char ec in excludeCharacters)
|
|
{
|
|
if (ec == ch)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
foreach (chinterval i in includeIntervals)
|
|
{
|
|
if (i.Match(ch))
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
foreach (char ic in includeCharacters)
|
|
{
|
|
if (ic == ch)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
public override MatchedPart[] Match(CharacterBuffer chbuffer)
|
|
{
|
|
if (!chbuffer.EndOfBuffer && Match(chbuffer.Current))
|
|
{
|
|
return new MatchedPart[] { new MatchedPart(this, new char[] { chbuffer.Current }) };
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
sb.Append("[");
|
|
foreach (char ch in includeCharacters)
|
|
{
|
|
if (ch <= 0x20)
|
|
{
|
|
sb.AppendFormat("\\0x{0:X4}", (int)ch);
|
|
}
|
|
else
|
|
{
|
|
sb.Append(ch);
|
|
}
|
|
}
|
|
|
|
foreach (chinterval chi in includeIntervals)
|
|
{
|
|
if (chi.first <= 0x20)
|
|
{
|
|
sb.AppendFormat("\\0x{0:X4}", (int)chi.first);
|
|
}
|
|
else
|
|
{
|
|
sb.Append(chi.first);
|
|
}
|
|
sb.Append("..");
|
|
if (chi.last <= 0x20)
|
|
{
|
|
sb.AppendFormat("\\0x{0:X4}", (int)chi.last);
|
|
}
|
|
else
|
|
{
|
|
sb.Append(chi.last);
|
|
}
|
|
|
|
}
|
|
|
|
if ((excludeIntervals.Count > 0) || (excludeCharacters.Count > 0))
|
|
{
|
|
sb.Append("/");
|
|
|
|
foreach (char ch in includeCharacters)
|
|
{
|
|
if (ch <= 0x20)
|
|
{
|
|
sb.AppendFormat("\\{0:X4}", (int)ch);
|
|
}
|
|
else
|
|
{
|
|
sb.Append(ch);
|
|
}
|
|
}
|
|
}
|
|
|
|
sb.Append("]");
|
|
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
}
|