Files
dmex b02427417c PH1.x: fixed build
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@5614 21ef857c-d57f-4fe0-8362-d861dc6d29cd
2014-02-25 23:14:38 +00:00

238 lines
6.8 KiB
C#

using System;
using System.Text;
namespace ProcessHacker.Common
{
public class Tokenizer
{
private string _text;
private int _i = 0;
public Tokenizer(string text)
{
_text = text;
}
public int Index
{
get { return _i; }
set { _i = value; }
}
public string EatId()
{
StringBuilder sb = new StringBuilder();
while (_i < _text.Length)
{
// identifiers can't start with a number-
if (sb.Length == 0)
{
if (!(char.IsLetter(_text[_i]) || _text[_i] == '_'))
break;
}
else
{
if (!(char.IsLetterOrDigit(_text[_i]) || _text[_i] == '_'))
break;
}
sb.Append(_text[_i]);
_i++;
}
return sb.ToString();
}
public string EatNumber()
{
StringBuilder sb = new StringBuilder();
while (_i < _text.Length)
{
// allow hex numbers and floating-point numbers
if (sb.Length == 1 && sb[0] == '0')
{
if (!char.IsDigit(_text[_i]) && char.ToLower(_text[_i]) != 'x' && _text[_i] != '.')
break;
}
else if (sb.Length >= 2 && sb[0] == '0' && char.ToLower(sb[1]) == 'x')
{
if (!(char.IsDigit(_text[_i]) ||
char.ToLower(_text[_i]) == 'a' ||
char.ToLower(_text[_i]) == 'b' ||
char.ToLower(_text[_i]) == 'c' ||
char.ToLower(_text[_i]) == 'd' ||
char.ToLower(_text[_i]) == 'e' ||
char.ToLower(_text[_i]) == 'f'))
break;
}
else
{
if (!char.IsDigit(_text[_i]))
break;
}
sb.Append(_text[_i]);
_i++;
}
return sb.ToString();
}
public string EatQuotedString()
{
StringBuilder sb = new StringBuilder();
bool inEscape = false;
if (_text[_i] == '"')
{
_i++;
}
else
return "";
while (_i < _text.Length)
{
if (_text[_i] == '\\')
{
inEscape = true;
_i++;
continue;
}
else if (inEscape)
{
if (_text[_i] == '\\')
sb.Append('\\');
else if (_text[_i] == '"')
sb.Append('"');
else if (_text[_i] == '\'')
sb.Append('\'');
else if (_text[_i] == 'r')
sb.Append('\r');
else if (_text[_i] == 'n')
sb.Append('\n');
else if (_text[_i] == 't')
sb.Append('\t');
else
throw new Exception("Unrecognized escape sequence '\\" + _text[_i] + "'");
_i++;
inEscape = false;
continue;
}
else if (_text[_i] == '"')
{
_i++;
break;
}
sb.Append(_text[_i]);
_i++;
}
return sb.ToString();
}
public string EatSymbol()
{
StringBuilder sb = new StringBuilder();
while (_i < _text.Length && sb.Length < 1) // we need a proper parser to solve this
{
char c = _text[_i];
if (c < ' ' || c > '~') // check if its an ASCII character
break;
if (char.IsLetterOrDigit(c) || c == '_') // check if its eligible to be an identifier
break;
sb.Append(c);
_i++;
}
return sb.ToString();
}
public string EatUntil(char c)
{
StringBuilder sb = new StringBuilder();
while (_i < _text.Length && _text[_i] != c)
{
sb.Append(_text[_i]);
_i++;
}
return sb.ToString();
}
public bool EatWhitespace()
{
return this.EatWhitespace(false);
}
public bool EatWhitespace(bool comments)
{
bool ranOut = true;
bool preComment = false; // '/'
bool inComment = false; // '*'
bool prePostComment = false; // '*'
while (_i < _text.Length)
{
if (comments && inComment && _text[_i] == '*')
{
prePostComment = true;
_i++;
continue;
}
else if (comments && prePostComment && _text[_i] == '/')
{
prePostComment = false;
inComment = false;
_i++;
continue;
}
else if (comments && !inComment && _text[_i] == '/')
{
preComment = true;
_i++;
continue;
}
else if (comments && preComment)
{
if (_text[_i] == '*')
{
preComment = false;
inComment = true;
_i++;
continue;
}
else
{
// it's a mistake, revert!
_i -= 1;
break;
}
}
else
{
preComment = false;
prePostComment = false;
}
if (!(_text[_i] == '\r' || _text[_i] == '\n' || _text[_i] == ' ' || _text[_i] == '\t') && !inComment)
{
ranOut = false;
break;
}
_i++;
}
return ranOut;
}
}
}