Преглед на файлове

Ensure trailing - on scientific notation is not parsed as part of number (#1067)

Fixes https://github.com/hyperledger/solang/issues/1065

Signed-off-by: Sean Young <sean@mess.org>
Sean Young преди 3 години
родител
ревизия
8437c62245
променени са 3 файла, в които са добавени 54 реда и са изтрити 16 реда
  1. 14 5
      solang-parser/src/lexer.rs
  2. 27 5
      tests/contract_testcases/solana/rational/rational.dot
  3. 13 6
      tests/contract_testcases/solana/rational/rational.sol

+ 14 - 5
solang-parser/src/lexer.rs

@@ -665,8 +665,12 @@ impl<'input> Lexer<'input> {
         if let Some((i, 'e' | 'E')) = self.chars.peek() {
             exp_start = *i + 1;
             self.chars.next();
+            // Negative exponent
+            while matches!(self.chars.peek(), Some((_, '-'))) {
+                self.chars.next();
+            }
             while let Some((i, ch)) = self.chars.peek() {
-                if !ch.is_ascii_digit() && *ch != '_' && *ch != '-' {
+                if !ch.is_ascii_digit() && *ch != '_' {
                     break;
                 }
                 end = *i;
@@ -1279,7 +1283,7 @@ fn lexertest() {
         )
     );
 
-    let tokens = Lexer::new("// foo bar\n0x00fead0_12 .0008 0.9e-2", 0, &mut comments)
+    let tokens = Lexer::new("// foo bar\n0x00fead0_12 .0008 0.9e-2-2", 0, &mut comments)
         .collect::<Vec<Result<(usize, Token, usize), LexicalError>>>();
 
     assert_eq!(
@@ -1287,16 +1291,21 @@ fn lexertest() {
         vec!(
             Ok((11, Token::HexNumber("0x00fead0_12"), 23)),
             Ok((24, Token::RationalNumber("", "0008", ""), 29)),
-            Ok((30, Token::RationalNumber("0", "9", "-2"), 36))
+            Ok((30, Token::RationalNumber("0", "9", "-2"), 36)),
+            Ok((36, Token::Subtract, 37)),
+            Ok((37, Token::Number("2", ""), 38))
         )
     );
 
-    let tokens = Lexer::new("1.2_3e2", 0, &mut comments)
+    let tokens = Lexer::new("1.2_3e2-", 0, &mut comments)
         .collect::<Vec<Result<(usize, Token, usize), LexicalError>>>();
 
     assert_eq!(
         tokens,
-        vec!(Ok((0, Token::RationalNumber("1", "2_3", "2"), 7)))
+        vec!(
+            Ok((0, Token::RationalNumber("1", "2_3", "2"), 7)),
+            Ok((7, Token::Subtract, 8))
+        )
     );
 
     let tokens = Lexer::new("\"foo\"", 0, &mut comments)

+ 27 - 5
tests/contract_testcases/solana/rational/rational.dot

@@ -1,12 +1,34 @@
 strict digraph "tests/contract_testcases/solana/rational/rational.sol" {
-	contract [label="contract foo\ntests/contract_testcases/solana/rational/rational.sol:2:9-7:10"]
-	test [label="function test\ncontract: foo\ntests/contract_testcases/solana/rational/rational.sol:3:13-50\nsignature test()\nvisibility public\nmutability nonpayable"]
+	contract [label="contract foo\ntests/contract_testcases/solana/rational/rational.sol:1:1-14:2"]
+	test [label="function test\ncontract: foo\ntests/contract_testcases/solana/rational/rational.sol:2:5-42\nsignature test()\nvisibility public\nmutability nonpayable"]
 	returns [label="returns\nuint256 "]
-	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/solana/rational/rational.sol:2:9-7:10"]
-	diagnostic_6 [label="conversion to uint256 from rational not allowed\nlevel Error\ntests/contract_testcases/solana/rational/rational.sol:4:26-29"]
+	test2 [label="function test2\ncontract: foo\ntests/contract_testcases/solana/rational/rational.sol:9:5-30\nsignature test2()\nvisibility external\nmutability nonpayable"]
+	var_decl [label="variable decl uint256 b\ntests/contract_testcases/solana/rational/rational.sol:10:9-24"]
+	number_literal [label="uint256 literal: 500\ntests/contract_testcases/solana/rational/rational.sol:10:21-24"]
+	var_decl_7 [label="variable decl uint256 a1\ntests/contract_testcases/solana/rational/rational.sol:11:9-28"]
+	subtract [label="subtract\nuint256\ntests/contract_testcases/solana/rational/rational.sol:11:22-28"]
+	number_literal_9 [label="uint256 literal: 1000000000000000000\ntests/contract_testcases/solana/rational/rational.sol:11:22-26"]
+	variable [label="variable: b\nuint256\ntests/contract_testcases/solana/rational/rational.sol:11:27-28"]
+	var_decl_11 [label="variable decl uint256 a2\ntests/contract_testcases/solana/rational/rational.sol:12:9-29"]
+	subtract_12 [label="subtract\nuint256\ntests/contract_testcases/solana/rational/rational.sol:12:22-29"]
+	number_literal_13 [label="uint256 literal: 1000000000000000000\ntests/contract_testcases/solana/rational/rational.sol:12:22-26"]
+	variable_14 [label="variable: b\nuint256\ntests/contract_testcases/solana/rational/rational.sol:12:28-29"]
+	diagnostic [label="found contract 'foo'\nlevel Debug\ntests/contract_testcases/solana/rational/rational.sol:1:1-14:2"]
+	diagnostic_17 [label="conversion to uint256 from rational not allowed\nlevel Error\ntests/contract_testcases/solana/rational/rational.sol:3:18-21"]
 	contracts -> contract
 	contract -> test [label="function"]
 	test -> returns [label="returns"]
+	contract -> test2 [label="function"]
+	test2 -> var_decl [label="body"]
+	var_decl -> number_literal [label="init"]
+	var_decl -> var_decl_7 [label="next"]
+	var_decl_7 -> subtract [label="init"]
+	subtract -> number_literal_9 [label="left"]
+	subtract -> variable [label="right"]
+	var_decl_7 -> var_decl_11 [label="next"]
+	var_decl_11 -> subtract_12 [label="init"]
+	subtract_12 -> number_literal_13 [label="left"]
+	subtract_12 -> variable_14 [label="right"]
 	diagnostics -> diagnostic [label="Debug"]
-	diagnostics -> diagnostic_6 [label="Error"]
+	diagnostics -> diagnostic_17 [label="Error"]
 }

+ 13 - 6
tests/contract_testcases/solana/rational/rational.sol

@@ -1,7 +1,14 @@
+contract foo {
+    function test() public returns (uint) {
+        uint y = 0.1;
+        return y;
+    }
 
-        contract foo {
-            function test() public returns (uint) {
-                uint y = 0.1;
-                return y;
-            }
-        }
+    // Ensure - after scientific notation is not lexed
+    // https://github.com/hyperledger/solang/issues/1065
+    function test2() external {
+        uint256 b = 500;
+        uint256 a1 = 1e18-b;
+        uint256 a2 = 1e18- b;
+    }
+}