Tokenicer: Better identifier tokening.

This commit is contained in:
2019-12-02 07:56:12 +01:00
parent 13daa68c26
commit 379583607b
3 changed files with 40 additions and 5 deletions

View File

@@ -171,6 +171,17 @@ namespace VAR.ExpressionEvaluator.Tests
Assert.AreEqual(50m, result); Assert.AreEqual(50m, result);
} }
[TestMethod()]
public void Variables__Var1DivideVar2()
{
EvaluationContext evaluationContex = new EvaluationContext();
evaluationContex.SetVariable("_v1", 100);
evaluationContex.SetVariable("$v2", 20);
string expression = "_v1 / $v2";
object result = Parser.EvaluateString(expression, evaluationContex);
Assert.AreEqual(5m, result);
}
#endregion Variables #endregion Variables
#region Funcitions #region Funcitions

View File

@@ -90,9 +90,9 @@ namespace VAR.ExpressionEvaluator.Tests
} }
[TestMethod()] [TestMethod()]
public void Tokenizer__Keywords() public void Tokenizer__Identifiers()
{ {
var testString = "null true false"; var testString = "null true false _$variable1 $variable2";
var t = new Tokenizer(new StringReader(testString)); var t = new Tokenizer(new StringReader(testString));
// "null" // "null"
@@ -110,6 +110,16 @@ namespace VAR.ExpressionEvaluator.Tests
Assert.AreEqual(t.Text, "false"); Assert.AreEqual(t.Text, "false");
t.NextToken(); t.NextToken();
// "_$variable1"
Assert.AreEqual(t.Token, Token.Identifier);
Assert.AreEqual(t.Text, "_$variable1");
t.NextToken();
// "$variable2"
Assert.AreEqual(t.Token, Token.Identifier);
Assert.AreEqual(t.Text, "$variable2");
t.NextToken();
Assert.AreEqual(t.Token, Token.EOF); Assert.AreEqual(t.Token, Token.EOF);
} }

View File

@@ -171,10 +171,10 @@ namespace VAR.ExpressionEvaluator
} }
// Identifier // Identifier
if (char.IsLetter(_currentChar)) if (IsIdentifierStartLetter(_currentChar))
{ {
var sb = new StringBuilder(); var sb = new StringBuilder();
while (char.IsLetterOrDigit(_currentChar) || _currentChar == '_') while (IsIdentifierLetter(_currentChar))
{ {
sb.Append(_currentChar); sb.Append(_currentChar);
NextChar(); NextChar();
@@ -216,7 +216,11 @@ namespace VAR.ExpressionEvaluator
else else
{ {
NextChar(); NextChar();
if (_currentChar == '\\') if (_currentChar == stringEndsWith)
{
sbString.Append(stringEndsWith);
}
else if (_currentChar == '\\')
{ {
sbString.Append('\\'); sbString.Append('\\');
} }
@@ -260,5 +264,15 @@ namespace VAR.ExpressionEvaluator
throw new InvalidDataException(string.Format("Unexpected character: {0} at {1}", _currentChar, _currentPosition)); throw new InvalidDataException(string.Format("Unexpected character: {0} at {1}", _currentChar, _currentPosition));
} }
private static bool IsIdentifierLetter(char c)
{
return char.IsLetterOrDigit(c) || c == '_' || c == '$' || c == '#' || c == '@';
}
private static bool IsIdentifierStartLetter(char c)
{
return char.IsLetter(c) || c == '_' || c == '$' || c == '#' || c == '@';
}
} }
} }