From 492f9b8470cce5c1d8e677af35e14a961e44f7ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Vo=C5=99=C3=AD=C5=A1ek?= Date: Tue, 30 May 2023 01:00:26 +0200 Subject: [PATCH] Add general "+" sign support for integer/float numbers --- doc/grammars/type.abnf | 20 ++++++++++++-------- src/Lexer/Lexer.php | 4 ++-- tests/PHPStan/Parser/ConstExprParserTest.php | 10 ++++++++++ tests/PHPStan/Parser/TypeParserTest.php | 8 ++++++++ 4 files changed, 32 insertions(+), 10 deletions(-) diff --git a/doc/grammars/type.abnf b/doc/grammars/type.abnf index 1b3912f2..0b3247ba 100644 --- a/doc/grammars/type.abnf +++ b/doc/grammars/type.abnf @@ -85,18 +85,18 @@ ConstantExpr / ConstantFetch *ByteHorizontalWs ConstantFloat - = ["-"] 1*ByteDecDigit *("_" 1*ByteDecDigit) "." [1*ByteDecDigit *("_" 1*ByteDecDigit)] [ConstantFloatExp] - / ["-"] 1*ByteDecDigit *("_" 1*ByteDecDigit) ConstantFloatExp - / ["-"] "." 1*ByteDecDigit *("_" 1*ByteDecDigit) [ConstantFloatExp] + = [ByteNumberSign] 1*ByteDecDigit *("_" 1*ByteDecDigit) "." [1*ByteDecDigit *("_" 1*ByteDecDigit)] [ConstantFloatExp] + / [ByteNumberSign] 1*ByteDecDigit *("_" 1*ByteDecDigit) ConstantFloatExp + / [ByteNumberSign] "." 1*ByteDecDigit *("_" 1*ByteDecDigit) [ConstantFloatExp] ConstantFloatExp - = "e" ["+" / "-"] 1*ByteDecDigit *("_" 1*ByteDecDigit) + = "e" [ByteNumberSign] 1*ByteDecDigit *("_" 1*ByteDecDigit) ConstantInt - = ["-"] "0b" 1*ByteBinDigit *("_" 1*ByteBinDigit) - / ["-"] "0o" 1*ByteOctDigit *("_" 1*ByteOctDigit) - / ["-"] "0x" 1*ByteHexDigit *("_" 1*ByteHexDigit) - / ["-"] 1*ByteDecDigit *("_" 1*ByteDecDigit) + = [ByteNumberSign] "0b" 1*ByteBinDigit *("_" 1*ByteBinDigit) + / [ByteNumberSign] "0o" 1*ByteOctDigit *("_" 1*ByteOctDigit) + / [ByteNumberSign] "0x" 1*ByteHexDigit *("_" 1*ByteHexDigit) + / [ByteNumberSign] 1*ByteDecDigit *("_" 1*ByteDecDigit) ConstantTrue = "true" @@ -213,6 +213,10 @@ ByteHorizontalWs = %x09 ; horizontal tab / %x20 ; space +ByteNumberSign + = "+" + / "-" + ByteBinDigit = %x30-31 ; 0-1 diff --git a/src/Lexer/Lexer.php b/src/Lexer/Lexer.php index 1459b4bf..737c2f54 100644 --- a/src/Lexer/Lexer.php +++ b/src/Lexer/Lexer.php @@ -160,8 +160,8 @@ private function generateRegexp(): string self::TOKEN_PHPDOC_TAG => '@(?:[a-z][a-z0-9-\\\\]+:)?[a-z][a-z0-9-\\\\]*+', self::TOKEN_PHPDOC_EOL => '\\r?+\\n[\\x09\\x20]*+(?:\\*(?!/)\\x20?+)?', - self::TOKEN_FLOAT => '(?:-?[0-9]++(_[0-9]++)*\\.[0-9]*+(_[0-9]++)*(?:e[+-]?[0-9]++(_[0-9]++)*)?)|(?:-?[0-9]*+(_[0-9]++)*\\.[0-9]++(_[0-9]++)*(?:e[+-]?[0-9]++(_[0-9]++)*)?)|(?:-?[0-9]++(_[0-9]++)*e[+-]?[0-9]++(_[0-9]++)*)', - self::TOKEN_INTEGER => '-?(?:(?:0b[0-1]++(_[0-1]++)*)|(?:0o[0-7]++(_[0-7]++)*)|(?:0x[0-9a-f]++(_[0-9a-f]++)*)|(?:[0-9]++(_[0-9]++)*))', + self::TOKEN_FLOAT => '[+\-]?(?:(?:[0-9]++(_[0-9]++)*\\.[0-9]*+(_[0-9]++)*(?:e[+\-]?[0-9]++(_[0-9]++)*)?)|(?:[0-9]*+(_[0-9]++)*\\.[0-9]++(_[0-9]++)*(?:e[+\-]?[0-9]++(_[0-9]++)*)?)|(?:[0-9]++(_[0-9]++)*e[+\-]?[0-9]++(_[0-9]++)*))', + self::TOKEN_INTEGER => '[+\-]?(?:(?:0b[0-1]++(_[0-1]++)*)|(?:0o[0-7]++(_[0-7]++)*)|(?:0x[0-9a-f]++(_[0-9a-f]++)*)|(?:[0-9]++(_[0-9]++)*))', self::TOKEN_SINGLE_QUOTED_STRING => '\'(?:\\\\[^\\r\\n]|[^\'\\r\\n\\\\])*+\'', self::TOKEN_DOUBLE_QUOTED_STRING => '"(?:\\\\[^\\r\\n]|[^"\\r\\n\\\\])*+"', diff --git a/tests/PHPStan/Parser/ConstExprParserTest.php b/tests/PHPStan/Parser/ConstExprParserTest.php index 07d69774..f3427431 100644 --- a/tests/PHPStan/Parser/ConstExprParserTest.php +++ b/tests/PHPStan/Parser/ConstExprParserTest.php @@ -152,6 +152,11 @@ public function provideIntegerNodeParseData(): Iterator new ConstExprIntegerNode('123'), ]; + yield [ + '+123', + new ConstExprIntegerNode('+123'), + ]; + yield [ '-123', new ConstExprIntegerNode('-123'), @@ -236,6 +241,11 @@ public function provideFloatNodeParseData(): Iterator new ConstExprFloatNode('12.3e4'), ]; + yield [ + '+123.5', + new ConstExprFloatNode('+123.5'), + ]; + yield [ '-123.', new ConstExprFloatNode('-123.'), diff --git a/tests/PHPStan/Parser/TypeParserTest.php b/tests/PHPStan/Parser/TypeParserTest.php index 8031412e..85ae0db8 100644 --- a/tests/PHPStan/Parser/TypeParserTest.php +++ b/tests/PHPStan/Parser/TypeParserTest.php @@ -1095,6 +1095,14 @@ public function provideParseData(): array '123_456.789_012', new ConstTypeNode(new ConstExprFloatNode('123456.789012')), ], + [ + '+0x10_20|+8e+2 | -0b11', + new UnionTypeNode([ + new ConstTypeNode(new ConstExprIntegerNode('+0x1020')), + new ConstTypeNode(new ConstExprFloatNode('+8e+2')), + new ConstTypeNode(new ConstExprIntegerNode('-0b11')), + ]), + ], [ '18_446_744_073_709_551_616|8.2023437675747321e-18_446_744_073_709_551_617', new UnionTypeNode([