FusionCalculator/src/Lexer.fu

89 lines
2.7 KiB
Plaintext

class Lexer
{
string ExprStr;
List<Token()>() tokens;
int tokType = Token.Type_Number;
int tokBegin = 0;
int i = 0;
Token() TokBracketOpen;
Token() TokBracketClose;
Token() TokPow;
Token() TokMul;
Token() TokMod;
Token() TokDiv;
Token() TokAdd;
Token() TokSub;
public Lexer(){
TokBracketOpen = Token.Create("(", 0, 1, Token.Type_BracketOpen);
TokBracketClose = Token.Create(")", 0, 1, Token.Type_BracketClose);
TokPow = Token.Create("^", 0, 1, Token.Type_OperatorPow);
TokMul = Token.Create("*", 0, 1, Token.Type_OperatorMul);
TokMod = Token.Create("%", 0, 1, Token.Type_OperatorMod);
TokDiv = Token.Create("/", 0, 1, Token.Type_OperatorDiv);
TokAdd = Token.Create("+", 0, 1, Token.Type_OperatorAdd);
TokSub = Token.Create("-", 0, 1, Token.Type_OperatorSub);
}
internal List<Token()> Lex!()
{
while (i < ExprStr.Length)
{
switch (ExprStr[i])
{
// end token, add new predifined token and move next
case '(': AddStaticToken(TokBracketOpen); break;
case ')': AddStaticToken(TokBracketClose); break;
case '^': AddStaticToken(TokPow); break;
case '*': AddStaticToken(TokMul); break;
case '%': AddStaticToken(TokMod); break;
case '/': AddStaticToken(TokDiv); break;
case '+': AddStaticToken(TokAdd); break;
case '-': AddStaticToken(TokSub); break;
// try end token and skip current char
case ' ': case '\t': case '\n': case '\r':
TryEndToken();
i++;
break;
// move next
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
i++;
break;
// set type from Numeric to Literal
default:
tokType = Token.Type_Literal;
i++;
break;
}
}
// end last token
TryEndToken();
return tokens;
}
void TryEndToken!()
{
if (tokBegin != i)
{
Token() tok = Token.Create(ExprStr, tokBegin, i - tokBegin, tokType);
tokens.Add();
tokens[tokens.Count-1] = tok;
tokType = Token.Type_Number;
tokBegin = i;
}
}
void AddStaticToken!(Token() tok)
{
TryEndToken();
tokens.Add();
tokens[tokens.Count-1] = tok;
tokType = Token.Type_Number;
tokBegin = ++i;
}
}