Skip to content

Commit 6da2088

Browse files
committed
(FabianNitsche) Tests and fix for issue pieterderycke#66 pieterderycke#67 pieterderycke#68 - Problems with ambiguity of e - Invalid scientific notation leads to IndexOutOfBoundsException instead of ParseException
1 parent 72e3d9e commit 6da2088

2 files changed

Lines changed: 94 additions & 5 deletions

File tree

Jace.Tests/TokenReaderTests.cs

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,5 +652,94 @@ public void TestTokenReader31()
652652
List<Token> tokens = reader.Read("0..1");
653653
});
654654
}
655+
656+
[TestMethod]
657+
public void TestTokenReader32()
658+
{
659+
var reader = new TokenReader<double>(CultureInfo.InvariantCulture, DoubleNumericalOperations.Instance);
660+
List<Token> tokens = reader.Read("-e");
661+
662+
Assert.AreEqual(2, tokens.Count);
663+
664+
Assert.AreEqual('_', tokens[0].Value);
665+
Assert.AreEqual(0, tokens[0].StartPosition);
666+
Assert.AreEqual(1, tokens[0].Length);
667+
668+
Assert.AreEqual("e", tokens[1].Value);
669+
Assert.AreEqual(1, tokens[1].StartPosition);
670+
Assert.AreEqual(1, tokens[1].Length);
671+
}
672+
673+
[TestMethod]
674+
public void TestTokenReader33()
675+
{
676+
var reader = new TokenReader<double>(CultureInfo.InvariantCulture, DoubleNumericalOperations.Instance);
677+
List<Token> tokens = reader.Read("1-e");
678+
679+
Assert.AreEqual(3, tokens.Count);
680+
681+
Assert.AreEqual(1, tokens[0].Value);
682+
Assert.AreEqual(0, tokens[0].StartPosition);
683+
Assert.AreEqual(1, tokens[0].Length);
684+
685+
Assert.AreEqual('-', tokens[1].Value);
686+
Assert.AreEqual(1, tokens[1].StartPosition);
687+
Assert.AreEqual(1, tokens[1].Length);
688+
689+
Assert.AreEqual("e", tokens[2].Value);
690+
Assert.AreEqual(2, tokens[2].StartPosition);
691+
Assert.AreEqual(1, tokens[2].Length);
692+
}
693+
694+
[TestMethod]
695+
public void TestTokenReader34()
696+
{
697+
var reader = new TokenReader<double>(CultureInfo.InvariantCulture, DoubleNumericalOperations.Instance);
698+
List<Token> tokens = reader.Read("1+e");
699+
700+
Assert.AreEqual(3, tokens.Count);
701+
702+
Assert.AreEqual(1, tokens[0].Value);
703+
Assert.AreEqual(0, tokens[0].StartPosition);
704+
Assert.AreEqual(1, tokens[0].Length);
705+
706+
Assert.AreEqual('+', tokens[1].Value);
707+
Assert.AreEqual(1, tokens[1].StartPosition);
708+
Assert.AreEqual(1, tokens[1].Length);
709+
710+
Assert.AreEqual("e", tokens[2].Value);
711+
Assert.AreEqual(2, tokens[2].StartPosition);
712+
Assert.AreEqual(1, tokens[2].Length);
713+
}
714+
715+
[TestMethod]
716+
public void TestTokenReader35()
717+
{
718+
AssertExtensions.ThrowsException<ParseException>(() =>
719+
{
720+
var reader = new TokenReader<double>(CultureInfo.InvariantCulture, DoubleNumericalOperations.Instance);
721+
List<Token> tokens = reader.Read("2.11E-e3");
722+
});
723+
}
724+
725+
[TestMethod]
726+
public void TestTokenReader36()
727+
{
728+
AssertExtensions.ThrowsException<ParseException>(() =>
729+
{
730+
var reader = new TokenReader<double>(CultureInfo.InvariantCulture, DoubleNumericalOperations.Instance);
731+
List<Token> tokens = reader.Read("2.11E-e");
732+
});
733+
}
734+
735+
[TestMethod]
736+
public void TestTokenReader37()
737+
{
738+
AssertExtensions.ThrowsException<ParseException>(() =>
739+
{
740+
var reader = new TokenReader<double>(CultureInfo.InvariantCulture, DoubleNumericalOperations.Instance);
741+
List<Token> tokens = reader.Read("3e");
742+
});
743+
}
655744
}
656745
}

Jace/Tokenizer/TokenReader.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -56,15 +56,15 @@ public List<Token> Read(string formula)
5656

5757
for(int i = 0; i < characters.Length; i++)
5858
{
59-
if (IsPartOfNumeric(characters[i], true, isFormulaSubPart))
59+
if (IsPartOfNumeric(characters[i], true, false, isFormulaSubPart))
6060
{
6161
StringBuilder buffer = new StringBuilder();
6262
buffer.Append(characters[i]);
6363
//string buffer = "" + characters[i];
6464
int startPosition = i;
6565

6666

67-
while (++i < characters.Length && IsPartOfNumeric(characters[i], false, isFormulaSubPart))
67+
while (++i < characters.Length && IsPartOfNumeric(characters[i], false, characters[i - 1] == '-', isFormulaSubPart))
6868
{
6969
if (isScientific && IsScientificNotation(characters[i]))
7070
throw new ParseException(string.Format("Invalid token \"{0}\" detected at position {1}.", characters[i], i));
@@ -73,7 +73,7 @@ public List<Token> Read(string formula)
7373
{
7474
isScientific = IsScientificNotation(characters[i]);
7575

76-
if (characters[i + 1] == '-')
76+
if (characters.Length > i + 1 && characters[i + 1] == '-')
7777
{
7878
buffer.Append(characters[i++]);
7979
}
@@ -235,9 +235,9 @@ public List<Token> Read(string formula)
235235
return tokens;
236236
}
237237

238-
private bool IsPartOfNumeric(char character, bool isFirstCharacter, bool isFormulaSubPart)
238+
private bool IsPartOfNumeric(char character, bool isFirstCharacter, bool afterMinus, bool isFormulaSubPart)
239239
{
240-
return character == decimalSeparator || (character >= '0' && character <= '9') || (isFormulaSubPart && isFirstCharacter && character == '-') || (!isFirstCharacter && character == 'e') || (!isFirstCharacter && character == 'E');
240+
return character == decimalSeparator || (character >= '0' && character <= '9') || (isFormulaSubPart && isFirstCharacter && character == '-') || (!isFirstCharacter && !afterMinus && character == 'e') || (!isFirstCharacter && character == 'E');
241241
}
242242

243243
private bool IsPartOfVariable(char character, bool isFirstCharacter)

0 commit comments

Comments
 (0)