using System;
using System.Collections;
+using System.Collections.Generic;
using System.Collections.Specialized;
using System.Text;
namespace Microsoft.Build.BuildEngine {
internal sealed class ConditionTokenizer {
+
string inputString = null;
int position = 0;
int tokenPosition = 0;
Token token;
- bool ignoreWhiteSpace = true;
+// bool ignoreWhiteSpace = true;
static TokenType[] charIndexToTokenType = new TokenType[128];
- static Hashtable keywordToTokenType = CollectionsUtil.CreateCaseInsensitiveHashtable ();
+ static Dictionary <string, TokenType> keywords = new Dictionary <string, TokenType> (StringComparer.InvariantCultureIgnoreCase);
static ConditionTokenizer ()
{
foreach (CharToTokenType cht in charToTokenType)
charIndexToTokenType [(int) cht.ch] = cht.tokenType;
+ keywords.Add ("and", TokenType.And);
+ keywords.Add ("or", TokenType.Or);
}
public ConditionTokenizer ()
{
- this.ignoreWhiteSpace = true;
+// this.ignoreWhiteSpace = true;
}
public void Tokenize (string s)
GetNextToken ();
}
- private void SkipWhiteSpace ()
+ void SkipWhiteSpace ()
{
int ch;
}
}
- private int PeekChar ()
+ int PeekChar ()
{
if (position < inputString.Length)
return (int) inputString [position];
return -1;
}
- private int ReadChar ()
+ int ReadChar ()
{
if (position < inputString.Length)
return (int) inputString [position++];
if (token.Type == TokenType.EOF)
throw new ExpressionParseException ("Cannot read past the end of stream.");
- if (IgnoreWhiteSpace)
- SkipWhiteSpace ();
+ SkipWhiteSpace ();
tokenPosition = position;
- int i = PeekChar ();
+// int i = PeekChar ();
+ int i = ReadChar ();
if (i == -1) {
token = new Token (null, TokenType.EOF);
}
char ch = (char) i;
-
- if (IgnoreWhiteSpace == false && Char.IsWhiteSpace (ch)) {
- StringBuilder sb = new StringBuilder ();
- int ch2;
- while ((ch2 = PeekChar ()) != -1) {
- if (!Char.IsWhiteSpace ((char) ch2))
- break;
-
- sb.Append ((char)ch2);
- ReadChar();
- }
-
- token = new Token (sb.ToString (), TokenType.WhiteSpace);
- return;
- }
- if (Char.IsDigit (ch)) {
+ // FIXME: looks like a hack: if '-' is here '->' won't be tokenized
+ // maybe we should treat item reference as a token
+ if (Char.IsDigit (ch) || ch == '-') {
StringBuilder sb = new StringBuilder ();
sb.Append (ch);
- ReadChar ();
while ((i = PeekChar ()) != -1) {
ch = (char) i;
}
token = new Token (sb.ToString (), TokenType.Number);
- return;
- }
-
- if (ch == '\'') {
+ } else if (ch == '\'') {
StringBuilder sb = new StringBuilder ();
string temp;
sb.Append (ch);
- ReadChar ();
while ((i = PeekChar ()) != -1) {
ch = (char) i;
temp = sb.ToString ();
- // FIXME: test extreme cases
token = new Token (temp.Substring (1, temp.Length - 2), TokenType.String);
- return;
- }
-
- if (ch == '_' || Char.IsLetter (ch)) {
+ } else if (ch == '_' || Char.IsLetter (ch)) {
StringBuilder sb = new StringBuilder ();
sb.Append ((char) ch);
- ReadChar ();
while ((i = PeekChar ()) != -1) {
if ((char) i == '_' || Char.IsLetterOrDigit ((char) i))
string temp = sb.ToString ();
- if (temp.ToLower () == "and")
- token = new Token (temp, TokenType.And);
- else if (temp.ToLower () == "or")
- token = new Token (temp, TokenType.Or);
+ if (keywords.ContainsKey (temp))
+ token = new Token (temp, keywords [temp]);
else
- token = new Token (sb.ToString (), TokenType.String);
- return;
- }
-
- ReadChar ();
-
- if (ch == '!' && PeekChar () == (int) '=') {
+ token = new Token (temp, TokenType.String);
+
+ } else if (ch == '!' && PeekChar () == (int) '=') {
token = new Token ("!=", TokenType.NotEqual);
ReadChar ();
- return;
- }
-
- if (ch == '<' && PeekChar () == (int) '=') {
+ } else if (ch == '<' && PeekChar () == (int) '=') {
token = new Token ("<=", TokenType.LessOrEqual);
ReadChar ();
- return;
- }
-
- if (ch == '>' && PeekChar () == (int) '=') {
+ } else if (ch == '>' && PeekChar () == (int) '=') {
token = new Token (">=", TokenType.GreaterOrEqual);
ReadChar ();
- return;
- }
-
- if (ch == '=' && PeekChar () == (int) '=') {
+ } else if (ch == '=' && PeekChar () == (int) '=') {
token = new Token ("==", TokenType.Equal);
ReadChar ();
- return;
- }
-
- if (ch == '-' && PeekChar () == (int) '>') {
- token = new Token ("->", TokenType.Transform);
- ReadChar ();
- return;
- }
-
- if (ch >= 32 && ch < 128) {
+ } else if (ch >= 32 && ch < 128) {
if (charIndexToTokenType [ch] != TokenType.Invalid) {
token = new Token (new String (ch, 1), charIndexToTokenType [ch]);
return;
} else
throw new ExpressionParseException (String.Format ("Invalid punctuation: {0}", ch));
- }
-
- throw new ExpressionParseException (String.Format ("Invalid token: {0}", ch));
+ } else
+ throw new ExpressionParseException (String.Format ("Invalid token: {0}", ch));
}
public int TokenPosition {
get { return token; }
}
+/*
public bool IgnoreWhiteSpace {
get { return ignoreWhiteSpace; }
set { ignoreWhiteSpace = value; }
}
+*/
struct CharToTokenType {
public char ch;