// Generated by TinyPG v1.3 available at www.codeproject.com
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
namespace calculator
{
#region Scanner
public partial class Scanner
{
public string Input;
public int StartPos = 0;
public int EndPos = 0;
public int CurrentLine;
public int CurrentColumn;
public int CurrentPosition;
public List<Token> Skipped; // tokens that were skipped
public Dictionary<TokenType, Regex> Patterns;
private Token LookAheadToken;
private List<TokenType> Tokens;
private List<TokenType> SkipList; // tokens to be skipped
public Scanner()
{
Regex regex;
Patterns = new Dictionary<TokenType, Regex>();
Tokens = new List<TokenType>();
LookAheadToken = null;
Skipped = new List<Token>();
SkipList = new List<TokenType>();
SkipList.Add(TokenType.WHITESPACE);
regex = new Regex(@"true|false", RegexOptions.Compiled);
Patterns.Add(TokenType.BOOLEANLITERAL, regex);
Tokens.Add(TokenType.BOOLEANLITERAL);
regex = new Regex(@"[0-9]+(UL|Ul|uL|ul|LU|Lu|lU|lu|U|u|L|l)?", RegexOptions.Compiled);
Patterns.Add(TokenType.DECIMALINTEGERLITERAL, regex);
Tokens.Add(TokenType.DECIMALINTEGERLITERAL);
regex = new Regex(@"([0-9]+\.[0-9]+([eE][+-]?[0-9]+)?([fFdDMm]?)?)|(\.[0-9]+([eE][+-]?[0-9]+)?([fFdDMm]?)?)|([0-9]+([eE][+-]?[0-9]+)([fFdDMm]?)?)|([0-9]+([fFdDMm]?))", RegexOptions.Compiled);
Patterns.Add(TokenType.REALLITERAL, regex);
Tokens.Add(TokenType.REALLITERAL);
regex = new Regex(@"0(x|X)[0-9a-fA-F]+", RegexOptions.Compiled);
Patterns.Add(TokenType.HEXINTEGERLITERAL, regex);
Tokens.Add(TokenType.HEXINTEGERLITERAL);
regex = new Regex(@"\""(\""\""|[^\""])*\""", RegexOptions.Compiled);
Patterns.Add(TokenType.STRINGLITERAL, regex);
Tokens.Add(TokenType.STRINGLITERAL);
regex = new Regex(@"[a-zA-Z_][a-zA-Z0-9_]*(?=\s*\()", RegexOptions.Compiled);
Patterns.Add(TokenType.FUNCTION, regex);
Tokens.Add(TokenType.FUNCTION);
regex = new Regex(@"(?i)pi|e", RegexOptions.Compiled);
Patterns.Add(TokenType.CONSTANT, regex);
Tokens.Add(TokenType.CONSTANT);
regex = new Regex(@"{\s*", RegexOptions.Compiled);
Patterns.Add(TokenType.BRACEOPEN, regex);
Tokens.Add(TokenType.BRACEOPEN);
regex = new Regex(@"\s*}", RegexOptions.Compiled);
Patterns.Add(TokenType.BRACECLOSE, regex);
Tokens.Add(TokenType.BRACECLOSE);
regex = new Regex(@"\(\s*", RegexOptions.Compiled);
Patterns.Add(TokenType.BRACKETOPEN, regex);
Tokens.Add(TokenType.BRACKETOPEN);
regex = new Regex(@"\s*\)", RegexOptions.Compiled);
Patterns.Add(TokenType.BRACKETCLOSE, regex);
Tokens.Add(TokenType.BRACKETCLOSE);
regex = new Regex(@";", RegexOptions.Compiled);
Patterns.Add(TokenType.SEMICOLON, regex);
Tokens.Add(TokenType.SEMICOLON);
regex = new Regex(@"\+\+", RegexOptions.Compiled);
Patterns.Add(TokenType.PLUSPLUS, regex);
Tokens.Add(TokenType.PLUSPLUS);
regex = new Regex(@"--", RegexOptions.Compiled);
Patterns.Add(TokenType.MINUSMINUS, regex);
Tokens.Add(TokenType.MINUSMINUS);
regex = new Regex(@"\|\|", RegexOptions.Compiled);
Patterns.Add(TokenType.PIPEPIPE, regex);
Tokens.Add(TokenType.PIPEPIPE);
regex = new Regex(@"&&", RegexOptions.Compiled);
Patterns.Add(TokenType.AMPAMP, regex);
Tokens.Add(TokenType.AMPAMP);
regex = new Regex(@"&(?!&)", RegexOptions.Compiled);
Patterns.Add(TokenType.AMP, regex);
Tokens.Add(TokenType.AMP);
regex = new Regex(@"\^", RegexOptions.Compiled);
Patterns.Add(TokenType.POWER, regex);
Tokens.Add(TokenType.POWER);
regex = new Regex(@"\+", RegexOptions.Compiled);
Patterns.Add(TokenType.PLUS, regex);
Tokens.Add(TokenType.PLUS);
regex = new Regex(@"-", RegexOptions.Compiled);
Patterns.Add(TokenType.MINUS, regex);
Tokens.Add(TokenType.MINUS);
regex = new Regex(@"=", RegexOptions.Compiled);
Patterns.Add(TokenType.EQUAL, regex);
Tokens.Add(TokenType.EQUAL);
regex = new Regex(@"!=", RegexOptions.Compiled);
Patterns.Add(TokenType.NOTEQUAL, regex);
Tokens.Add(TokenType.NOTEQUAL);
regex = new Regex(@"!", RegexOptions.Compiled);
Patterns.Add(TokenType.NOT, regex);
Tokens.Add(TokenType.NOT);
regex = new Regex(@"\*", RegexOptions.Compiled);
Patterns.Add(TokenType.ASTERIKS, regex);
Tokens.Add(TokenType.ASTERIKS);
regex = new Regex(@"/", RegexOptions.Compiled);
Patterns.Add(TokenType.SLASH, regex);
Tokens.Add(TokenType.SLASH);
regex = new Regex(@"%", RegexOptions.Compiled);
Patterns.Add(TokenType.PERCENT, regex);
Tokens.Add(TokenType.PERCENT);
regex = new Regex(@"\?", RegexOptions.Compiled);
Patterns.Add(TokenType.QUESTIONMARK, regex);
Tokens.Add(TokenType.QUESTIONMARK);
regex = new Regex(@",", RegexOptions.Compiled);
Patterns.Add(TokenType.COMMA, regex);
Tokens.Add(TokenType.COMMA);
regex = new Regex(@"<=", RegexOptions.Compiled);
Patterns.Add(TokenType.LESSEQUAL, regex);
Tokens.Add(TokenType.LESSEQUAL);
regex = new Regex(@">=", RegexOptions.Compiled);
Patterns.Add(TokenType.GREATEREQUAL, regex);
Tokens.Add(TokenType.GREATEREQUAL);
regex = new Regex(@"<", RegexOptions.Compiled);
Patterns.Add(TokenType.LESSTHAN, regex);
Tokens.Add(TokenType.LESSTHAN);
regex = new Regex(@">", RegexOptions.Compiled);
Patterns.Add(TokenType.GREATERTHAN, regex);
Tokens.Add(TokenType.GREATERTHAN);
regex = new Regex(@":", RegexOptions.Compiled);
Patterns.Add(TokenType.COLON, regex);
Tokens.Add(TokenType.COLON);
regex = new Regex(@"^$", RegexOptions.Compiled);
Patterns.Add(TokenType.EOF, regex);
Tokens.Add(TokenType.EOF);
regex = new Regex(@"\s+", RegexOptions.Compiled);
Patterns.Add(TokenType.WHITESPACE, regex);
Tokens.Add(TokenType.WHITESPACE);
}
public void Init(string input)
{
this.Input = input;
StartPos = 0;
EndPos = 0;
CurrentLine = 0;
CurrentColumn = 0;
CurrentPosition = 0;
LookAheadToken = null;
}
public Token GetToken(TokenType type)
{
Token t = new Token(this.StartPos, this.EndPos);
t.Type = type;
return t;
}
/// <summary>
/// executes a lookahead of the next token
/// and will advance the scan on the input string
/// </summary>
/// <returns></returns>
public Token Scan(params TokenType[] expectedtokens)
{
Token tok = LookAhead(expectedtokens); // temporarely retrieve the lookahead
LookAheadToken = null; // reset lookahead token, so scanning will continue
StartPos = tok.EndPos;
EndPos = tok.EndPos; // set the tokenizer to the new scan position
return tok;
}
/// <summary>
/// returns token with longest best match
/// </summary>
/// <returns></returns>
public Token LookAhead(params TokenType[] expectedtokens)
{
int i;
int startpos = StartPos;
Token tok = null;
List<TokenType> scantokens;
// this prevents double scanning and matching
// increased performance
if (LookAheadToken != null
&& LookAheadToken.Type != TokenType._UNDETERMINED_
&& LookAheadToken.Type != TokenType._NONE_) return LookAheadToken;
// if no scantokens specified, then scan for all of them (= backward compatible)
if (expectedtokens.Length == 0)
scantokens = Tokens;
else
{
scantokens = new List<TokenType>(expectedtokens);
scantokens.AddRange(SkipList);
}
do
{
int len = -1;
TokenType index = (TokenType)int.MaxValue;
string input = Input.Substring(startpos);
tok = new Token(startpos, EndPos);
for (i = 0; i < scantokens.Count; i++)
{
Regex r = Patterns[scantokens[i]];
Match m = r.Match(input);
if (m.Success && m.Index == 0 && ((m.Length > len) || (scantokens[i] < index && m.Length == len )))
{
len = m.Length;
index = scantokens[i];
}
}
if (index >= 0 && len >= 0)
{
tok.EndPos = startpos + len;
tok.Text = Input.Substring(tok.StartPos, len);
tok.Type = index;
}
else if (tok.StartPos < tok.EndPos - 1)
{
tok.Text = Input.Substring(tok.StartPos, 1);
}
if (SkipList.Contains(tok.Type))
{
startpos = tok.EndPos;
Skipped.Add(tok);
}
else
{
// only assign to non-skipped tokens
tok.Skipped = Skipped; // assign prior skips to this token
Skipped = new List<Token>(); //reset skips
}
}
while (SkipList.Contains(tok.Type));
LookAheadToken = tok;
return tok;
}
}
#endregion
#region Token
public enum TokenType
{
//Non terminal tokens:
_NONE_ = 0,
_UNDETERMINED_= 1,
//Non terminal tokens:
Start = 2,
UnaryExpression= 3,
Function= 4,
PrimaryExpression= 5,
ParenthesizedExpression= 6,
PowerExpression= 7,
MultiplicativeExpression= 8,
AdditiveExpression= 9,
ConcatEpression= 10,
RelationalExpression= 11,
EqualityExpression= 12,
ConditionalAndExpression= 13,
ConditionalOrExpression= 14,
Expression= 15,
Params = 16,
Literal = 17,
IntegerLiteral= 18,
RealLiteral= 19,
StringLiteral= 20,
//Terminal tokens:
BOOLEANLITERAL= 21,
DECIMALINTEGERLITERAL= 22,
REALLITERAL= 23,
HEXINTEGERLITERAL= 24,
STRINGLITERAL= 25,
FUNCTION= 26,
CONSTANT= 27,
BRACEOPEN= 28,
BRACECLOSE= 29,
BRACKETOPEN= 30,
BRACKETCLOSE= 31,
SEMICOLON= 32,
PLUSPLUS= 33,
MINUSMINUS= 34,
PIPEPIPE= 35,
AMPAMP = 36,
AMP = 37,
POWER = 38,
PLUS = 39,
MINUS = 40,
EQUAL = 41,
NOTEQUAL= 42,
NOT = 43,
ASTERIKS= 44,
SLASH = 45,
PERCENT = 46,
QUESTIONMARK= 47,
COMMA = 48,
LESSEQUAL= 49,
GREATEREQUAL= 50,
LESSTHAN= 51,
GREATERTHAN= 52,
COLON = 53,
EOF = 54,
WHITESPACE= 55
}
public class Token
{
private int startpos;
private int endpos;
private string text;
private object value;
// contains all prior skipped symbols
private List<Token> skipped;
public int StartPos {
get { return startpos;}
set { startpos = value; }
}
public int Length {
get { return endpos - startpos;}
}
public int EndPos {
get { return endpos;}
set { endpos = value; }
}
public string Text {
get { return text;}
set { text = value; }
}
public List<Token> Skipped {
get { return skipped;}
set { skipped = value; }
}
public object Value {
get { return value;}
set { this.value = value; }
}
[XmlAttribute]
public TokenType Type;
public Token()
: this(0, 0)
{
}
public Token(int start, int end)
{
Type = TokenType._UNDETERMINED_;
startpos = start;
endpos = end;
Text = ""; // must initialize with empty string, may cause null reference exceptions otherwise
Value = null;
}
public void UpdateRange(Token token)
{
if (token.StartPos < startpos) startpos = token.StartPos;
if (token.EndPos > endpos) endpos = token.EndPos;
}
public override string ToString()
{
if (Text != null)
return Type.ToString() + " '" + Text + "'";
else
return Type.ToString();
}
}
#endregion
}