blob: 4b22b1ffc0e86ea6f10078970a9c7fcce9433023 [file] [log] [blame]
/*Author:Martin.Holzherr;Date:20080922;Context:"PEG Support for C#";Licence:CPOL
* <<History>>
* 20080922;V1.0 created
* 20080929;UTF16BE;Added UTF16BE read support to <<FileLoader.LoadFile(out string src)>>
* <</History>>
*/
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Diagnostics;
using System.Text;
using System;
namespace Peg.Base
{
#region Input File Support
public enum EncodingClass { unicode, utf8, binary, ascii };
public enum UnicodeDetection { notApplicable, BOM, FirstCharIsAscii };
public class FileLoader
{
public enum FileEncoding { none, ascii, binary, utf8, unicode, utf16be, utf16le, utf32le, utf32be, uniCodeBOM };
public FileLoader(EncodingClass encodingClass, UnicodeDetection detection, string path)
{
encoding_ = GetEncoding(encodingClass, detection, path);
path_ = path;
}
public bool IsBinaryFile()
{
return encoding_ == FileEncoding.binary;
}
public bool LoadFile(out byte[] src)
{
src = null;
if (!IsBinaryFile()) return false;
using (BinaryReader brdr = new BinaryReader(File.Open(path_, FileMode.Open,FileAccess.Read)))
{
src = brdr.ReadBytes((int)brdr.BaseStream.Length);
return true;
}
}
public bool LoadFile(out string src)
{
src = null;
Encoding textEncoding = FileEncodingToTextEncoding();
if (textEncoding == null)
{
if (encoding_ == FileEncoding.binary) return false;
using (StreamReader rd = new StreamReader(path_, true))
{
src = rd.ReadToEnd();
return true;
}
}
else
{
if (encoding_ == FileEncoding.utf16be)//UTF16BE
{
using (BinaryReader brdr = new BinaryReader(File.Open(path_, FileMode.Open, FileAccess.Read)))
{
byte[] bytes = brdr.ReadBytes((int)brdr.BaseStream.Length);
StringBuilder s = new StringBuilder();
for (int i = 0; i < bytes.Length; i += 2)
{
char c = (char)(bytes[i] << 8 | bytes[i + 1]);
s.Append(c);
}
src = s.ToString();
return true;
}
}
else
{
using (StreamReader rd = new StreamReader(path_, textEncoding))
{
src = rd.ReadToEnd();
return true;
}
}
}
}
Encoding FileEncodingToTextEncoding()
{
switch (encoding_)
{
case FileEncoding.utf8: return new UTF8Encoding();
case FileEncoding.utf32be:
case FileEncoding.utf32le: return new UTF32Encoding();
case FileEncoding.unicode:
case FileEncoding.utf16be:
case FileEncoding.utf16le: return new UnicodeEncoding();
case FileEncoding.ascii: return new ASCIIEncoding();
case FileEncoding.binary:
case FileEncoding.uniCodeBOM: return null;
default: Debug.Assert(false);
return null;
}
}
static FileEncoding DetermineUnicodeWhenFirstCharIsAscii(string path)
{
using (BinaryReader br = new BinaryReader(File.Open(path, FileMode.Open, FileAccess.Read)))
{
byte[] startBytes = br.ReadBytes(4);
if (startBytes.Length == 0) return FileEncoding.none;
if (startBytes.Length == 1 || startBytes.Length == 3) return FileEncoding.utf8;
if (startBytes.Length == 2 && startBytes[0] != 0) return FileEncoding.utf16le;
if (startBytes.Length == 2 && startBytes[0] == 0) return FileEncoding.utf16be;
if (startBytes[0] == 0 && startBytes[1] == 0) return FileEncoding.utf32be;
if (startBytes[0] == 0 && startBytes[1] != 0) return FileEncoding.utf16be;
if (startBytes[0] != 0 && startBytes[1] == 0) return FileEncoding.utf16le;
return FileEncoding.utf8;
}
}
FileEncoding GetEncoding(EncodingClass encodingClass, UnicodeDetection detection, string path)
{
switch (encodingClass)
{
case EncodingClass.ascii: return FileEncoding.ascii;
case EncodingClass.unicode:
{
if (detection == UnicodeDetection.FirstCharIsAscii)
{
return DetermineUnicodeWhenFirstCharIsAscii(path);
}
else if (detection == UnicodeDetection.BOM)
{
return FileEncoding.uniCodeBOM;
}
else return FileEncoding.unicode;
}
case EncodingClass.utf8: return FileEncoding.utf8;
case EncodingClass.binary: return FileEncoding.binary;
}
return FileEncoding.none;
}
string path_;
public readonly FileEncoding encoding_;
}
#endregion Input File Support
#region Error handling
public class PegException : System.Exception
{
public PegException()
: base("Fatal parsing error ocurred")
{
}
}
public struct PegError
{
internal SortedList<int, int> lineStarts;
void AddLineStarts(string s, int first, int last, ref int lineNo, out int colNo)
{
colNo = 2;
for (int i = first + 1; i <= last; ++i, ++colNo)
{
if (s[i - 1] == '\n')
{
lineStarts[i] = ++lineNo;
colNo = 1;
}
}
--colNo;
}
public void GetLineAndCol(string s, int pos, out int lineNo, out int colNo)
{
for (int i = lineStarts.Count(); i > 0; --i)
{
KeyValuePair<int, int> curLs = lineStarts.ElementAt(i - 1);
if (curLs.Key == pos)
{
lineNo = curLs.Value;
colNo = 1;
return;
}
if (curLs.Key < pos)
{
lineNo = curLs.Value;
AddLineStarts(s, curLs.Key, pos, ref lineNo, out colNo);
return;
}
}
lineNo = 1;
AddLineStarts(s, 0, pos, ref lineNo, out colNo);
}
}
#endregion Error handling
#region Syntax/Parse-Tree related classes
public enum ESpecialNodes { eFatal = -10001, eAnonymNTNode = -1000, eAnonymASTNode = -1001, eAnonymousNode = -100 }
public enum ECreatorPhase { eCreate, eCreationComplete, eCreateAndComplete }
public struct PegBegEnd//indices into the source string
{
public int Length
{
get { return posEnd_ - posBeg_; }
}
public string GetAsString(string src)
{
Debug.Assert(src.Length >= posEnd_);
return src.Substring(posBeg_, Length);
}
public int posBeg_;
public int posEnd_;
}
public class PegNode : ICloneable
{
#region Constructors
public PegNode(PegNode parent, int id, PegBegEnd match, PegNode child, PegNode next)
{
parent_ = parent; id_ = id; child_ = child; next_ = next;
match_ = match;
}
public PegNode(PegNode parent, int id, PegBegEnd match, PegNode child)
: this(parent, id, match, child, null)
{
}
public PegNode(PegNode parent, int id, PegBegEnd match)
: this(parent, id, match, null, null)
{ }
public PegNode(PegNode parent, int id)
: this(parent, id, new PegBegEnd(), null, null)
{
}
#endregion Constructors
#region Public Members
public virtual string GetAsString(string s)
{
return match_.GetAsString(s);
}
public virtual PegNode Clone()
{
PegNode clone= new PegNode(parent_, id_, match_);
CloneSubTrees(clone);
return clone;
}
#endregion Public Members
#region Protected Members
protected void CloneSubTrees(PegNode clone)
{
PegNode child = null, next = null;
if (child_ != null)
{
child = child_.Clone();
child.parent_ = clone;
}
if (next_ != null)
{
next = next_.Clone();
next.parent_ = clone;
}
clone.child_ = child;
clone.next_ = next;
}
#endregion Protected Members
#region Data Members
public int id_;
public PegNode parent_, child_, next_;
public PegBegEnd match_;
#endregion Data Members
#region ICloneable Members
object ICloneable.Clone()
{
return Clone();
}
#endregion
}
internal struct PegTree
{
internal enum AddPolicy { eAddAsChild, eAddAsSibling };
internal PegNode root_;
internal PegNode cur_;
internal AddPolicy addPolicy;
}
public abstract class PrintNode
{
public abstract int LenMaxLine();
public abstract bool IsLeaf(PegNode p);
public virtual bool IsSkip(PegNode p) { return false; }
public abstract void PrintNodeBeg(PegNode p, bool bAlignVertical, ref int nOffsetLineBeg, int nLevel);
public abstract void PrintNodeEnd(PegNode p, bool bAlignVertical, ref int nOffsetLineBeg, int nLevel);
public abstract int LenNodeBeg(PegNode p);
public abstract int LenNodeEnd(PegNode p);
public abstract void PrintLeaf(PegNode p, ref int nOffsetLineBeg, bool bAlignVertical);
public abstract int LenLeaf(PegNode p);
public abstract int LenDistNext(PegNode p, bool bAlignVertical, ref int nOffsetLineBeg, int nLevel);
public abstract void PrintDistNext(PegNode p, bool bAlignVertical, ref int nOffsetLineBeg, int nLevel);
}
public class TreePrint : PrintNode
{
#region Data Members
public delegate string GetNodeName(PegNode node);
string src_;
TextWriter treeOut_;
int nMaxLineLen_;
bool bVerbose_;
GetNodeName GetNodeName_;
#endregion Data Members
#region Methods
public TreePrint(TextWriter treeOut, string src, int nMaxLineLen, GetNodeName GetNodeName, bool bVerbose)
{
treeOut_ = treeOut;
nMaxLineLen_ = nMaxLineLen;
bVerbose_ = bVerbose;
GetNodeName_ = GetNodeName;
src_ = src;
}
public void PrintTree(PegNode parent, int nOffsetLineBeg, int nLevel)
{
if (IsLeaf(parent))
{
PrintLeaf(parent, ref nOffsetLineBeg, false);
treeOut_.Flush();
return;
}
bool bAlignVertical =
DetermineLineLength(parent, nOffsetLineBeg) > LenMaxLine();
PrintNodeBeg(parent, bAlignVertical, ref nOffsetLineBeg, nLevel);
int nOffset = nOffsetLineBeg;
for (PegNode p = parent.child_; p != null; p = p.next_)
{
if (IsSkip(p)) continue;
if (IsLeaf(p))
{
PrintLeaf(p, ref nOffsetLineBeg, bAlignVertical);
}
else
{
PrintTree(p, nOffsetLineBeg, nLevel + 1);
}
if (bAlignVertical)
{
nOffsetLineBeg = nOffset;
}
while (p.next_ != null && IsSkip(p.next_)) p = p.next_;
if (p.next_ != null)
{
PrintDistNext(p, bAlignVertical, ref nOffsetLineBeg, nLevel);
}
}
PrintNodeEnd(parent, bAlignVertical, ref nOffsetLineBeg, nLevel);
treeOut_.Flush();
}
int DetermineLineLength(PegNode parent, int nOffsetLineBeg)
{
int nLen = LenNodeBeg(parent);
PegNode p;
for (p = parent.child_; p != null; p = p.next_)
{
if (IsSkip(p)) continue;
if (IsLeaf(p))
{
nLen += LenLeaf(p);
}
else
{
nLen += DetermineLineLength(p, nOffsetLineBeg);
}
if (nLen + nOffsetLineBeg > LenMaxLine())
{
return nLen + nOffsetLineBeg;
}
}
nLen += LenNodeEnd(p);
return nLen;
}
public override int LenMaxLine() { return nMaxLineLen_; }
public override void
PrintNodeBeg(PegNode p, bool bAlignVertical, ref int nOffsetLineBeg, int nLevel)
{
PrintIdAsName(p);
treeOut_.Write("<");
if (bAlignVertical)
{
treeOut_.WriteLine();
treeOut_.Write(new string(' ', nOffsetLineBeg += 2));
}
else
{
++nOffsetLineBeg;
}
}
public override void
PrintNodeEnd(PegNode p, bool bAlignVertical, ref int nOffsetLineBeg, int nLevel)
{
if (bAlignVertical)
{
treeOut_.WriteLine();
treeOut_.Write(new string(' ', nOffsetLineBeg -= 2));
}
treeOut_.Write('>');
if (!bAlignVertical)
{
++nOffsetLineBeg;
}
}
public override int LenNodeBeg(PegNode p) { return LenIdAsName(p) + 1; }
public override int LenNodeEnd(PegNode p) { return 1; }
public override void PrintLeaf(PegNode p, ref int nOffsetLineBeg, bool bAlignVertical)
{
if (bVerbose_)
{
PrintIdAsName(p);
treeOut_.Write('<');
}
int len = p.match_.posEnd_ - p.match_.posBeg_;
treeOut_.Write("'");
if (len > 0)
{
treeOut_.Write(src_.Substring(p.match_.posBeg_, p.match_.posEnd_ - p.match_.posBeg_));
}
treeOut_.Write("'");
if (bVerbose_) treeOut_.Write('>');
}
public override int LenLeaf(PegNode p)
{
int nLen = p.match_.posEnd_ - p.match_.posBeg_ + 2;
if (bVerbose_) nLen += LenIdAsName(p) + 2;
return nLen;
}
public override bool IsLeaf(PegNode p)
{
return p.child_ == null;
}
public override void
PrintDistNext(PegNode p, bool bAlignVertical, ref int nOffsetLineBeg, int nLevel)
{
if (bAlignVertical)
{
treeOut_.WriteLine();
treeOut_.Write(new string(' ', nOffsetLineBeg));
}
else
{
treeOut_.Write(' ');
++nOffsetLineBeg;
}
}
public override int
LenDistNext(PegNode p, bool bAlignVertical, ref int nOffsetLineBeg, int nLevel)
{
return 1;
}
int LenIdAsName(PegNode p)
{
string name = GetNodeName_(p);
return name.Length;
}
void PrintIdAsName(PegNode p)
{
string name = GetNodeName_(p);
treeOut_.Write(name);
}
#endregion Methods
}
#endregion Syntax/Parse-Tree related classes
#region Parsers
public abstract class PegBaseParser
{
#region Data Types
public delegate bool Matcher();
public delegate PegNode Creator(ECreatorPhase ePhase, PegNode parentOrCreated, int id);
#endregion Data Types
#region Data members
protected int srcLen_;
protected int pos_;
protected bool bMute_;
protected TextWriter errOut_;
protected Creator nodeCreator_;
protected int maxpos_;
PegTree tree;
#endregion Data members
public virtual string GetRuleNameFromId(int id)
{//normally overridden
switch (id)
{
case (int)ESpecialNodes.eFatal: return "FATAL";
case (int)ESpecialNodes.eAnonymNTNode: return "Nonterminal";
case (int)ESpecialNodes.eAnonymASTNode: return "ASTNode";
case (int)ESpecialNodes.eAnonymousNode: return "Node";
default: return id.ToString();
}
}
public virtual void GetProperties(out EncodingClass encoding, out UnicodeDetection detection)
{
encoding = EncodingClass.ascii;
detection = UnicodeDetection.notApplicable;
}
public int GetMaximumPosition()
{
return maxpos_;
}
protected PegNode DefaultNodeCreator(ECreatorPhase phase, PegNode parentOrCreated, int id)
{
if (phase == ECreatorPhase.eCreate || phase == ECreatorPhase.eCreateAndComplete)
return new PegNode(parentOrCreated, id);
else
{
if (parentOrCreated.match_.posEnd_ > maxpos_)
maxpos_ = parentOrCreated.match_.posEnd_;
return null;
}
}
#region Constructors
public PegBaseParser(TextWriter errOut)
{
srcLen_ = pos_ = 0;
errOut_ = errOut;
nodeCreator_ = DefaultNodeCreator;
}
#endregion Constructors
#region Reinitialization, TextWriter access,Tree Access
public void Construct(TextWriter Fout)
{
srcLen_ = pos_ = 0;
bMute_ = false;
SetErrorDestination(Fout);
ResetTree();
}
public void Rewind() { pos_ = 0; }
public void SetErrorDestination(TextWriter errOut)
{
errOut_ = errOut == null ? new StreamWriter(System.Console.OpenStandardError())
: errOut;
}
#endregion Reinitialization, TextWriter access,Tree Access
#region Tree root access, Tree Node generation/display
public PegNode GetRoot() { return tree.root_; }
public void ResetTree()
{
tree.root_ = null;
tree.cur_ = null;
tree.addPolicy = PegTree.AddPolicy.eAddAsChild;
}
void AddTreeNode(int nId, PegTree.AddPolicy newAddPolicy, Creator createNode, ECreatorPhase ePhase)
{
if (bMute_) return;
if (tree.root_ == null)
{
tree.root_ = tree.cur_ = createNode(ePhase, tree.cur_, nId);
}
else if (tree.addPolicy == PegTree.AddPolicy.eAddAsChild)
{
tree.cur_ = tree.cur_.child_ = createNode(ePhase, tree.cur_, nId);
}
else
{
tree.cur_ = tree.cur_.next_ = createNode(ePhase, tree.cur_.parent_, nId);
}
tree.addPolicy = newAddPolicy;
}
void RestoreTree(PegNode prevCur, PegTree.AddPolicy prevPolicy)
{
if (bMute_) return;
if (prevCur == null)
{
tree.root_ = null;
}
else if (prevPolicy == PegTree.AddPolicy.eAddAsChild)
{
prevCur.child_ = null;
}
else
{
prevCur.next_ = null;
}
tree.cur_ = prevCur;
tree.addPolicy = prevPolicy;
}
public bool TreeChars(Matcher toMatch)
{
return TreeCharsWithId((int)ESpecialNodes.eAnonymousNode, toMatch);
}
public bool TreeChars(Creator nodeCreator, Matcher toMatch)
{
return TreeCharsWithId(nodeCreator, (int)ESpecialNodes.eAnonymousNode, toMatch);
}
public bool TreeCharsWithId(int nId, Matcher toMatch)
{
return TreeCharsWithId(nodeCreator_, nId, toMatch);
}
public bool TreeCharsWithId(Creator nodeCreator, int nId, Matcher toMatch)
{
int pos = pos_;
if (toMatch())
{
if (!bMute_)
{
AddTreeNode(nId, PegTree.AddPolicy.eAddAsSibling, nodeCreator, ECreatorPhase.eCreateAndComplete);
tree.cur_.match_.posBeg_ = pos;
tree.cur_.match_.posEnd_ = pos_;
}
return true;
}
return false;
}
public bool TreeNT(int nRuleId, Matcher toMatch)
{
return TreeNT(nodeCreator_, nRuleId, toMatch);
}
public bool TreeNT(Creator nodeCreator, int nRuleId, Matcher toMatch)
{
if (bMute_) return toMatch();
PegNode prevCur = tree.cur_, ruleNode;
PegTree.AddPolicy prevPolicy = tree.addPolicy;
int posBeg = pos_;
AddTreeNode(nRuleId, PegTree.AddPolicy.eAddAsChild, nodeCreator, ECreatorPhase.eCreate);
ruleNode = tree.cur_;
bool bMatches = toMatch();
if (!bMatches) RestoreTree(prevCur, prevPolicy);
else
{
ruleNode.match_.posBeg_ = posBeg;
ruleNode.match_.posEnd_ = pos_;
tree.cur_ = ruleNode;
tree.addPolicy = PegTree.AddPolicy.eAddAsSibling;
nodeCreator(ECreatorPhase.eCreationComplete, ruleNode, nRuleId);
}
return bMatches;
}
public bool TreeAST(int nRuleId, Matcher toMatch)
{
return TreeAST(nodeCreator_, nRuleId, toMatch);
}
public bool TreeAST(Creator nodeCreator, int nRuleId, Matcher toMatch)
{
if (bMute_) return toMatch();
bool bMatches = TreeNT(nodeCreator, nRuleId, toMatch);
if (bMatches)
{
if (tree.cur_.child_ != null && tree.cur_.child_.next_ == null && tree.cur_.parent_ != null)
{
if (tree.cur_.parent_.child_ == tree.cur_)
{
tree.cur_.parent_.child_ = tree.cur_.child_;
tree.cur_.child_.parent_ = tree.cur_.parent_;
tree.cur_ = tree.cur_.child_;
}
else
{
PegNode prev;
for (prev = tree.cur_.parent_.child_; prev != null && prev.next_ != tree.cur_; prev = prev.next_)
{
}
if (prev != null)
{
prev.next_ = tree.cur_.child_;
tree.cur_.child_.parent_ = tree.cur_.parent_;
tree.cur_ = tree.cur_.child_;
}
}
}
}
return bMatches;
}
public bool TreeNT(Matcher toMatch)
{
return TreeNT((int)ESpecialNodes.eAnonymNTNode, toMatch);
}
public bool TreeNT(Creator nodeCreator, Matcher toMatch)
{
return TreeNT(nodeCreator, (int)ESpecialNodes.eAnonymNTNode, toMatch);
}
public bool TreeAST(Matcher toMatch)
{
return TreeAST((int)ESpecialNodes.eAnonymASTNode, toMatch);
}
public bool TreeAST(Creator nodeCreator, Matcher toMatch)
{
return TreeAST(nodeCreator, (int)ESpecialNodes.eAnonymASTNode, toMatch);
}
public virtual string TreeNodeToString(PegNode node)
{
return GetRuleNameFromId(node.id_);
}
public void SetNodeCreator(Creator nodeCreator)
{
Debug.Assert(nodeCreator != null);
nodeCreator_ = nodeCreator;
}
#endregion Tree Node generation
#region PEG e1 e2 .. ; &e1 ; !e1 ; e? ; e* ; e+ ; e{a,b} ; .
public bool And(Matcher pegSequence)
{
PegNode prevCur = tree.cur_;
PegTree.AddPolicy prevPolicy = tree.addPolicy;
int pos0 = pos_;
bool bMatches = pegSequence();
if (!bMatches)
{
pos_ = pos0;
RestoreTree(prevCur, prevPolicy);
}
return bMatches;
}
public bool Peek(Matcher toMatch)
{
int pos0 = pos_;
bool prevMute = bMute_;
bMute_ = true;
bool bMatches = toMatch();
bMute_ = prevMute;
pos_ = pos0;
return bMatches;
}
public bool Not(Matcher toMatch)
{
int pos0 = pos_;
bool prevMute = bMute_;
bMute_ = true;
bool bMatches = toMatch();
bMute_ = prevMute;
pos_ = pos0;
return !bMatches;
}
public bool PlusRepeat(Matcher toRepeat)
{
int i;
for (i = 0; ; ++i)
{
int pos0 = pos_;
if (!toRepeat())
{
pos_ = pos0;
break;
}
}
return i > 0;
}
public bool OptRepeat(Matcher toRepeat)
{
for (; ; )
{
int pos0 = pos_;
if (!toRepeat())
{
pos_ = pos0;
return true;
}
}
}
public bool Option(Matcher toMatch)
{
int pos0 = pos_;
if (!toMatch()) pos_ = pos0;
return true;
}
public bool ForRepeat(int count, Matcher toRepeat)
{
PegNode prevCur = tree.cur_;
PegTree.AddPolicy prevPolicy = tree.addPolicy;
int pos0 = pos_;
int i;
for (i = 0; i < count; ++i)
{
if (!toRepeat())
{
pos_ = pos0;
RestoreTree(prevCur, prevPolicy);
return false;
}
}
return true;
}
public bool ForRepeat(int lower, int upper, Matcher toRepeat)
{
PegNode prevCur = tree.cur_;
PegTree.AddPolicy prevPolicy = tree.addPolicy;
int pos0 = pos_;
int i;
for (i = 0; i < upper; ++i)
{
if (!toRepeat()) break;
}
if (i < lower)
{
pos_ = pos0;
RestoreTree(prevCur, prevPolicy);
return false;
}
return true;
}
public bool Any()
{
if (pos_ < srcLen_)
{
++pos_;
return true;
}
return false;
}
#endregion PEG e1 e2 .. ; &e1 ; !e1 ; e? ; e* ; e+ ; e{a,b} ; .
}
public class PegByteParser : PegBaseParser
{
#region Data members
protected byte[] src_;
PegError errors;
#endregion Data members
#region PEG optimizations
public sealed class BytesetData
{
public struct Range
{
public Range(byte low, byte high) { this.low = low; this.high = high; }
public byte low;
public byte high;
}
System.Collections.BitArray charSet_;
bool bNegated_;
public BytesetData(System.Collections.BitArray b)
: this(b, false)
{
}
public BytesetData(System.Collections.BitArray b, bool bNegated)
{
charSet_ = new System.Collections.BitArray(b);
bNegated_ = bNegated;
}
public BytesetData(Range[] r, byte[] c)
: this(r, c, false)
{
}
public BytesetData(Range[] r, byte[] c, bool bNegated)
{
int max = 0;
if (r != null) foreach (Range val in r) if (val.high > max) max = val.high;
if (c != null) foreach (int val in c) if (val > max) max = val;
charSet_ = new System.Collections.BitArray(max + 1, false);
if (r != null)
{
foreach (Range val in r)
{
for (int i = val.low; i <= val.high; ++i)
{
charSet_[i] = true;
}
}
}
if (c != null) foreach (int val in c) charSet_[val] = true;
bNegated_ = bNegated;
}
public bool Matches(byte c)
{
bool bMatches = c < charSet_.Length && charSet_[(int)c];
if (bNegated_) return !bMatches;
else return bMatches;
}
}
/* public class BytesetData
{
public struct Range
{
public Range(byte low, byte high) { this.low = low; this.high = high; }
public byte low;
public byte high;
}
protected System.Collections.BitArray charSet_;
bool bNegated_;
public BytesetData(System.Collections.BitArray b, bool bNegated)
{
charSet_ = new System.Collections.BitArray(b);
bNegated_ = bNegated;
}
public BytesetData(byte[] c, bool bNegated)
{
int max = 0;
foreach (int val in c) if (val > max) max = val;
charSet_ = new System.Collections.BitArray(max + 1, false);
foreach (int val in c) charSet_[val] = true;
bNegated_ = bNegated;
}
public BytesetData(Range[] r, byte[] c, bool bNegated)
{
int max = 0;
foreach (Range val in r) if (val.high > max) max = val.high;
foreach (int val in c) if (val > max) max = val;
charSet_ = new System.Collections.BitArray(max + 1, false);
foreach (Range val in r)
{
for (int i = val.low; i <= val.high; ++i)
{
charSet_[i] = true;
}
}
foreach (int val in c) charSet_[val] = true;
}
public bool Matches(byte c)
{
bool bMatches = c < charSet_.Length && charSet_[(int)c];
if (bNegated_) return !bMatches;
else return bMatches;
}
}*/
#endregion PEG optimizations
#region Constructors
public PegByteParser()
: this(null)
{
}
public PegByteParser(byte[] src):base(null)
{
SetSource(src);
}
public PegByteParser(byte[] src, TextWriter errOut):base(errOut)
{
SetSource(src);
}
#endregion Constructors
#region Reinitialization, Source Code access, TextWriter access,Tree Access
public void Construct(byte[] src, TextWriter Fout)
{
base.Construct(Fout);
SetSource(src);
}
public void SetSource(byte[] src)
{
if (src == null) src = new byte[0];
src_ = src; srcLen_ = src.Length;
errors.lineStarts = new SortedList<int, int>();
errors.lineStarts[0] = 1;
}
public byte[] GetSource() { return src_; }
#endregion Reinitialization, Source Code access, TextWriter access,Tree Access
#region Setting host variables
public bool Into(Matcher toMatch,out byte[] into)
{
int pos = pos_;
if (toMatch())
{
int nLen = pos_ - pos;
into= new byte[nLen];
for(int i=0;i<nLen;++i){
into[i] = src_[i+pos];
}
return true;
}
else
{
into = null;
return false;
}
}
public bool Into(Matcher toMatch,out PegBegEnd begEnd)
{
begEnd.posBeg_ = pos_;
bool bMatches = toMatch();
begEnd.posEnd_ = pos_;
return bMatches;
}
public bool Into(Matcher toMatch,out int into)
{
byte[] s;
into = 0;
if (!Into(toMatch,out s)) return false;
into = 0;
for (int i = 0; i < s.Length; ++i)
{
into <<= 8;
into |= s[i];
}
return true;
}
public bool Into(Matcher toMatch,out double into)
{
byte[] s;
into = 0.0;
if (!Into(toMatch,out s)) return false;
System.Text.Encoding encoding = System.Text.Encoding.UTF8;
string sAsString = encoding.GetString(s);
if (!System.Double.TryParse(sAsString, out into)) return false;
return true;
}
public bool BitsInto(int lowBitNo, int highBitNo,out int into)
{
if (pos_ < srcLen_)
{
into = (src_[pos_] >> (lowBitNo - 1)) & ((1 << highBitNo) - 1);
++pos_;
return true;
}
into = 0;
return false;
}
public bool BitsInto(int lowBitNo, int highBitNo, BytesetData toMatch, out int into)
{
if (pos_ < srcLen_)
{
byte value = (byte)((src_[pos_] >> (lowBitNo - 1)) & ((1 << highBitNo) - 1));
++pos_;
into = value;
return toMatch.Matches(value);
}
into = 0;
return false;
}
#endregion Setting host variables
#region Error handling
void LogOutMsg(string sErrKind, string sMsg)
{
errOut_.WriteLine("<{0}>{1}:{2}", pos_, sErrKind, sMsg);
errOut_.Flush();
}
public virtual bool Fatal(string sMsg)
{
LogOutMsg("FATAL", sMsg);
throw new PegException();
}
public bool Warning(string sMsg)
{
LogOutMsg("WARNING", sMsg);
return true;
}
#endregion Error handling
#region PEG Bit level equivalents for PEG e1 ; &e1 ; !e1; e1:into ;
public bool Bits(int lowBitNo, int highBitNo, byte toMatch)
{
if (pos_ < srcLen_ && ((src_[pos_] >> (lowBitNo - 1)) & ((1 << highBitNo) - 1)) == toMatch)
{
++pos_;
return true;
}
return false;
}
public bool Bits(int lowBitNo, int highBitNo,BytesetData toMatch)
{
if( pos_ < srcLen_ )
{
byte value= (byte)((src_[pos_] >> (lowBitNo - 1)) & ((1 << highBitNo) - 1));
++pos_;
return toMatch.Matches(value);
}
return false;
}
public bool PeekBits(int lowBitNo, int highBitNo, byte toMatch)
{
return pos_ < srcLen_ && ((src_[pos_] >> (lowBitNo - 1)) & ((1 << highBitNo) - 1)) == toMatch;
}
public bool NotBits(int lowBitNo, int highBitNo, byte toMatch)
{
return !(pos_ < srcLen_ && ((src_[pos_] >> (lowBitNo - 1)) & ((1 << highBitNo) - 1)) == toMatch);
}
public bool IntoBits(int lowBitNo,int highBitNo,out int val)
{
return BitsInto(lowBitNo,highBitNo,out val);
}
public bool IntoBits(int lowBitNo, int highBitNo, BytesetData toMatch, out int val)
{
return BitsInto(lowBitNo, highBitNo, out val);
}
public bool Bit(int bitNo,byte toMatch)
{
if (pos_ < srcLen_ && ((src_[pos_]>>(bitNo-1))&1)==toMatch){
++pos_;
return true;
}
return false;
}
public bool PeekBit(int bitNo, byte toMatch)
{
return pos_ < srcLen_ && ((src_[pos_] >> (bitNo - 1)) & 1) == toMatch;
}
public bool NotBit(int bitNo, byte toMatch)
{
return !(pos_ < srcLen_ && ((src_[pos_] >> (bitNo - 1)) & 1) == toMatch);
}
#endregion PEG Bit level equivalents for PEG e1 ; &e1 ; !e1; e1:into ;
#region PEG '<Literal>' / '<Literal>'/i / [low1-high1,low2-high2..] / [<CharList>]
public bool Char(byte c1)
{
if (pos_ < srcLen_ && src_[pos_] == c1)
{ ++pos_; return true; }
return false;
}
public bool Char(byte c1, byte c2)
{
if (pos_ + 1 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2)
{ pos_ += 2; return true; }
return false;
}
public bool Char(byte c1, byte c2, byte c3)
{
if (pos_ + 2 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3)
{ pos_ += 3; return true; }
return false;
}
public bool Char(byte c1, byte c2, byte c3, byte c4)
{
if (pos_ + 3 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4)
{ pos_ += 4; return true; }
return false;
}
public bool Char(byte c1, byte c2, byte c3, byte c4, byte c5)
{
if (pos_ + 4 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4
&& src_[pos_ + 4] == c5)
{ pos_ += 5; return true; }
return false;
}
public bool Char(byte c1, byte c2, byte c3, byte c4, byte c5, byte c6)
{
if (pos_ + 5 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4
&& src_[pos_ + 4] == c5
&& src_[pos_ + 5] == c6)
{ pos_ += 6; return true; }
return false;
}
public bool Char(byte c1, byte c2, byte c3, byte c4, byte c5, byte c6, byte c7)
{
if (pos_ + 6 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4
&& src_[pos_ + 4] == c5
&& src_[pos_ + 5] == c6
&& src_[pos_ + 6] == c7)
{ pos_ += 7; return true; }
return false;
}
public bool Char(byte c1, byte c2, byte c3, byte c4, byte c5, byte c6, byte c7, byte c8)
{
if (pos_ + 7 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4
&& src_[pos_ + 4] == c5
&& src_[pos_ + 5] == c6
&& src_[pos_ + 6] == c7
&& src_[pos_ + 7] == c8)
{ pos_ += 8; return true; }
return false;
}
public bool Char(byte[] s)
{
int sLength = s.Length;
if (pos_ + sLength > srcLen_) return false;
for (int i = 0; i < sLength; ++i)
{
if (s[i] != src_[pos_ + i]) return false;
}
pos_ += sLength;
return true;
}
public static byte ToUpper(byte c)
{
if (c >= 97 && c <= 122) return (byte)(c - 32); else return c;
}
public bool IChar(byte c1)
{
if (pos_ < srcLen_ && ToUpper(src_[pos_]) == c1)
{ ++pos_; return true; }
return false;
}
public bool IChar(byte c1, byte c2)
{
if (pos_ + 1 < srcLen_
&& ToUpper(src_[pos_]) == ToUpper(c1)
&& ToUpper(src_[pos_ + 1]) == ToUpper(c2))
{ pos_ += 2; return true; }
return false;
}
public bool IChar(byte c1, byte c2, byte c3)
{
if (pos_ + 2 < srcLen_
&& ToUpper(src_[pos_]) == ToUpper(c1)
&& ToUpper(src_[pos_ + 1]) == ToUpper(c2)
&& ToUpper(src_[pos_ + 2]) == ToUpper(c3))
{ pos_ += 3; return true; }
return false;
}
public bool IChar(byte c1, byte c2, byte c3, byte c4)
{
if (pos_ + 3 < srcLen_
&& ToUpper(src_[pos_]) == ToUpper(c1)
&& ToUpper(src_[pos_ + 1]) == ToUpper(c2)
&& ToUpper(src_[pos_ + 2]) == ToUpper(c3)
&& ToUpper(src_[pos_ + 3]) == ToUpper(c4))
{ pos_ += 4; return true; }
return false;
}
public bool IChar(byte c1, byte c2, byte c3, byte c4, byte c5)
{
if (pos_ + 4 < srcLen_
&& ToUpper(src_[pos_]) == ToUpper(c1)
&& ToUpper(src_[pos_ + 1]) == ToUpper(c2)
&& ToUpper(src_[pos_ + 2]) == ToUpper(c3)
&& ToUpper(src_[pos_ + 3]) == ToUpper(c4)
&& ToUpper(src_[pos_ + 4]) == ToUpper(c5))
{ pos_ += 5; return true; }
return false;
}
public bool IChar(byte c1, byte c2, byte c3, byte c4, byte c5, byte c6)
{
if (pos_ + 5 < srcLen_
&& ToUpper(src_[pos_]) == ToUpper(c1)
&& ToUpper(src_[pos_ + 1]) == ToUpper(c2)
&& ToUpper(src_[pos_ + 2]) == ToUpper(c3)
&& ToUpper(src_[pos_ + 3]) == ToUpper(c4)
&& ToUpper(src_[pos_ + 4]) == ToUpper(c5)
&& ToUpper(src_[pos_ + 5]) == ToUpper(c6))
{ pos_ += 6; return true; }
return false;
}
public bool IChar(byte c1, byte c2, byte c3, byte c4, byte c5, byte c6, byte c7)
{
if (pos_ + 6 < srcLen_
&& ToUpper(src_[pos_]) == ToUpper(c1)
&& ToUpper(src_[pos_ + 1]) == ToUpper(c2)
&& ToUpper(src_[pos_ + 2]) == ToUpper(c3)
&& ToUpper(src_[pos_ + 3]) == ToUpper(c4)
&& ToUpper(src_[pos_ + 4]) == ToUpper(c5)
&& ToUpper(src_[pos_ + 5]) == ToUpper(c6)
&& ToUpper(src_[pos_ + 6]) == ToUpper(c7))
{ pos_ += 7; return true; }
return false;
}
public bool IChar(byte[] s)
{
int sLength = s.Length;
if (pos_ + sLength > srcLen_) return false;
for (int i = 0; i < sLength; ++i)
{
if (s[i] != ToUpper(src_[pos_ + i])) return false;
}
pos_ += sLength;
return true;
}
public bool In(byte c0, byte c1)
{
if (pos_ < srcLen_
&& src_[pos_] >= c0 && src_[pos_] <= c1)
{
++pos_;
return true;
}
return false;
}
public bool In(byte c0, byte c1, byte c2, byte c3)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c >= c0 && c <= c1
|| c >= c2 && c <= c3)
{
++pos_;
return true;
}
}
return false;
}
public bool In(byte c0, byte c1, byte c2, byte c3, byte c4, byte c5)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c >= c0 && c <= c1
|| c >= c2 && c <= c3
|| c >= c4 && c <= c5)
{
++pos_;
return true;
}
}
return false;
}
public bool In(byte c0, byte c1, byte c2, byte c3, byte c4, byte c5, byte c6, byte c7)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c >= c0 && c <= c1
|| c >= c2 && c <= c3
|| c >= c4 && c <= c5
|| c >= c6 && c <= c7)
{
++pos_;
return true;
}
}
return false;
}
public bool In(byte[] s)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
for (int i = 0; i < s.Length - 1; i += 2)
{
if (c >= s[i] && c <= s[i + 1])
{
++pos_;
return true;
}
}
}
return false;
}
public bool NotIn(byte[] s)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
for (int i = 0; i < s.Length - 1; i += 2)
{
if ( c >= s[i] && c <= s[i + 1] ) return false;
}
++pos_;
return true;
}
return false;
}
public bool OneOf(byte c0, byte c1)
{
if (pos_ < srcLen_
&& (src_[pos_] == c0 || src_[pos_] == c1))
{
++pos_;
return true;
}
return false;
}
public bool OneOf(byte c0, byte c1, byte c2)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c == c0 || c == c1 || c == c2)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(byte c0, byte c1, byte c2, byte c3)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(byte c0, byte c1, byte c2, byte c3, byte c4)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3 || c == c4)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(byte c0, byte c1, byte c2, byte c3, byte c4, byte c5)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3 || c == c4 || c == c5)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(byte c0, byte c1, byte c2, byte c3, byte c4, byte c5, byte c6)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3 || c == c4 || c == c5 || c == c6)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(byte c0, byte c1, byte c2, byte c3, byte c4, byte c5, byte c6, byte c7)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3 || c == c4 || c == c5 || c == c6 || c == c7)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(byte[] s)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
for (int i = 0; i < s.Length; ++i)
{
if (c == s[i]) { ++pos_; return true; }
}
}
return false;
}
public bool NotOneOf(byte[] s)
{
if (pos_ < srcLen_)
{
byte c = src_[pos_];
for (int i = 0; i < s.Length; ++i)
{
if (c == s[i]) { return false; }
}
return true;
}
return false;
}
public bool OneOf(BytesetData bset)
{
if(pos_ < srcLen_ && bset.Matches(src_[pos_]))
{
++pos_; return true;
}
return false;
}
#endregion PEG '<Literal>' / '<Literal>'/i / [low1-high1,low2-high2..] / [<CharList>]
}
public class PegCharParser : PegBaseParser
{
#region Data members
protected string src_;
PegError errors;
#endregion Data members
#region PEG optimizations
public sealed class OptimizedCharset
{
public struct Range
{
public Range(char low, char high) { this.low = low; this.high = high; }
public char low;
public char high;
}
System.Collections.BitArray charSet_;
bool bNegated_;
public OptimizedCharset(System.Collections.BitArray b)
: this(b, false)
{
}
public OptimizedCharset(System.Collections.BitArray b, bool bNegated)
{
charSet_ = new System.Collections.BitArray(b);
bNegated_ = bNegated;
}
public OptimizedCharset(Range[] r, char[] c)
: this(r, c, false)
{
}
public OptimizedCharset(Range[] r, char[] c, bool bNegated)
{
int max = 0;
if (r != null) foreach (Range val in r) if (val.high > max) max = val.high;
if (c != null) foreach (int val in c) if (val > max) max = val;
charSet_ = new System.Collections.BitArray(max + 1, false);
if (r != null)
{
foreach (Range val in r)
{
for (int i = val.low; i <= val.high; ++i)
{
charSet_[i] = true;
}
}
}
if (c != null) foreach (int val in c) charSet_[val] = true;
bNegated_ = bNegated;
}
public bool Matches(char c)
{
bool bMatches = c < charSet_.Length && charSet_[(int)c];
if (bNegated_) return !bMatches;
else return bMatches;
}
}
public sealed class OptimizedLiterals
{
internal class Trie
{
internal Trie(char cThis,int nIndex, string[] literals)
{
cThis_ = cThis;
char cMax = char.MinValue;
cMin_ = char.MaxValue;
HashSet<char> followChars = new HashSet<char>();
foreach (string literal in literals)
{
if (literal==null || nIndex > literal.Length ) continue;
if (nIndex == literal.Length)
{
bLitEnd_ = true;
continue;
}
char c = literal[nIndex];
followChars.Add(c);
if ( c < cMin_) cMin_ = c;
if ( c > cMax) cMax = c;
}
if (followChars.Count == 0)
{
children_ = null;
}
else
{
children_ = new Trie[(cMax - cMin_) + 1];
foreach (char c in followChars)
{
List<string> subLiterals = new List<string>();
foreach (string s in literals)
{
if ( nIndex >= s.Length ) continue;
if (c == s[nIndex])
{
subLiterals.Add(s);
}
}
children_[c - cMin_] = new Trie(c, nIndex + 1, subLiterals.ToArray());
}
}
}
internal char cThis_; //character stored in this node
internal bool bLitEnd_; //end of literal
internal char cMin_; //first valid character in children
internal Trie[] children_; //contains the successor node of cThis_;
}
internal Trie literalsRoot;
public OptimizedLiterals(string[] litAlternatives)
{
literalsRoot = new Trie('\u0000', 0, litAlternatives);
}
}
#endregion PEG optimizations
#region Constructors
public PegCharParser():this("")
{
}
public PegCharParser(string src):base(null)
{
SetSource(src);
}
public PegCharParser(string src, TextWriter errOut):base(errOut)
{
SetSource(src);
nodeCreator_ = DefaultNodeCreator;
}
#endregion Constructors
#region Overrides
public override string TreeNodeToString(PegNode node)
{
string label = base.TreeNodeToString(node);
if (node.id_ == (int)ESpecialNodes.eAnonymousNode)
{
string value = node.GetAsString(src_);
if (value.Length < 32) label += " <" + value + ">";
else label += " <" + value.Substring(0, 29) + "...>";
}
return label;
}
#endregion Overrides
#region Reinitialization, Source Code access, TextWriter access,Tree Access
public void Construct(string src, TextWriter Fout)
{
base.Construct(Fout);
SetSource(src);
}
public void SetSource(string src)
{
if (src == null) src = "";
src_ = src; srcLen_ = src.Length; pos_ = 0;
errors.lineStarts = new SortedList<int, int>();
errors.lineStarts[0] = 1;
}
public string GetSource() { return src_; }
#endregion Reinitialization, Source Code access, TextWriter access,Tree Access
#region Setting host variables
public bool Into(Matcher toMatch,out string into)
{
int pos = pos_;
if (toMatch())
{
into = src_.Substring(pos, pos_ - pos);
return true;
}
else
{
into = "";
return false;
}
}
public bool Into(Matcher toMatch,out PegBegEnd begEnd)
{
begEnd.posBeg_ = pos_;
bool bMatches = toMatch();
begEnd.posEnd_ = pos_;
return bMatches;
}
public bool Into(Matcher toMatch,out int into)
{
string s;
into = 0;
if (!Into(toMatch,out s)) return false;
if (!System.Int32.TryParse(s, out into)) return false;
return true;
}
public bool Into(Matcher toMatch,out double into)
{
string s;
into = 0.0;
if (!Into(toMatch,out s)) return false;
if (!System.Double.TryParse(s, out into)) return false;
return true;
}
#endregion Setting host variables
#region Error handling
void LogOutMsg(string sErrKind, string sMsg)
{
int lineNo, colNo;
errors.GetLineAndCol(src_, pos_, out lineNo, out colNo);
errOut_.WriteLine("<{0},{1},{2}>{3}:{4}", lineNo, colNo, maxpos_, sErrKind, sMsg);
errOut_.Flush();
}
public virtual bool Fatal(string sMsg)
{
LogOutMsg("FATAL", sMsg);
throw new PegException();
//return false;
}
public bool Warning(string sMsg)
{
LogOutMsg("WARNING", sMsg);
return true;
}
#endregion Error handling
#region PEG optimized version of e* ; e+
public bool OptRepeat(OptimizedCharset charset)
{
for (; pos_ < srcLen_ && charset.Matches(src_[pos_]); ++pos_) ;
return true;
}
public bool PlusRepeat(OptimizedCharset charset)
{
int pos0 = pos_;
for (; pos_ < srcLen_ && charset.Matches(src_[pos_]); ++pos_) ;
return pos_ > pos0;
}
#endregion PEG optimized version of e* ; e+
#region PEG '<Literal>' / '<Literal>'/i / [low1-high1,low2-high2..] / [<CharList>]
public bool Char(char c1)
{
if (pos_ < srcLen_ && src_[pos_] == c1)
{ ++pos_; return true; }
return false;
}
public bool Char(char c1, char c2)
{
if (pos_ + 1 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2)
{ pos_ += 2; return true; }
return false;
}
public bool Char(char c1, char c2, char c3)
{
if (pos_ + 2 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3)
{ pos_ += 3; return true; }
return false;
}
public bool Char(char c1, char c2, char c3, char c4)
{
if (pos_ + 3 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4)
{ pos_ += 4; return true; }
return false;
}
public bool Char(char c1, char c2, char c3, char c4, char c5)
{
if (pos_ + 4 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4
&& src_[pos_ + 4] == c5)
{ pos_ += 5; return true; }
return false;
}
public bool Char(char c1, char c2, char c3, char c4, char c5, char c6)
{
if (pos_ + 5 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4
&& src_[pos_ + 4] == c5
&& src_[pos_ + 5] == c6)
{ pos_ += 6; return true; }
return false;
}
public bool Char(char c1, char c2, char c3, char c4, char c5, char c6, char c7)
{
if (pos_ + 6 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4
&& src_[pos_ + 4] == c5
&& src_[pos_ + 5] == c6
&& src_[pos_ + 6] == c7)
{ pos_ += 7; return true; }
return false;
}
public bool Char(char c1, char c2, char c3, char c4, char c5, char c6, char c7, char c8)
{
if (pos_ + 7 < srcLen_
&& src_[pos_] == c1
&& src_[pos_ + 1] == c2
&& src_[pos_ + 2] == c3
&& src_[pos_ + 3] == c4
&& src_[pos_ + 4] == c5
&& src_[pos_ + 5] == c6
&& src_[pos_ + 6] == c7
&& src_[pos_ + 7] == c8)
{ pos_ += 8; return true; }
return false;
}
public bool Char(string s)
{
int sLength = s.Length;
if (pos_ + sLength > srcLen_) return false;
for (int i = 0; i < sLength; ++i)
{
if (s[i] != src_[pos_ + i]) return false;
}
pos_ += sLength;
return true;
}
public bool IChar(char c1)
{
if (pos_ < srcLen_ && System.Char.ToUpper(src_[pos_]) == c1)
{ ++pos_; return true; }
return false;
}
public bool IChar(char c1, char c2)
{
if (pos_ + 1 < srcLen_
&& System.Char.ToUpper(src_[pos_]) == System.Char.ToUpper(c1)
&& System.Char.ToUpper(src_[pos_ + 1]) == System.Char.ToUpper(c2))
{ pos_ += 2; return true; }
return false;
}
public bool IChar(char c1, char c2, char c3)
{
if (pos_ + 2 < srcLen_
&& System.Char.ToUpper(src_[pos_]) == System.Char.ToUpper(c1)
&& System.Char.ToUpper(src_[pos_ + 1]) == System.Char.ToUpper(c2)
&& System.Char.ToUpper(src_[pos_ + 2]) == System.Char.ToUpper(c3))
{ pos_ += 3; return true; }
return false;
}
public bool IChar(char c1, char c2, char c3, char c4)
{
if (pos_ + 3 < srcLen_
&& System.Char.ToUpper(src_[pos_]) == System.Char.ToUpper(c1)
&& System.Char.ToUpper(src_[pos_ + 1]) == System.Char.ToUpper(c2)
&& System.Char.ToUpper(src_[pos_ + 2]) == System.Char.ToUpper(c3)
&& System.Char.ToUpper(src_[pos_ + 3]) == System.Char.ToUpper(c4))
{ pos_ += 4; return true; }
return false;
}
public bool IChar(char c1, char c2, char c3, char c4, char c5)
{
if (pos_ + 4 < srcLen_
&& System.Char.ToUpper(src_[pos_]) == System.Char.ToUpper(c1)
&& System.Char.ToUpper(src_[pos_ + 1]) == System.Char.ToUpper(c2)
&& System.Char.ToUpper(src_[pos_ + 2]) == System.Char.ToUpper(c3)
&& System.Char.ToUpper(src_[pos_ + 3]) == System.Char.ToUpper(c4)
&& System.Char.ToUpper(src_[pos_ + 4]) == System.Char.ToUpper(c5))
{ pos_ += 5; return true; }
return false;
}
public bool IChar(char c1, char c2, char c3, char c4, char c5, char c6)
{
if (pos_ + 5 < srcLen_
&& System.Char.ToUpper(src_[pos_]) == System.Char.ToUpper(c1)
&& System.Char.ToUpper(src_[pos_ + 1]) == System.Char.ToUpper(c2)
&& System.Char.ToUpper(src_[pos_ + 2]) == System.Char.ToUpper(c3)
&& System.Char.ToUpper(src_[pos_ + 3]) == System.Char.ToUpper(c4)
&& System.Char.ToUpper(src_[pos_ + 4]) == System.Char.ToUpper(c5)
&& System.Char.ToUpper(src_[pos_ + 5]) == System.Char.ToUpper(c6))
{ pos_ += 6; return true; }
return false;
}
public bool IChar(char c1, char c2, char c3, char c4, char c5, char c6, char c7)
{
if (pos_ + 6 < srcLen_
&& System.Char.ToUpper(src_[pos_]) == System.Char.ToUpper(c1)
&& System.Char.ToUpper(src_[pos_ + 1]) == System.Char.ToUpper(c2)
&& System.Char.ToUpper(src_[pos_ + 2]) == System.Char.ToUpper(c3)
&& System.Char.ToUpper(src_[pos_ + 3]) == System.Char.ToUpper(c4)
&& System.Char.ToUpper(src_[pos_ + 4]) == System.Char.ToUpper(c5)
&& System.Char.ToUpper(src_[pos_ + 5]) == System.Char.ToUpper(c6)
&& System.Char.ToUpper(src_[pos_ + 6]) == System.Char.ToUpper(c7))
{ pos_ += 7; return true; }
return false;
}
public bool IChar(string s)
{
int sLength = s.Length;
if (pos_ + sLength > srcLen_) return false;
for (int i = 0; i < sLength; ++i)
{
if (s[i] != System.Char.ToUpper(src_[pos_ + i])) return false;
}
pos_ += sLength;
return true;
}
public bool In(char c0, char c1)
{
if (pos_ < srcLen_
&& src_[pos_] >= c0 && src_[pos_] <= c1)
{
++pos_;
return true;
}
return false;
}
public bool In(char c0, char c1, char c2, char c3)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c >= c0 && c <= c1
|| c >= c2 && c <= c3)
{
++pos_;
return true;
}
}
return false;
}
public bool In(char c0, char c1, char c2, char c3, char c4, char c5)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c >= c0 && c <= c1
|| c >= c2 && c <= c3
|| c >= c4 && c <= c5)
{
++pos_;
return true;
}
}
return false;
}
public bool In(char c0, char c1, char c2, char c3, char c4, char c5, char c6, char c7)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c >= c0 && c <= c1
|| c >= c2 && c <= c3
|| c >= c4 && c <= c5
|| c >= c6 && c <= c7)
{
++pos_;
return true;
}
}
return false;
}
public bool In(string s)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
for (int i = 0; i < s.Length - 1; i += 2)
{
if (!(c >= s[i] && c <= s[i + 1])) return false;
}
++pos_;
return true;
}
return false;
}
public bool NotIn(string s)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
for (int i = 0; i < s.Length - 1; i += 2)
{
if ( c >= s[i] && c <= s[i + 1]) return false;
}
++pos_;
return true;
}
return false;
}
public bool OneOf(char c0, char c1)
{
if (pos_ < srcLen_
&& (src_[pos_] == c0 || src_[pos_] == c1))
{
++pos_;
return true;
}
return false;
}
public bool OneOf(char c0, char c1, char c2)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c == c0 || c == c1 || c == c2)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(char c0, char c1, char c2, char c3)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(char c0, char c1, char c2, char c3, char c4)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3 || c == c4)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(char c0, char c1, char c2, char c3, char c4, char c5)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3 || c == c4 || c == c5)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(char c0, char c1, char c2, char c3, char c4, char c5, char c6)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3 || c == c4 || c == c5 || c == c6)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(char c0, char c1, char c2, char c3, char c4, char c5, char c6, char c7)
{
if (pos_ < srcLen_)
{
char c = src_[pos_];
if (c == c0 || c == c1 || c == c2 || c == c3 || c == c4 || c == c5 || c == c6 || c == c7)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(string s)
{
if (pos_ < srcLen_)
{
if (s.IndexOf(src_[pos_]) != -1)
{
++pos_;
return true;
}
}
return false;
}
public bool NotOneOf(string s)
{
if (pos_ < srcLen_)
{
if (s.IndexOf(src_[pos_]) == -1)
{
++pos_;
return true;
}
}
return false;
}
public bool OneOf(OptimizedCharset cset)
{
if (pos_ < srcLen_ && cset.Matches(src_[pos_]))
{
++pos_; return true;
}
return false;
}
public bool OneOfLiterals(OptimizedLiterals litAlt)
{
OptimizedLiterals.Trie node = litAlt.literalsRoot;
int matchPos = pos_-1;
for (int pos = pos_; pos < srcLen_ ; ++pos)
{
char c = src_[pos];
if ( node.children_==null
|| c < node.cMin_ || c > node.cMin_ + node.children_.Length - 1
|| node.children_[c - node.cMin_] == null)
{
break;
}
node = node.children_[c - node.cMin_];
if (node.bLitEnd_) matchPos = pos + 1;
}
if (matchPos >= pos_)
{
pos_= matchPos;
return true;
}
else return false;
}
#endregion PEG '<Literal>' / '<Literal>'/i / [low1-high1,low2-high2..] / [<CharList>]
}
#endregion Parsers
}