From afe7a7dcb044427f114c0ad2aed8d725f5a76411 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Thu, 28 Apr 2022 18:55:44 +0200 Subject: [PATCH 1/5] phpstan.neon skips TagParser.php WIP --- phpstan.neon | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/phpstan.neon b/phpstan.neon index 7013f6993..5db9012da 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,4 +1,8 @@ parameters: + excludePaths: + analyse: + - src/Latte/Compiler/TagParser.php + level: 5 paths: From 8214088e9cc8d7634c09a14cd971a553ed3ab160 Mon Sep 17 00:00:00 2001 From: David Grudl Date: Sat, 8 Oct 2022 15:37:30 +0200 Subject: [PATCH 2/5] added operator 'not' --- src/Latte/Compiler/TagLexer.php | 1 + src/Latte/Compiler/TagParserData.php | 509 ++++++++++++++------------- src/Latte/Compiler/Token.php | 122 +++---- tests/phpLexer/names.phpt | 2 +- tests/phpLexer/operators.phpt | 14 +- tests/phpParser/in.phpt | 26 +- tests/phpParser/logic.phpt | 32 +- tests/phpPrint/operators.phpt | 9 +- 8 files changed, 389 insertions(+), 326 deletions(-) diff --git a/src/Latte/Compiler/TagLexer.php b/src/Latte/Compiler/TagLexer.php index 5f8794180..120d94ee8 100644 --- a/src/Latte/Compiler/TagLexer.php +++ b/src/Latte/Compiler/TagLexer.php @@ -35,6 +35,7 @@ final class TagLexer 'null' => Token::Php_Null, 'true' => Token::Php_True, 'false' => Token::Php_False, + 'not' => Token::Php_Not, ]; private const KeywordsFollowed = [ // must follows ( & = diff --git a/src/Latte/Compiler/TagParserData.php b/src/Latte/Compiler/TagParserData.php index 352380711..1850a4f24 100644 --- a/src/Latte/Compiler/TagParserData.php +++ b/src/Latte/Compiler/TagParserData.php @@ -26,187 +26,187 @@ abstract class TagParserData /** Rule number signifying that an unexpected token was encountered */ protected const UnexpectedTokenRule = 8191; - protected const Yy2Tblstate = 257; + protected const Yy2Tblstate = 259; /** Number of non-leaf states */ - protected const NumNonLeafStates = 350; + protected const NumNonLeafStates = 352; /** Map of lexer tokens to internal symbols */ protected const TokenToSymbol = [ - 0, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 48, 107, 112, 108, 47, 112, 112, - 101, 102, 45, 42, 2, 43, 44, 46, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 22, 105, - 35, 7, 37, 21, 59, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 61, 112, 106, 27, 112, 112, 100, 112, 112, - 112, 98, 112, 112, 112, 112, 112, 112, 112, 99, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 103, 26, 104, 50, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, - 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 112, 1, 3, 4, 5, + 0, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 49, 108, 113, 109, 48, 113, 113, + 102, 103, 46, 43, 2, 44, 45, 47, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 22, 106, + 36, 7, 38, 21, 60, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 62, 113, 107, 27, 113, 113, 101, 113, 113, + 113, 99, 113, 113, 113, 113, 113, 113, 113, 100, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 104, 26, 105, 51, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, + 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, 1, 3, 4, 5, 6, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 23, 24, 25, 28, 29, 30, - 31, 32, 33, 34, 36, 38, 39, 40, 41, 49, 51, 52, 53, 54, 55, 56, 57, 58, 60, 62, + 31, 32, 33, 34, 35, 37, 39, 40, 41, 42, 50, 52, 53, 54, 55, 56, 57, 58, 59, 61, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 109, 91, 92, 93, 94, 110, 111, 95, 96, 97, + 83, 84, 85, 86, 87, 88, 89, 90, 91, 110, 92, 93, 94, 95, 111, 112, 96, 97, 98, ]; /** Map of states to a displacement into the self::Action table. The corresponding action for this * state/symbol pair is self::Action[self::ActionBase[$state] + $symbol]. If self::ActionBase[$state] is 0, the * action is defaulted, i.e. self::ActionDefault[$state] should be used instead. */ protected const ActionBase = [ - 97, 305, 305, 305, 305, 100, 141, 305, 264, 182, 223, 305, 385, 385, 385, 385, 385, 155, 155, 155, - 232, 232, 214, 225, 353, 354, 355, 375, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, 38, 224, 378, 381, 380, 382, 422, 429, 430, 433, 441, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 140, 64, 557, 107, 107, 107, - 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 107, 274, 274, 274, 371, 504, - 492, 391, -67, 412, 412, 127, 127, 127, 127, 127, 426, 426, 426, 426, 79, 79, 79, 79, 250, 250, - 250, 250, 250, 250, 250, 250, 87, 87, 103, 208, -39, -39, -39, 451, 451, 451, 41, 41, 41, 41, - 41, 111, 152, 193, 449, 203, 446, 446, 446, 446, 446, 446, 230, 444, -21, -11, -11, 388, 303, 303, - 303, -11, 397, 94, 321, -36, 461, 474, 318, 419, 263, 222, 377, 216, 217, 236, 26, 26, 26, 26, - 155, 445, 445, 155, 155, 155, 132, 132, 132, -83, 221, 52, 23, 389, 221, 221, 221, 47, 37, 60, - 285, 220, 271, 276, 33, 104, 61, 292, 311, 285, 285, 145, 61, 61, 234, 240, 244, 169, 99, 244, - 235, 235, 165, 29, 322, 317, 324, 269, 261, 387, 181, 192, 233, 231, 260, 245, 215, 322, 317, 324, - 218, 181, 228, 228, 228, 258, 228, 228, 228, 228, 228, 228, 228, 432, 30, 239, 326, 327, 342, 344, - 211, 226, 394, 228, 227, 255, 252, 434, 181, 259, 435, 384, 320, 254, 213, 336, 212, 439, 348, 407, - 200, 331, 202, 414, 219, 390, 229, 352, 418, 420, 0, -42, -42, -42, -42, -42, -42, -42, -42, -42, - -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, -42, 0, 0, + 133, 336, 336, 336, 336, 114, 134, 336, 316, 215, 235, 336, 417, 417, 417, 417, 417, 171, 171, 171, + 286, 286, 268, 244, 375, 376, 380, 384, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, 118, 176, 397, 405, 398, 407, 448, 451, 452, 456, + 455, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 153, 127, 422, 7, 7, + 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 469, 469, 469, 528, + 445, 148, 423, -55, 325, 325, 325, 225, 225, 225, 225, 225, 449, 449, 449, 449, 44, 44, 44, 44, + 59, 59, 59, 59, 59, 59, 59, 59, 93, 17, 17, 38, 175, -41, -41, 261, 261, 261, 239, 239, + 239, 239, 239, 185, 140, 420, 453, 255, -51, -51, -51, -51, -51, -51, 280, 458, 189, 457, 457, 476, + 115, 115, 115, 457, 233, -71, 79, -21, 103, 289, 358, 122, 281, 73, 385, 214, 223, 283, 275, 275, + 275, 275, 171, 454, 454, 171, 171, 171, 219, 219, 219, -60, 191, 34, 102, 414, 191, 191, 191, 48, + 46, 10, 307, 274, 304, 305, 50, 90, 58, 321, 322, 307, 307, 94, 58, 58, 288, 270, 252, 145, + 75, 252, 262, 262, 138, 8, 349, 345, 353, 302, 300, 430, 197, 209, 284, 278, 299, 291, 213, 349, + 345, 353, 240, 197, 200, 200, 200, 285, 200, 200, 200, 200, 200, 200, 200, 282, 43, 287, 354, 356, + 360, 361, 277, 264, 355, 200, 248, 279, 272, 436, 197, 296, 443, 416, 315, 298, 273, 359, 271, 447, + 368, 440, 160, 357, 164, 441, 173, 438, 220, 374, 415, 442, 0, -30, -30, -30, -30, -30, -30, -30, + -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, -30, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, - 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 0, 426, 53, 53, 53, 53, 53, 53, 53, - 0, 0, 0, 0, 303, 303, 303, 303, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, - 303, 303, 303, 41, 41, 41, 0, 0, 0, 0, 0, 0, 0, 0, 0, 397, 235, 235, 235, 235, - 235, 235, 397, 397, 0, 0, 0, 0, 0, 0, 0, 0, 0, 397, 235, 0, 0, 0, 0, 0, - 0, 0, 155, 155, 155, 397, 0, 0, 0, 0, 0, 235, 235, 0, 0, 0, 0, 0, 0, 0, - 228, 0, 0, 30, 228, 228, 228, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 0, 449, 66, 66, 66, 66, + 66, 66, 66, 66, 0, 0, 0, 0, -41, -41, -41, -41, 239, 239, 239, 239, 239, 239, 239, 239, + -41, 239, 239, 239, 239, 0, 0, 239, 239, 239, 0, 0, 0, 0, 0, 0, 0, 0, 0, 233, + 262, 262, 262, 262, 262, 262, 233, 233, 0, 0, 0, 0, -41, -41, -41, 0, 0, 233, 262, 0, + 0, 0, 0, 0, 0, 0, 171, 171, 171, 233, 0, 0, 0, 0, 0, 262, 262, 0, 0, 0, + 0, 0, 0, 0, 200, 0, 0, 43, 200, 200, 200, ]; /** Table of actions. Indexed according to self::ActionBase comment. */ protected const Action = [ - 34, 35, 376, 75, 76, 77, 36, -176, 37, 178, 179, 38, 39, 40, 41, 42, 43, 44, -176, 1, - 193, 45, 544, 545, 202, -213, 527, 376, 12, 0, 542, 284, 7, 243, 244, 11, 98, 285, 286, 16, - -211, 289, 287, 288, 205, -213, -213, -213, 13, 173, -208, 529, 528, 550, 548, 549, 54, 55, 56, 29, - -211, -211, -211, 15, 172, 222, 289, -8190, -8190, -211, -208, -208, -208, 197, 23, 198, 57, 58, 59, -208, - 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, - 80, 21, 195, 357, 358, 356, 101, 525, 196, 527, -8190, -8190, -8190, 81, -8191, -8191, -8191, -8191, 72, 73, - 74, 75, 76, 77, 196, 493, 405, 14, 355, 354, -8190, -8190, -8190, -21, 529, 528, 407, 32, 406, 434, - 204, 367, -175, -8190, 357, 358, 356, 188, -8190, 361, -8190, -8190, -8190, -175, -8190, -8190, -8190, -8191, -8191, -8191, - -8191, -8191, 194, 46, 510, -8190, 201, 232, 296, 355, 354, 378, -214, 297, 363, 233, 234, 362, 368, 298, - 299, 553, 367, 355, 354, 357, 358, 356, 95, -45, 361, 24, -214, -214, -214, 33, 261, 3, 374, 96, - 375, -175, 416, 194, 46, -28, 105, 201, 106, 296, 355, 354, -175, -214, 297, 363, 233, 234, 362, 368, - 298, 299, -260, 367, -260, 107, 357, 358, 356, 196, 18, 361, 25, -214, -214, -214, 108, -22, -16, -15, - 19, 200, -175, 416, 194, 46, 170, 97, 201, 104, 296, 355, 354, -175, -210, 297, 363, 233, 234, 362, - 368, 298, 299, -257, 367, -257, 189, 357, 358, 356, 195, 171, 361, 26, -210, -210, -210, -8190, -8190, -8190, - 199, 320, 630, -210, 416, 194, 46, 102, 81, 201, 554, 296, 355, 354, -217, -8190, 297, 363, 233, 234, - 362, 368, 298, 299, 376, 367, 277, -8190, 357, 358, 356, 1, 341, 361, 27, 625, 251, 555, -254, 376, - -254, -184, 542, 162, -260, 416, 194, 46, -260, 241, 201, 386, 296, 355, 354, 288, 0, 297, 363, 233, - 234, 362, 368, 298, 299, -8190, 367, -8190, 78, 79, 80, 49, 195, -243, 361, 100, -241, 222, 289, -217, - -216, -215, 2, 81, 336, -257, 416, 194, 46, -257, 4, 201, 5, 296, -8190, -8190, -8190, 6, 297, 363, - 233, 234, 362, 368, 298, 299, 8, 628, 357, 358, 356, 629, -8190, 9, -8190, -8190, 47, 48, 17, 82, - 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 10, 355, 354, -8190, -8190, -8190, 28, -71, - -254, -71, 274, 51, -254, 52, 367, 186, 187, 357, 358, 356, 240, -8190, 361, -8190, -8190, -8190, 276, -8190, - -8190, -8190, 456, 458, 498, -71, 540, 194, 46, 31, 417, 201, -208, 296, 513, 519, 521, 523, 297, 363, - 233, 234, 362, 368, 298, 299, 376, 367, 617, 209, 210, 211, -208, -208, -208, 361, 100, 572, 242, -28, - 329, -208, 331, 532, 499, 22, 181, 20, 360, 359, 53, 597, 371, 259, 372, -8190, -8190, -8190, 627, 364, - 363, 366, 365, 362, 368, 369, 370, -8190, -8190, -8190, -209, 387, 374, -8190, 375, -8190, -8190, -8190, 626, -8190, - 376, -71, 30, 349, 509, -8190, 624, -8190, -8190, -8190, -209, -209, -209, 581, 592, 224, -8190, 595, 539, -209, - 569, 585, 206, 207, 208, 620, -8190, 343, -8190, 99, -216, 543, 50, 289, 289, 246, 247, 248, 0, 289, - -8190, -8190, -8190, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 103, + 34, -8190, 76, 77, 78, 79, 80, 81, 0, 197, -8190, -8190, -8190, 35, 36, 378, 376, 556, 377, 37, + 82, 38, 180, 181, 39, 40, 41, 42, 43, 44, 45, -177, 1, 195, 46, 547, 548, 204, 198, 530, + 378, -214, -177, 545, 286, 7, 245, 246, 16, 99, 287, 288, 11, 100, 291, 289, 290, 207, 291, 198, + 15, -214, -214, -214, 532, 531, 553, 551, 552, 55, 56, 57, 29, -261, 199, -261, 200, 21, 224, 291, + -8191, -8191, -8191, -8191, 73, 74, 75, 23, 32, 58, 59, 60, 102, 61, 62, 63, 191, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 513, 197, 359, 360, 358, + -45, 1, -71, 338, -71, -176, 253, 82, 175, 378, -8190, -8190, 545, -8191, 74, 75, -176, 359, 360, 358, + 234, -28, 357, 356, 174, 290, 631, 380, -71, 436, 632, -8190, -8190, -8190, 369, -8190, -8190, -8190, -8190, -8190, + -8190, 50, 357, 356, 363, 30, 106, 224, 291, -8190, 107, -8190, -8190, -8190, 369, -8190, -261, 196, 47, 108, + -261, 203, 18, 298, 363, 208, 209, 210, 299, 365, 235, 236, 364, 370, 300, 301, 198, 196, 47, 357, + 356, 203, -215, 298, 96, 496, 24, -21, 299, 365, 235, 236, 364, 370, 300, 301, 97, 418, 359, 360, + 358, 206, -215, -215, -215, -71, 25, 109, -8190, -8190, -8190, -176, 33, 263, 3, -22, -16, 418, 359, 360, + 358, 197, -176, 357, 356, -15, -8190, -215, -8190, -8190, -8190, -212, -8190, -8190, -8190, 369, -8191, -8191, -8191, -8191, + -8191, 82, 19, 357, 356, 363, 98, -215, -215, -215, 105, -212, -212, -212, 192, 369, -176, 12, 196, 47, + -212, -258, 203, -258, 298, 363, 376, -176, 377, 299, 365, 235, 236, 364, 370, 300, 301, 13, 196, 47, + 172, 202, 203, 378, 298, 620, 528, 26, 530, 299, 365, 235, 236, 364, 370, 300, 301, 173, 418, 359, + 360, 358, 22, 183, 201, 407, 103, 27, -8190, -8190, -8190, 378, 378, 532, 531, 409, 322, 408, 418, 359, + 360, 358, 633, 557, 357, 356, -8190, -8190, -8190, -8190, -8190, 226, -8190, -8190, -8190, -8190, 369, -8190, -255, -8190, + -255, 279, 388, 51, 357, 356, 363, 343, 558, -185, 291, 248, 249, 250, -244, 163, 369, 14, 243, 196, + 47, -242, 628, 203, -258, 298, 363, -218, -258, 542, 299, 365, 235, 236, 364, 370, 300, 301, -217, 196, + 47, -216, 2, 203, 4, 298, 5, 6, 101, 8, 299, 365, 235, 236, 364, 370, 300, 301, 276, 418, + 359, 360, 358, 9, 10, -8190, -8190, -8190, 48, 49, 17, 83, 84, 85, 86, 87, 88, 89, 90, 91, + 92, 93, 94, 95, 104, 357, 356, 28, -8190, -8190, -8190, 52, 359, 360, 358, 53, 189, 369, 190, 242, + 630, -255, 278, 501, 543, -255, -8190, 363, -8190, -8190, -8190, 419, -8190, -8190, -8190, 458, 460, 516, 522, 524, + 196, 47, -211, 526, 203, -209, 298, 575, -28, 369, -8190, 299, 365, 235, 236, 364, 370, 300, 301, 363, + 331, 333, -211, -211, -211, -209, -209, -209, 535, 101, 502, -211, 362, 361, -209, -210, 373, 600, 374, -209, + 20, 351, -218, 366, 365, 368, 367, 364, 370, 371, 372, -8190, -8190, -8190, 54, -210, -210, -210, 31, -209, + -209, -209, 261, 572, -210, 389, 629, 512, -209, -8190, 588, -8190, -8190, 627, 623, -217, 584, 595, 211, 212, + 213, 598, 345, 291, 0, 0, 546, 244, ]; /** Table indexed analogously to self::Action. If self::ActionCheck[self::ActionBase[$state] + $symbol] != $symbol * then the action is defaulted, i.e. self::ActionDefault[$state] should be used instead. */ protected const ActionCheck = [ - 42, 43, 69, 42, 43, 44, 48, 90, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 101, 61, - 62, 63, 64, 65, 66, 61, 68, 69, 2, 0, 72, 73, 2, 75, 76, 2, 103, 79, 80, 2, - 61, 108, 84, 85, 86, 81, 82, 83, 22, 26, 61, 93, 94, 95, 96, 97, 3, 4, 5, 101, - 81, 82, 83, 2, 26, 107, 108, 3, 4, 90, 81, 82, 83, 26, 21, 28, 23, 24, 25, 90, - 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, - 47, 2, 49, 3, 4, 5, 2, 66, 21, 68, 3, 4, 5, 60, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 21, 102, 85, 101, 28, 29, 3, 4, 5, 22, 93, 94, 95, 77, 97, 102, - 102, 41, 90, 3, 3, 4, 5, 2, 21, 49, 23, 24, 25, 101, 27, 28, 29, 30, 31, 32, - 33, 34, 62, 63, 104, 71, 66, 2, 68, 28, 29, 2, 61, 73, 74, 75, 76, 77, 78, 79, - 80, 87, 41, 28, 29, 3, 4, 5, 7, 102, 49, 91, 81, 82, 83, 98, 99, 100, 66, 7, - 68, 90, 102, 62, 63, 102, 6, 66, 6, 68, 28, 29, 101, 61, 73, 74, 75, 76, 77, 78, - 79, 80, 0, 41, 2, 6, 3, 4, 5, 21, 6, 49, 91, 81, 82, 83, 7, 22, 22, 22, - 22, 28, 90, 102, 62, 63, 26, 22, 66, 22, 68, 28, 29, 101, 61, 73, 74, 75, 76, 77, - 78, 79, 80, 0, 41, 2, 22, 3, 4, 5, 49, 26, 49, 91, 81, 82, 83, 3, 4, 5, - 26, 67, 70, 90, 102, 62, 63, 61, 60, 66, 87, 68, 28, 29, 101, 21, 73, 74, 75, 76, - 77, 78, 79, 80, 69, 41, 74, 71, 3, 4, 5, 61, 78, 49, 91, 104, 66, 87, 0, 69, - 2, 90, 72, 90, 102, 102, 62, 63, 106, 90, 66, 91, 68, 28, 29, 85, -1, 73, 74, 75, - 76, 77, 78, 79, 80, 95, 41, 97, 45, 46, 47, 101, 49, 101, 49, 91, 101, 107, 108, 101, - 101, 101, 101, 60, 43, 102, 102, 62, 63, 106, 101, 66, 101, 68, 3, 4, 5, 101, 73, 74, - 75, 76, 77, 78, 79, 80, 101, 66, 3, 4, 5, 70, 21, 101, 23, 24, 91, 92, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 101, 28, 29, 3, 4, 5, 101, 0, - 102, 2, 102, 101, 106, 101, 41, 101, 101, 3, 4, 5, 101, 21, 49, 23, 24, 25, 102, 27, - 28, 29, 51, 52, 102, 26, 102, 62, 63, 61, 102, 66, 61, 68, 102, 102, 102, 102, 73, 74, - 75, 76, 77, 78, 79, 80, 69, 41, 71, 81, 82, 83, 81, 82, 83, 49, 91, 102, 90, 102, - 102, 90, 102, 102, 102, 88, 89, 103, 62, 63, 103, 102, 66, 103, 68, 3, 4, 5, 104, 73, - 74, 75, 76, 77, 78, 79, 80, 3, 4, 5, 61, 104, 66, 21, 68, 23, 24, 25, 104, 27, - 69, 102, 61, 105, 104, 21, 104, 23, 24, 25, 81, 82, 83, 104, 104, 61, 85, 104, 106, 90, - 106, 106, 81, 82, 83, 106, 95, 106, 97, 103, 101, 107, 101, 108, 108, 81, 82, 83, -1, 108, - 3, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 22, + 30, 72, 43, 44, 45, 46, 47, 48, 0, 50, 3, 4, 5, 43, 44, 70, 67, 88, 69, 49, + 61, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 91, 62, 63, 64, 65, 66, 67, 21, 69, + 70, 62, 102, 73, 74, 2, 76, 77, 2, 104, 80, 81, 2, 104, 109, 85, 86, 87, 109, 21, + 2, 82, 83, 84, 94, 95, 96, 97, 98, 3, 4, 5, 102, 0, 26, 2, 28, 2, 108, 109, + 36, 37, 38, 39, 40, 41, 42, 21, 78, 23, 24, 25, 2, 27, 28, 29, 2, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 105, 50, 3, 4, 5, + 103, 62, 0, 44, 2, 91, 67, 61, 26, 70, 3, 4, 73, 40, 41, 42, 102, 3, 4, 5, + 2, 103, 28, 29, 26, 86, 67, 2, 26, 103, 71, 3, 4, 5, 40, 96, 3, 98, 43, 44, + 45, 102, 28, 29, 50, 62, 6, 108, 109, 21, 6, 23, 24, 25, 40, 27, 103, 63, 64, 6, + 107, 67, 6, 69, 50, 82, 83, 84, 74, 75, 76, 77, 78, 79, 80, 81, 21, 63, 64, 28, + 29, 67, 62, 69, 7, 103, 92, 22, 74, 75, 76, 77, 78, 79, 80, 81, 7, 103, 3, 4, + 5, 103, 82, 83, 84, 103, 92, 7, 3, 4, 5, 91, 99, 100, 101, 22, 22, 103, 3, 4, + 5, 50, 102, 28, 29, 22, 21, 62, 23, 24, 25, 62, 27, 28, 29, 40, 31, 32, 33, 34, + 35, 61, 22, 28, 29, 50, 22, 82, 83, 84, 22, 82, 83, 84, 22, 40, 91, 2, 63, 64, + 91, 0, 67, 2, 69, 50, 67, 102, 69, 74, 75, 76, 77, 78, 79, 80, 81, 22, 63, 64, + 26, 28, 67, 70, 69, 72, 67, 92, 69, 74, 75, 76, 77, 78, 79, 80, 81, 26, 103, 3, + 4, 5, 89, 90, 26, 86, 62, 92, 3, 4, 5, 70, 70, 94, 95, 96, 68, 98, 103, 3, + 4, 5, 71, 88, 28, 29, 21, 86, 23, 24, 25, 62, 27, 28, 29, 72, 40, 96, 0, 98, + 2, 75, 92, 102, 28, 29, 50, 79, 88, 91, 109, 82, 83, 84, 102, 91, 40, 102, 91, 63, + 64, 102, 105, 67, 103, 69, 50, 102, 107, 107, 74, 75, 76, 77, 78, 79, 80, 81, 102, 63, + 64, 102, 102, 67, 102, 69, 102, 102, 92, 102, 74, 75, 76, 77, 78, 79, 80, 81, 103, 103, + 3, 4, 5, 102, 102, 3, 4, 5, 92, 93, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 22, 28, 29, 102, 3, 4, 5, 102, 3, 4, 5, 102, 102, 40, 102, 102, + 105, 103, 103, 103, 103, 107, 21, 50, 23, 24, 25, 103, 3, 4, 5, 52, 53, 103, 103, 103, + 63, 64, 62, 103, 67, 62, 69, 103, 103, 40, 21, 74, 75, 76, 77, 78, 79, 80, 81, 50, + 103, 103, 82, 83, 84, 82, 83, 84, 103, 92, 103, 91, 63, 64, 91, 62, 67, 103, 69, 62, + 104, 106, 102, 74, 75, 76, 77, 78, 79, 80, 81, 3, 4, 5, 104, 82, 83, 84, 62, 82, + 83, 84, 104, 107, 91, 105, 105, 105, 91, 21, 107, 23, 24, 105, 107, 102, 105, 105, 82, 83, + 84, 105, 107, 109, -1, -1, 108, 91, ]; /** Map of states to their default action */ protected const ActionDefault = [ - 8191, 252, 252, 30, 252, 8191, 8191, 252, 8191, 8191, 8191, 28, 8191, 8191, 8191, 28, 8191, 8191, 8191, 8191, - 38, 28, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 206, 206, 206, 8191, 8191, 8191, 8191, 8191, 8191, 8191, - 8191, 8191, 8191, 8191, 8191, 8191, 9, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, + 8191, 253, 253, 30, 253, 8191, 8191, 253, 8191, 8191, 8191, 28, 8191, 8191, 8191, 28, 8191, 8191, 8191, 8191, + 38, 28, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 207, 207, 207, 8191, 8191, 8191, 8191, 8191, 8191, 8191, + 8191, 8191, 8191, 8191, 8191, 8191, 8191, 9, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, - 8191, 28, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 253, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, - 1, 261, 262, 76, 70, 207, 256, 259, 72, 75, 73, 42, 43, 49, 112, 114, 146, 113, 88, 93, - 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 86, 87, 158, 147, 145, 144, 110, 111, - 117, 85, 8191, 115, 116, 134, 135, 132, 133, 136, 8191, 8191, 8191, 8191, 137, 138, 139, 140, 8191, 8191, - 8191, 8191, 8191, 8191, 8191, 8191, 62, 62, 62, 8191, 124, 125, 127, 8191, 10, 8191, 8191, 8191, 8191, 8191, - 8191, 197, 197, 196, 142, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 202, 107, 109, 181, 119, 120, - 118, 89, 8191, 8191, 8191, 201, 8191, 269, 208, 208, 208, 208, 33, 33, 33, 8191, 81, 81, 81, 81, - 33, 8191, 8191, 33, 33, 33, 8191, 8191, 8191, 187, 130, 214, 8191, 8191, 121, 122, 123, 50, 8191, 8191, - 185, 8191, 174, 8191, 27, 27, 27, 8191, 227, 228, 229, 27, 27, 27, 162, 35, 64, 27, 27, 64, - 8191, 8191, 27, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 191, 8191, 212, 225, 2, 177, 14, 19, 20, - 8191, 255, 128, 129, 131, 210, 150, 151, 152, 153, 154, 155, 156, 8191, 248, 180, 8191, 8191, 8191, 8191, - 268, 8191, 208, 126, 8191, 188, 232, 8191, 258, 209, 8191, 8191, 8191, 52, 53, 8191, 8191, 8191, 8191, 8191, - 8191, 8191, 8191, 8191, 8191, 8191, 48, 8191, 8191, 8191, + 8191, 8191, 28, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 254, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, + 8191, 1, 262, 263, 76, 70, 208, 257, 260, 72, 75, 73, 42, 43, 49, 112, 114, 147, 113, 88, + 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 86, 87, 159, 148, 146, 145, 110, + 111, 117, 85, 8191, 131, 115, 116, 135, 136, 133, 134, 137, 8191, 8191, 8191, 8191, 138, 139, 140, 141, + 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 127, 62, 62, 62, 8191, 124, 125, 8191, 10, 8191, 8191, 8191, + 8191, 8191, 8191, 198, 198, 197, 143, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 203, 107, 109, 182, + 119, 120, 118, 89, 8191, 8191, 8191, 202, 8191, 270, 209, 209, 209, 209, 33, 33, 33, 8191, 81, 81, + 81, 81, 33, 8191, 8191, 33, 33, 33, 8191, 8191, 8191, 188, 130, 215, 8191, 8191, 121, 122, 123, 50, + 8191, 8191, 186, 8191, 175, 8191, 27, 27, 27, 8191, 228, 229, 230, 27, 27, 27, 163, 35, 64, 27, + 27, 64, 8191, 8191, 27, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 192, 8191, 213, 226, 2, 178, 14, + 19, 20, 8191, 256, 128, 129, 132, 211, 151, 152, 153, 154, 155, 156, 157, 8191, 249, 181, 8191, 8191, + 8191, 8191, 269, 8191, 209, 126, 8191, 189, 233, 8191, 259, 210, 8191, 8191, 8191, 52, 53, 8191, 8191, 8191, + 8191, 8191, 8191, 8191, 8191, 8191, 8191, 8191, 48, 8191, 8191, 8191, ]; /** Map of non-terminals to a displacement into the self::Goto table. The corresponding goto state for this * non-terminal/state pair is self::Goto[self::GotoBase[$nonTerminal] + $state] (unless defaulted) */ protected const GotoBase = [ - 0, 0, -1, 0, 0, 107, 0, 161, -2, -39, -96, 0, 260, -55, 0, 0, 0, 0, 114, 110, - -16, 0, -8, 0, 64, 52, 0, 0, -66, -9, -255, 103, -11, 19, 0, 0, -44, 236, 27, 0, - 73, 0, 0, 233, 0, 0, 0, 29, 0, 0, 0, 0, 67, -47, 0, 0, 35, 43, 7, 51, - -35, -86, 0, 0, -50, 48, 0, 25, 109, 4, -68, 0, 0, + 0, 0, -1, 0, 0, 108, 0, 184, 23, -18, -64, 0, 181, -103, 0, 0, 0, 0, 169, 170, + 9, 0, 11, 0, 13, -78, 0, 0, -61, -63, -257, 104, -11, -32, 0, 0, 21, 252, 41, 0, + 15, 0, 0, 125, 0, 0, 0, 16, 0, 0, 0, 0, 71, -25, 0, 0, 49, 57, 7, 65, + -10, 50, 0, 0, -50, -31, 0, -75, 110, 4, -24, 0, 0, ]; /** Table of states to goto after reduction. Indexed according to self::GotoBase comment. */ protected const Goto = [ - 110, 110, 110, 110, 419, 419, 110, 518, 520, 319, 110, 599, 522, 571, 573, 574, 138, 126, 127, 123, - 123, 115, 136, 128, 128, 128, 128, 123, 109, 125, 125, 125, 120, 302, 303, 250, 304, 306, 307, 308, - 309, 310, 311, 312, 442, 442, 121, 122, 111, 112, 113, 114, 116, 134, 135, 137, 155, 158, 159, 160, - 163, 164, 165, 166, 167, 168, 169, 174, 175, 176, 177, 190, 191, 192, 218, 219, 220, 254, 255, 256, - 323, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 156, 117, 118, 128, - 129, 119, 157, 130, 131, 154, 132, 133, 180, 180, 180, 180, 326, 253, 180, 272, 273, 258, 180, 223, - 404, 404, 404, 404, 183, 184, 185, 524, 524, 524, 404, 404, 404, 404, 404, 391, 235, 615, 318, 526, - 526, 526, 526, 584, 584, 584, 526, 526, 526, 526, 526, 526, 526, 526, 615, 616, 596, 596, 596, 596, - 596, 596, 300, 300, 300, 300, 227, 616, 300, 424, 338, 335, 300, 227, 227, 394, 433, 432, 316, 317, - 397, 344, 389, 227, 227, 631, 514, 213, 316, 317, 275, 582, 582, 430, 427, 428, 227, 215, 216, 228, - 322, 229, 221, 230, 231, 541, 541, 541, 541, 541, 541, 541, 541, 563, 563, 563, 563, 563, 563, 563, - 563, 561, 561, 561, 561, 561, 561, 561, 561, 305, 305, 305, 305, 305, 305, 305, 305, 301, 301, 301, - 301, 346, 517, 301, 621, 622, 623, 301, 401, 408, 410, 409, 411, 415, 328, 269, 270, 586, 587, 588, - 315, 315, 315, 381, 330, 348, 589, 590, 491, 515, 345, 382, 0, 0, 0, 0, 0, 0, 0, 0, + 111, 111, 111, 111, 421, 421, 111, 521, 523, 321, 111, 602, 525, 574, 576, 577, 139, 127, 128, 124, + 124, 116, 137, 129, 129, 129, 129, 124, 110, 126, 126, 126, 121, 164, 304, 305, 252, 306, 308, 309, + 310, 311, 312, 313, 314, 444, 444, 122, 123, 112, 113, 114, 115, 117, 135, 136, 138, 156, 159, 160, + 161, 165, 166, 167, 168, 169, 170, 171, 176, 177, 178, 179, 188, 193, 194, 220, 221, 222, 256, 257, + 258, 325, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 157, 118, 119, + 129, 130, 120, 158, 131, 132, 155, 133, 134, 182, 182, 182, 182, 328, 255, 182, 274, 275, 260, 182, + 403, 410, 412, 411, 413, 185, 186, 187, 406, 406, 406, 406, 318, 319, 527, 527, 527, 406, 406, 406, + 406, 406, 318, 319, 277, 587, 587, 587, 217, 218, 230, 324, 231, 223, 232, 233, 332, 350, 599, 599, + 599, 599, 599, 599, 529, 529, 529, 529, 592, 593, 529, 529, 529, 529, 529, 529, 529, 529, 271, 272, + 589, 590, 591, 618, 383, 302, 302, 302, 302, 229, 393, 302, 384, 585, 585, 302, 229, 229, 320, 337, + 618, 619, 399, 426, 340, 417, 229, 229, 634, 396, 435, 434, 494, 619, 215, 346, 391, 0, 347, 229, + 517, 544, 544, 544, 544, 544, 544, 544, 544, 566, 566, 566, 566, 566, 566, 566, 566, 564, 564, 564, + 564, 564, 564, 564, 564, 307, 307, 307, 307, 307, 307, 307, 307, 303, 303, 303, 303, 225, 518, 303, + 432, 429, 430, 303, 348, 520, 317, 317, 317, 0, 330, 624, 625, 626, 237, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 325, 0, 0, 0, 0, 0, 0, 0, 236, 237, 238, 239, 0, 0, 0, 0, 384, - 384, 384, 0, 0, 0, 0, 0, 384, 0, 0, 384, 384, 384, + 0, 0, 386, 386, 386, 0, 0, 327, 0, 0, 386, 0, 0, 386, 386, 386, 238, 239, 240, 241, ]; /** Table indexed analogously to self::Goto. If self::GotoCheck[self::GotoBase[$nonTerminal] + $state] != $nonTerminal @@ -217,27 +217,27 @@ abstract class TagParserData 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 64, 68, 5, 31, 31, 31, 5, 61, - 28, 28, 28, 28, 5, 5, 5, 28, 28, 28, 28, 28, 28, 28, 28, 18, 61, 70, 19, 53, - 53, 53, 53, 64, 64, 64, 53, 53, 53, 53, 53, 53, 53, 53, 70, 70, 64, 64, 64, 64, - 64, 64, 7, 7, 7, 7, 9, 70, 7, 10, 10, 20, 7, 9, 9, 10, 10, 10, 13, 13, - 22, 10, 10, 9, 9, 9, 10, 60, 13, 13, 13, 64, 64, 36, 36, 36, 9, 33, 33, 33, - 33, 33, 33, 33, 33, 38, 38, 38, 38, 38, 38, 38, 38, 56, 56, 56, 56, 56, 56, 56, - 56, 57, 57, 57, 57, 57, 57, 57, 57, 59, 59, 59, 59, 59, 59, 59, 59, 37, 37, 37, - 37, 9, 9, 37, 8, 8, 8, 37, 25, 25, 25, 25, 25, 24, 37, 65, 65, 65, 65, 65, - 52, 52, 52, 12, 43, 43, 67, 67, 40, 47, 29, 12, -1, -1, -1, -1, -1, -1, -1, -1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 5, 5, 5, 64, 68, 5, 31, 31, 31, 5, + 25, 25, 25, 25, 25, 5, 5, 5, 28, 28, 28, 28, 13, 13, 28, 28, 28, 28, 28, 28, + 28, 28, 13, 13, 13, 64, 64, 64, 33, 33, 33, 33, 33, 33, 33, 33, 43, 43, 64, 64, + 64, 64, 64, 64, 53, 53, 53, 53, 67, 67, 53, 53, 53, 53, 53, 53, 53, 53, 65, 65, + 65, 65, 65, 70, 12, 7, 7, 7, 7, 9, 18, 7, 12, 64, 64, 7, 9, 9, 19, 20, + 70, 70, 22, 10, 10, 24, 9, 9, 9, 10, 10, 10, 40, 70, 60, 10, 10, -1, 29, 9, + 10, 38, 38, 38, 38, 38, 38, 38, 38, 56, 56, 56, 56, 56, 56, 56, 56, 57, 57, 57, + 57, 57, 57, 57, 57, 59, 59, 59, 59, 59, 59, 59, 59, 37, 37, 37, 37, 61, 47, 37, + 36, 36, 36, 37, 9, 9, 52, 52, 52, -1, 37, 8, 8, 8, 61, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 7, -1, -1, -1, -1, -1, -1, -1, 7, 7, 7, 7, -1, -1, -1, -1, 5, - 5, 5, -1, -1, -1, -1, -1, 5, -1, -1, 5, 5, 5, + -1, -1, 5, 5, 5, -1, -1, 7, -1, -1, 5, -1, -1, 5, 5, 5, 7, 7, 7, 7, ]; /** Map of non-terminals to the default state to goto after their reduction */ protected const GotoDefault = [ - -8192, 283, 124, 295, 353, 182, 373, 324, 594, 580, 379, 264, 601, 281, 280, 441, 339, 278, 390, 340, - 332, 271, 396, 245, 413, 257, 333, 334, 262, 342, 536, 266, 418, 161, 265, 252, 429, 290, 291, 440, - 260, 507, 279, 327, 511, 347, 282, 516, 570, 263, 292, 267, 533, 249, 217, 293, 225, 214, 313, 203, - 212, 614, 226, 294, 568, 268, 576, 583, 314, 600, 613, 321, 337, + -8192, 285, 125, 297, 355, 184, 375, 326, 597, 583, 381, 266, 604, 283, 282, 443, 341, 280, 392, 342, + 334, 273, 398, 247, 415, 259, 335, 336, 264, 344, 539, 268, 420, 162, 267, 254, 431, 292, 293, 442, + 262, 510, 281, 329, 514, 349, 284, 519, 573, 265, 294, 269, 536, 251, 219, 295, 227, 216, 315, 205, + 214, 617, 228, 296, 571, 270, 579, 586, 316, 603, 616, 323, 339, ]; /** Map of rules to the non-terminal on their left-hand side, i.e. the non-terminal to use for @@ -251,13 +251,13 @@ abstract class TagParserData 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 39, 42, 42, 45, 46, 46, 47, 48, 48, 48, 48, 48, 48, 52, 28, 28, 53, 53, 53, - 40, 40, 40, 50, 50, 44, 44, 56, 57, 38, 59, 59, 59, 59, 41, 41, 41, 41, 41, 41, - 41, 41, 41, 41, 41, 41, 43, 43, 55, 55, 55, 55, 62, 62, 62, 49, 49, 49, 63, 63, - 63, 63, 63, 63, 63, 33, 33, 33, 33, 33, 64, 64, 67, 66, 54, 54, 54, 54, 54, 54, - 54, 51, 51, 51, 65, 65, 65, 37, 58, 68, 68, 69, 69, 12, 12, 12, 12, 12, 12, 12, - 12, 12, 12, 60, 60, 60, 60, 61, 71, 70, 70, 70, 70, 70, 70, 70, 70, 70, 72, 72, - 72, 72, + 2, 2, 39, 42, 42, 45, 46, 46, 47, 48, 48, 48, 48, 48, 48, 52, 28, 28, 53, 53, + 53, 40, 40, 40, 50, 50, 44, 44, 56, 57, 38, 59, 59, 59, 59, 41, 41, 41, 41, 41, + 41, 41, 41, 41, 41, 41, 41, 43, 43, 55, 55, 55, 55, 62, 62, 62, 49, 49, 49, 63, + 63, 63, 63, 63, 63, 63, 33, 33, 33, 33, 33, 64, 64, 67, 66, 54, 54, 54, 54, 54, + 54, 54, 51, 51, 51, 65, 65, 65, 37, 58, 68, 68, 69, 69, 12, 12, 12, 12, 12, 12, + 12, 12, 12, 12, 60, 60, 60, 60, 61, 71, 70, 70, 70, 70, 70, 70, 70, 70, 70, 72, + 72, 72, 72, ]; /** Map of rules to the length of their right-hand side, which is the number of elements that have to @@ -269,15 +269,15 @@ abstract class TagParserData 3, 3, 0, 1, 0, 2, 2, 4, 1, 3, 1, 2, 2, 3, 2, 3, 1, 4, 4, 3, 4, 0, 3, 3, 3, 1, 3, 3, 3, 4, 1, 1, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 5, 4, 3, 3, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 8, 12, - 9, 3, 0, 4, 2, 1, 3, 2, 2, 4, 2, 4, 4, 6, 1, 1, 1, 1, 1, 1, - 1, 1, 3, 1, 1, 0, 1, 1, 3, 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 4, - 1, 4, 6, 4, 4, 1, 1, 3, 3, 3, 1, 4, 1, 3, 1, 4, 3, 3, 3, 3, - 3, 1, 3, 1, 1, 3, 1, 4, 1, 3, 1, 1, 0, 1, 2, 1, 3, 4, 3, 3, - 4, 2, 2, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 3, 3, 6, 3, 1, 1, - 2, 1, + 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 5, 4, 3, 3, 4, 4, 2, 2, 2, 2, 2, 2, 2, 1, 8, + 12, 9, 3, 0, 4, 2, 1, 3, 2, 2, 4, 2, 4, 4, 6, 1, 1, 1, 1, 1, + 1, 1, 1, 3, 1, 1, 0, 1, 1, 3, 3, 4, 1, 1, 3, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 3, 2, 3, 0, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, + 4, 1, 4, 6, 4, 4, 1, 1, 3, 3, 3, 1, 4, 1, 3, 1, 4, 3, 3, 3, + 3, 3, 1, 3, 1, 1, 3, 1, 4, 1, 3, 1, 1, 0, 1, 2, 1, 3, 4, 3, + 3, 4, 2, 2, 2, 2, 1, 2, 1, 1, 1, 4, 3, 3, 3, 3, 3, 6, 3, 1, + 1, 2, 1, ]; /** Map of symbols to their names */ @@ -312,6 +312,7 @@ abstract class TagParserData "'^'", "'&'", "'&'", + "'not'", "'=='", "'!='", "'==='", @@ -321,9 +322,9 @@ abstract class TagParserData "'<='", "'>'", "'>='", + "'in'", "'<<'", "'>>'", - "'in'", "'+'", "'-'", "'.'", @@ -409,15 +410,15 @@ abstract class TagParserData protected function reduce(int $rule, int $pos): void { (match ($rule) { - 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 27, 28, 50, 63, 65, 85, 90, 91, 157, 174, 176, 180, 181, 183, 184, 186, 191, 196, 201, 202, 207, 208, 210, 211, 212, 213, 215, 217, 218, 220, 225, 226, 230, 234, 241, 243, 244, 246, 251, 269, 281 => fn() => $this->semValue = $this->semStack[$pos], + 0, 1, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 27, 28, 50, 63, 65, 85, 90, 91, 158, 175, 177, 181, 182, 184, 185, 187, 192, 197, 202, 203, 208, 209, 211, 212, 213, 214, 216, 218, 219, 221, 226, 227, 231, 235, 242, 244, 245, 247, 252, 270, 282 => fn() => $this->semValue = $this->semStack[$pos], 2 => fn() => $this->semValue = new Node\ModifierNode($this->semStack[$pos]), 3 => fn() => $this->semValue = new Expression\ArrayNode($this->semStack[$pos]), 21, 22, 23, 24, 25, 55, 56, 57 => fn() => $this->semValue = new Node\IdentifierNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), 26 => fn() => $this->semValue = new Expression\VariableNode(substr($this->semStack[$pos], 1), $this->startTokenStack[$pos]->position), - 29, 39, 44, 74, 82, 83, 84, 142, 143, 163, 164, 182, 209, 216, 242, 245, 277 => fn() => $this->semValue = $this->semStack[$pos - 1], - 30, 38, 45, 66, 81, 162, 185 => fn() => $this->semValue = [], - 31, 40, 46, 68, 76, 165, 250, 265 => fn() => $this->semValue = [$this->semStack[$pos]], - 32, 41, 47, 59, 61, 69, 75, 166, 249 => function () use ($pos) { + 29, 39, 44, 74, 82, 83, 84, 143, 144, 164, 165, 183, 210, 217, 243, 246, 278 => fn() => $this->semValue = $this->semStack[$pos - 1], + 30, 38, 45, 66, 81, 163, 186 => fn() => $this->semValue = [], + 31, 40, 46, 68, 76, 166, 251, 266 => fn() => $this->semValue = [$this->semStack[$pos]], + 32, 41, 47, 59, 61, 69, 75, 167, 250 => function () use ($pos) { $this->semStack[$pos - 2][] = $this->semStack[$pos]; $this->semValue = $this->semStack[$pos - 2]; }, @@ -433,7 +434,7 @@ protected function reduce(int $rule, int $pos): void 53 => fn() => $this->semValue = new Node\IntersectionTypeNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), 54 => fn() => $this->semValue = TagParser::handleBuiltinTypes($this->semStack[$pos]), 58, 60 => fn() => $this->semValue = [$this->semStack[$pos - 2], $this->semStack[$pos]], - 62, 64, 206, 252 => fn() => $this->semValue = null, + 62, 64, 207, 253 => fn() => $this->semValue = null, 67 => fn() => $this->semValue = $this->semStack[$pos - 2], 70 => fn() => $this->semValue = new Node\ArgumentNode($this->semStack[$pos], false, false, null, $this->startTokenStack[$pos]->position), 71 => fn() => $this->semValue = new Node\ArgumentNode($this->semStack[$pos], true, false, null, $this->startTokenStack[$pos - 1]->position), @@ -484,97 +485,97 @@ protected function reduce(int $rule, int $pos): void 127 => fn() => $this->semValue = new Expression\InRangeNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), 128 => fn() => $this->semValue = new Expression\UnaryOpNode($this->semStack[$pos], '+', $this->startTokenStack[$pos - 1]->position), 129 => fn() => $this->semValue = new Expression\UnaryOpNode($this->semStack[$pos], '-', $this->startTokenStack[$pos - 1]->position), - 130 => fn() => $this->semValue = new Expression\NotNode($this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 131 => fn() => $this->semValue = new Expression\UnaryOpNode($this->semStack[$pos], '~', $this->startTokenStack[$pos - 1]->position), - 132 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '===', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 133 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '!==', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 134 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '==', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 135 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '!=', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 136 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '<=>', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 137 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '<', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 138 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '<=', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 139 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '>', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 140 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '>=', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 141 => fn() => $this->semValue = new Expression\InstanceofNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 144 => fn() => $this->semValue = new Expression\TernaryNode($this->semStack[$pos - 4], $this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 4]->position), - 145 => fn() => $this->semValue = new Expression\TernaryNode($this->semStack[$pos - 3], null, $this->semStack[$pos], $this->startTokenStack[$pos - 3]->position), - 146 => fn() => $this->semValue = new Expression\TernaryNode($this->semStack[$pos - 2], $this->semStack[$pos], null, $this->startTokenStack[$pos - 2]->position), - 147 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '??', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 148 => fn() => $this->semValue = new Expression\IssetNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), - 149 => fn() => $this->semValue = new Expression\EmptyNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), - 150 => fn() => $this->semValue = new Expression\CastNode('int', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 151 => fn() => $this->semValue = new Expression\CastNode('float', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 152 => fn() => $this->semValue = new Expression\CastNode('string', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 153 => fn() => $this->semValue = new Expression\CastNode('array', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 154 => fn() => $this->semValue = new Expression\CastNode('object', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 155 => fn() => $this->semValue = new Expression\CastNode('bool', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 156 => fn() => $this->semValue = new Expression\ErrorSuppressNode($this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 158 => fn() => $this->semValue = new Expression\ClosureNode((bool) $this->semStack[$pos - 6], $this->semStack[$pos - 4], [], $this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 7]->position), - 159 => fn() => $this->semValue = new Expression\ClosureNode((bool) $this->semStack[$pos - 10], $this->semStack[$pos - 8], $this->semStack[$pos - 6], $this->semStack[$pos - 5], $this->semStack[$pos - 2], $this->startTokenStack[$pos - 11]->position), - 160 => fn() => $this->semValue = new Expression\ClosureNode((bool) $this->semStack[$pos - 7], $this->semStack[$pos - 5], $this->semStack[$pos - 3], $this->semStack[$pos - 2], null, $this->startTokenStack[$pos - 8]->position), - 161 => fn() => $this->semValue = new Expression\NewNode($this->semStack[$pos - 1], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 167 => fn() => $this->semValue = new Expression\ClosureUseNode($this->semStack[$pos], $this->semStack[$pos - 1], $this->startTokenStack[$pos - 1]->position), - 168, 170 => fn() => $this->semValue = new Expression\FunctionCallNode($this->semStack[$pos - 1], $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), - 169, 171 => fn() => $this->semValue = new Expression\FunctionCallableNode($this->semStack[$pos - 3], $this->startTokenStack[$pos - 3]->position), - 172 => fn() => $this->semValue = new Expression\StaticCallNode($this->semStack[$pos - 3], $this->semStack[$pos - 1], $this->semStack[$pos], $this->startTokenStack[$pos - 3]->position), - 173 => fn() => $this->semValue = new Expression\StaticCallableNode($this->semStack[$pos - 5], $this->semStack[$pos - 3], $this->startTokenStack[$pos - 5]->position), - 175, 177, 178 => fn() => $this->semValue = new Node\NameNode($this->semStack[$pos], Node\NameNode::KindNormal, $this->startTokenStack[$pos]->position), - 179 => fn() => $this->semValue = new Node\NameNode($this->semStack[$pos], Node\NameNode::KindFullyQualified, $this->startTokenStack[$pos]->position), - 187 => fn() => $this->semValue = new Expression\ConstantFetchNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), - 188 => fn() => $this->semValue = new Expression\ClassConstantFetchNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 189 => fn() => $this->semValue = new Expression\ArrayNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 2]->position), - 190, 247 => fn() => $this->semValue = new Expression\ArrayNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), - 192 => fn() => $this->semValue = Scalar\StringNode::parse($this->semStack[$pos], $this->startTokenStack[$pos]->position), - 193 => fn() => $this->semValue = Scalar\EncapsedStringNode::parse($this->semStack[$pos - 1], $this->startTokenStack[$pos - 2]->position), - 194 => fn() => $this->semValue = Scalar\IntegerNode::parse($this->semStack[$pos], $this->startTokenStack[$pos]->position), - 195 => fn() => $this->semValue = Scalar\FloatNode::parse($this->semStack[$pos], $this->startTokenStack[$pos]->position), - 197, 278 => fn() => $this->semValue = new Scalar\StringNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), - 198 => fn() => $this->semValue = new Scalar\BooleanNode(true, $this->startTokenStack[$pos]->position), - 199 => fn() => $this->semValue = new Scalar\BooleanNode(false, $this->startTokenStack[$pos]->position), - 200 => fn() => $this->semValue = new Scalar\NullNode($this->startTokenStack[$pos]->position), - 203 => fn() => $this->semValue = $this->parseDocString($this->semStack[$pos - 2], [$this->semStack[$pos - 1]], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position, $this->startTokenStack[$pos]->position), - 204 => fn() => $this->semValue = $this->parseDocString($this->semStack[$pos - 1], [], $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position, $this->startTokenStack[$pos]->position), - 205 => fn() => $this->semValue = $this->parseDocString($this->semStack[$pos - 2], $this->semStack[$pos - 1], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position, $this->startTokenStack[$pos]->position), - 214 => fn() => $this->semValue = new Expression\ConstantFetchNode(new Node\NameNode($this->semStack[$pos], Node\NameNode::KindNormal, $this->startTokenStack[$pos]->position), $this->startTokenStack[$pos]->position), - 219, 235, 270 => fn() => $this->semValue = new Expression\ArrayAccessNode($this->semStack[$pos - 3], $this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), - 221 => fn() => $this->semValue = new Expression\MethodCallNode($this->semStack[$pos - 3], $this->semStack[$pos - 1], $this->semStack[$pos], false, $this->startTokenStack[$pos - 3]->position), - 222 => fn() => $this->semValue = new Expression\MethodCallableNode($this->semStack[$pos - 5], $this->semStack[$pos - 3], $this->startTokenStack[$pos - 5]->position), - 223 => fn() => $this->semValue = new Expression\MethodCallNode($this->semStack[$pos - 3], $this->semStack[$pos - 1], $this->semStack[$pos], true, $this->startTokenStack[$pos - 3]->position), - 224 => fn() => $this->semValue = new Expression\MethodCallNode(new Expression\BinaryOpNode($this->semStack[$pos - 3], '??', new Scalar\NullNode($this->startTokenStack[$pos - 3]->position), $this->startTokenStack[$pos - 3]->position), $this->semStack[$pos - 1], $this->semStack[$pos], true, $this->startTokenStack[$pos - 3]->position), - 227, 236, 271 => fn() => $this->semValue = new Expression\PropertyFetchNode($this->semStack[$pos - 2], $this->semStack[$pos], false, $this->startTokenStack[$pos - 2]->position), - 228, 237, 272 => fn() => $this->semValue = new Expression\PropertyFetchNode($this->semStack[$pos - 2], $this->semStack[$pos], true, $this->startTokenStack[$pos - 2]->position), - 229, 238, 273 => fn() => $this->semValue = new Expression\PropertyFetchNode(new Expression\BinaryOpNode($this->semStack[$pos - 2], '??', new Scalar\NullNode($this->startTokenStack[$pos - 2]->position), $this->startTokenStack[$pos - 2]->position), $this->semStack[$pos], true, $this->startTokenStack[$pos - 2]->position), - 231 => fn() => $this->semValue = new Expression\VariableNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), - 232 => function () use ($pos) { + 130, 131 => fn() => $this->semValue = new Expression\NotNode($this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 132 => fn() => $this->semValue = new Expression\UnaryOpNode($this->semStack[$pos], '~', $this->startTokenStack[$pos - 1]->position), + 133 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '===', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 134 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '!==', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 135 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '==', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 136 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '!=', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 137 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '<=>', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 138 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '<', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 139 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '<=', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 140 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '>', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 141 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '>=', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 142 => fn() => $this->semValue = new Expression\InstanceofNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 145 => fn() => $this->semValue = new Expression\TernaryNode($this->semStack[$pos - 4], $this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 4]->position), + 146 => fn() => $this->semValue = new Expression\TernaryNode($this->semStack[$pos - 3], null, $this->semStack[$pos], $this->startTokenStack[$pos - 3]->position), + 147 => fn() => $this->semValue = new Expression\TernaryNode($this->semStack[$pos - 2], $this->semStack[$pos], null, $this->startTokenStack[$pos - 2]->position), + 148 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '??', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 149 => fn() => $this->semValue = new Expression\IssetNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), + 150 => fn() => $this->semValue = new Expression\EmptyNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), + 151 => fn() => $this->semValue = new Expression\CastNode('int', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 152 => fn() => $this->semValue = new Expression\CastNode('float', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 153 => fn() => $this->semValue = new Expression\CastNode('string', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 154 => fn() => $this->semValue = new Expression\CastNode('array', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 155 => fn() => $this->semValue = new Expression\CastNode('object', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 156 => fn() => $this->semValue = new Expression\CastNode('bool', $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 157 => fn() => $this->semValue = new Expression\ErrorSuppressNode($this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 159 => fn() => $this->semValue = new Expression\ClosureNode((bool) $this->semStack[$pos - 6], $this->semStack[$pos - 4], [], $this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 7]->position), + 160 => fn() => $this->semValue = new Expression\ClosureNode((bool) $this->semStack[$pos - 10], $this->semStack[$pos - 8], $this->semStack[$pos - 6], $this->semStack[$pos - 5], $this->semStack[$pos - 2], $this->startTokenStack[$pos - 11]->position), + 161 => fn() => $this->semValue = new Expression\ClosureNode((bool) $this->semStack[$pos - 7], $this->semStack[$pos - 5], $this->semStack[$pos - 3], $this->semStack[$pos - 2], null, $this->startTokenStack[$pos - 8]->position), + 162 => fn() => $this->semValue = new Expression\NewNode($this->semStack[$pos - 1], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 168 => fn() => $this->semValue = new Expression\ClosureUseNode($this->semStack[$pos], $this->semStack[$pos - 1], $this->startTokenStack[$pos - 1]->position), + 169, 171 => fn() => $this->semValue = new Expression\FunctionCallNode($this->semStack[$pos - 1], $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 170, 172 => fn() => $this->semValue = new Expression\FunctionCallableNode($this->semStack[$pos - 3], $this->startTokenStack[$pos - 3]->position), + 173 => fn() => $this->semValue = new Expression\StaticCallNode($this->semStack[$pos - 3], $this->semStack[$pos - 1], $this->semStack[$pos], $this->startTokenStack[$pos - 3]->position), + 174 => fn() => $this->semValue = new Expression\StaticCallableNode($this->semStack[$pos - 5], $this->semStack[$pos - 3], $this->startTokenStack[$pos - 5]->position), + 176, 178, 179 => fn() => $this->semValue = new Node\NameNode($this->semStack[$pos], Node\NameNode::KindNormal, $this->startTokenStack[$pos]->position), + 180 => fn() => $this->semValue = new Node\NameNode($this->semStack[$pos], Node\NameNode::KindFullyQualified, $this->startTokenStack[$pos]->position), + 188 => fn() => $this->semValue = new Expression\ConstantFetchNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), + 189 => fn() => $this->semValue = new Expression\ClassConstantFetchNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 190 => fn() => $this->semValue = new Expression\ArrayNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 2]->position), + 191, 248 => fn() => $this->semValue = new Expression\ArrayNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), + 193 => fn() => $this->semValue = Scalar\StringNode::parse($this->semStack[$pos], $this->startTokenStack[$pos]->position), + 194 => fn() => $this->semValue = Scalar\EncapsedStringNode::parse($this->semStack[$pos - 1], $this->startTokenStack[$pos - 2]->position), + 195 => fn() => $this->semValue = Scalar\IntegerNode::parse($this->semStack[$pos], $this->startTokenStack[$pos]->position), + 196 => fn() => $this->semValue = Scalar\FloatNode::parse($this->semStack[$pos], $this->startTokenStack[$pos]->position), + 198, 279 => fn() => $this->semValue = new Scalar\StringNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), + 199 => fn() => $this->semValue = new Scalar\BooleanNode(true, $this->startTokenStack[$pos]->position), + 200 => fn() => $this->semValue = new Scalar\BooleanNode(false, $this->startTokenStack[$pos]->position), + 201 => fn() => $this->semValue = new Scalar\NullNode($this->startTokenStack[$pos]->position), + 204 => fn() => $this->semValue = $this->parseDocString($this->semStack[$pos - 2], [$this->semStack[$pos - 1]], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position, $this->startTokenStack[$pos]->position), + 205 => fn() => $this->semValue = $this->parseDocString($this->semStack[$pos - 1], [], $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position, $this->startTokenStack[$pos]->position), + 206 => fn() => $this->semValue = $this->parseDocString($this->semStack[$pos - 2], $this->semStack[$pos - 1], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position, $this->startTokenStack[$pos]->position), + 215 => fn() => $this->semValue = new Expression\ConstantFetchNode(new Node\NameNode($this->semStack[$pos], Node\NameNode::KindNormal, $this->startTokenStack[$pos]->position), $this->startTokenStack[$pos]->position), + 220, 236, 271 => fn() => $this->semValue = new Expression\ArrayAccessNode($this->semStack[$pos - 3], $this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), + 222 => fn() => $this->semValue = new Expression\MethodCallNode($this->semStack[$pos - 3], $this->semStack[$pos - 1], $this->semStack[$pos], false, $this->startTokenStack[$pos - 3]->position), + 223 => fn() => $this->semValue = new Expression\MethodCallableNode($this->semStack[$pos - 5], $this->semStack[$pos - 3], $this->startTokenStack[$pos - 5]->position), + 224 => fn() => $this->semValue = new Expression\MethodCallNode($this->semStack[$pos - 3], $this->semStack[$pos - 1], $this->semStack[$pos], true, $this->startTokenStack[$pos - 3]->position), + 225 => fn() => $this->semValue = new Expression\MethodCallNode(new Expression\BinaryOpNode($this->semStack[$pos - 3], '??', new Scalar\NullNode($this->startTokenStack[$pos - 3]->position), $this->startTokenStack[$pos - 3]->position), $this->semStack[$pos - 1], $this->semStack[$pos], true, $this->startTokenStack[$pos - 3]->position), + 228, 237, 272 => fn() => $this->semValue = new Expression\PropertyFetchNode($this->semStack[$pos - 2], $this->semStack[$pos], false, $this->startTokenStack[$pos - 2]->position), + 229, 238, 273 => fn() => $this->semValue = new Expression\PropertyFetchNode($this->semStack[$pos - 2], $this->semStack[$pos], true, $this->startTokenStack[$pos - 2]->position), + 230, 239, 274 => fn() => $this->semValue = new Expression\PropertyFetchNode(new Expression\BinaryOpNode($this->semStack[$pos - 2], '??', new Scalar\NullNode($this->startTokenStack[$pos - 2]->position), $this->startTokenStack[$pos - 2]->position), $this->semStack[$pos], true, $this->startTokenStack[$pos - 2]->position), + 232 => fn() => $this->semValue = new Expression\VariableNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 3]->position), + 233 => function () use ($pos) { $var = $this->semStack[$pos]->name; $this->semValue = \is_string($var) ? new Node\VarLikeIdentifierNode($var, $this->startTokenStack[$pos]->position) : $var; }, - 233, 239, 240 => fn() => $this->semValue = new Expression\StaticPropertyFetchNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 248 => function () use ($pos) { + 234, 240, 241 => fn() => $this->semValue = new Expression\StaticPropertyFetchNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 249 => function () use ($pos) { $this->semValue = $this->semStack[$pos]; $end = count($this->semValue) - 1; if ($this->semValue[$end] === null) { array_pop($this->semValue); } }, - 253, 255 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], null, false, false, $this->startTokenStack[$pos]->position), - 254 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], null, true, false, $this->startTokenStack[$pos - 1]->position), - 256, 258, 259 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], $this->semStack[$pos - 2], false, false, $this->startTokenStack[$pos - 2]->position), - 257, 260 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], $this->semStack[$pos - 3], true, false, $this->startTokenStack[$pos - 3]->position), - 261, 262 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], null, false, true, $this->startTokenStack[$pos - 1]->position), - 263, 264 => function () use ($pos) { + 254, 256 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], null, false, false, $this->startTokenStack[$pos]->position), + 255 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], null, true, false, $this->startTokenStack[$pos - 1]->position), + 257, 259, 260 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], $this->semStack[$pos - 2], false, false, $this->startTokenStack[$pos - 2]->position), + 258, 261 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], $this->semStack[$pos - 3], true, false, $this->startTokenStack[$pos - 3]->position), + 262, 263 => fn() => $this->semValue = new Expression\ArrayItemNode($this->semStack[$pos], null, false, true, $this->startTokenStack[$pos - 1]->position), + 264, 265 => function () use ($pos) { $this->semStack[$pos - 1][] = $this->semStack[$pos]; $this->semValue = $this->semStack[$pos - 1]; }, - 266 => fn() => $this->semValue = [$this->semStack[$pos - 1], $this->semStack[$pos]], - 267 => fn() => $this->semValue = new Scalar\EncapsedStringPartNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), - 268 => fn() => $this->semValue = new Expression\VariableNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), - 274, 275 => fn() => $this->semValue = new Expression\VariableNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 2]->position), - 276 => fn() => $this->semValue = new Expression\ArrayAccessNode($this->semStack[$pos - 4], $this->semStack[$pos - 2], $this->startTokenStack[$pos - 5]->position), - 279 => fn() => $this->semValue = TagParser::parseOffset($this->semStack[$pos], $this->startTokenStack[$pos]->position), - 280 => fn() => $this->semValue = TagParser::parseOffset('-' . $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), + 267 => fn() => $this->semValue = [$this->semStack[$pos - 1], $this->semStack[$pos]], + 268 => fn() => $this->semValue = new Scalar\EncapsedStringPartNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), + 269 => fn() => $this->semValue = new Expression\VariableNode($this->semStack[$pos], $this->startTokenStack[$pos]->position), + 275, 276 => fn() => $this->semValue = new Expression\VariableNode($this->semStack[$pos - 1], $this->startTokenStack[$pos - 2]->position), + 277 => fn() => $this->semValue = new Expression\ArrayAccessNode($this->semStack[$pos - 4], $this->semStack[$pos - 2], $this->startTokenStack[$pos - 5]->position), + 280 => fn() => $this->semValue = TagParser::parseOffset($this->semStack[$pos], $this->startTokenStack[$pos]->position), + 281 => fn() => $this->semValue = TagParser::parseOffset('-' . $this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), })(); } } diff --git a/src/Latte/Compiler/Token.php b/src/Latte/Compiler/Token.php index 569474f8d..843b9ef25 100644 --- a/src/Latte/Compiler/Token.php +++ b/src/Latte/Compiler/Token.php @@ -64,65 +64,66 @@ final class Token Php_BooleanAnd = 276, Php_AmpersandNotFollowed = 277, Php_AmpersandFollowed = 278, - Php_IsEqual = 279, - Php_IsNotEqual = 280, - Php_IsIdentical = 281, - Php_IsNotIdentical = 282, - Php_Spaceship = 283, - Php_IsSmallerOrEqual = 284, - Php_IsGreaterOrEqual = 285, - Php_Sl = 286, - Php_Sr = 287, - Php_In = 288, - Php_Instanceof = 289, - Php_Inc = 290, - Php_Dec = 291, - Php_IntCast = 292, - Php_FloatCast = 293, - Php_StringCast = 294, - Php_ArrayCast = 295, - Php_ObjectCast = 296, - Php_BoolCast = 297, - Php_Pow = 298, - Php_New = 299, - Php_Clone = 300, - Php_Integer = 301, - Php_Float = 302, - Php_Identifier = 303, - Php_StringVarname = 304, - Php_Constant = 305, - Php_Variable = 306, - Php_NumString = 307, - Php_EncapsedAndWhitespace = 308, - Php_ConstantEncapsedString = 309, - Php_Match = 310, - Php_Default = 311, - Php_Function = 312, - Php_Fn = 313, - Php_Return = 314, - Php_Use = 315, - Php_Isset = 316, - Php_Empty = 317, - Php_ObjectOperator = 318, - Php_NullsafeObjectOperator = 319, - Php_UndefinedsafeObjectOperator = 320, - Php_List = 321, - Php_Array = 322, - Php_StartHeredoc = 323, - Php_EndHeredoc = 324, - Php_DollarOpenCurlyBraces = 325, - Php_CurlyOpen = 326, - Php_PaamayimNekudotayim = 327, - Php_NsSeparator = 328, - Php_Ellipsis = 329, - Php_ExpandCast = 330, - Php_NameFullyQualified = 331, - Php_NameQualified = 332, - Php_Whitespace = 333, - Php_Comment = 334, - Php_Null = 335, - Php_True = 336, - Php_False = 337; + Php_Not = 279, + Php_IsEqual = 280, + Php_IsNotEqual = 281, + Php_IsIdentical = 282, + Php_IsNotIdentical = 283, + Php_Spaceship = 284, + Php_IsSmallerOrEqual = 285, + Php_IsGreaterOrEqual = 286, + Php_In = 287, + Php_Sl = 288, + Php_Sr = 289, + Php_Instanceof = 290, + Php_Inc = 291, + Php_Dec = 292, + Php_IntCast = 293, + Php_FloatCast = 294, + Php_StringCast = 295, + Php_ArrayCast = 296, + Php_ObjectCast = 297, + Php_BoolCast = 298, + Php_Pow = 299, + Php_New = 300, + Php_Clone = 301, + Php_Integer = 302, + Php_Float = 303, + Php_Identifier = 304, + Php_StringVarname = 305, + Php_Constant = 306, + Php_Variable = 307, + Php_NumString = 308, + Php_EncapsedAndWhitespace = 309, + Php_ConstantEncapsedString = 310, + Php_Match = 311, + Php_Default = 312, + Php_Function = 313, + Php_Fn = 314, + Php_Return = 315, + Php_Use = 316, + Php_Isset = 317, + Php_Empty = 318, + Php_ObjectOperator = 319, + Php_NullsafeObjectOperator = 320, + Php_UndefinedsafeObjectOperator = 321, + Php_List = 322, + Php_Array = 323, + Php_StartHeredoc = 324, + Php_EndHeredoc = 325, + Php_DollarOpenCurlyBraces = 326, + Php_CurlyOpen = 327, + Php_PaamayimNekudotayim = 328, + Php_NsSeparator = 329, + Php_Ellipsis = 330, + Php_ExpandCast = 331, + Php_NameFullyQualified = 332, + Php_NameQualified = 333, + Php_Whitespace = 334, + Php_Comment = 335, + Php_Null = 336, + Php_True = 337, + Php_False = 338; public const NAMES = [ self::End => '[EOF]', @@ -169,6 +170,7 @@ final class Token self::Php_BooleanAnd => "'&&'", self::Php_AmpersandNotFollowed => "'&'", self::Php_AmpersandFollowed => "'&'", + self::Php_Not => "'not'", self::Php_IsEqual => "'=='", self::Php_IsNotEqual => "'!='", self::Php_IsIdentical => "'==='", @@ -176,9 +178,9 @@ final class Token self::Php_Spaceship => "'<=>'", self::Php_IsSmallerOrEqual => "'<='", self::Php_IsGreaterOrEqual => "'>='", + self::Php_In => "'in'", self::Php_Sl => "'<<'", self::Php_Sr => "'>>'", - self::Php_In => "'in'", self::Php_Instanceof => "'instanceof'", self::Php_Inc => "'++'", self::Php_Dec => "'--'", diff --git a/tests/phpLexer/names.phpt b/tests/phpLexer/names.phpt index 42ca3d4c5..5603a02bb 100644 --- a/tests/phpLexer/names.phpt +++ b/tests/phpLexer/names.phpt @@ -56,7 +56,7 @@ __halt_compiler(); #10:8 Php_Whitespace '\n' #11:1 Php_Identifier 'aaa--bbb' #11:9 Php_Whitespace '\n' -#12:1 Php_Identifier 'not' +#12:1 Php_Not 'not' #12:4 Php_Dec '--' #12:6 '-' #12:7 Php_Identifier 'name' diff --git a/tests/phpLexer/operators.phpt b/tests/phpLexer/operators.phpt index 2be7b5fc4..f3a0f7783 100644 --- a/tests/phpLexer/operators.phpt +++ b/tests/phpLexer/operators.phpt @@ -44,6 +44,9 @@ $test = <<<'XX' $a xor $b; $b && 2; $b || 1; + + !$a; + not $a; XX; $tokens = (new TagLexer)->tokenize($test); @@ -268,4 +271,13 @@ __halt_compiler(); #34:6 Php_Whitespace ' ' #34:7 Php_Integer '1' #34:8 ';' -#34:9 End '' +#34:9 Php_Whitespace '\n\n' +#36:1 '!' +#36:2 Php_Variable '$a' +#36:4 ';' +#36:5 Php_Whitespace '\n' +#37:1 Php_Not 'not' +#37:4 Php_Whitespace ' ' +#37:5 Php_Variable '$a' +#37:7 ';' +#37:8 End '' diff --git a/tests/phpParser/in.phpt b/tests/phpParser/in.phpt index 08bd3a241..64fed9435 100644 --- a/tests/phpParser/in.phpt +++ b/tests/phpParser/in.phpt @@ -13,7 +13,7 @@ $test = <<<'XX' /* precedence */ $a in $b || $c in $d, - $a = $b in $c, + $a = not 10 + 20 in $c, XX; $node = parseCode($test); @@ -68,13 +68,23 @@ Latte\Compiler\Nodes\Php\Expression\ArrayNode | | | var: Latte\Compiler\Nodes\Php\Expression\VariableNode | | | | name: 'a' | | | | position: 5:1 (offset 50) - | | | expr: Latte\Compiler\Nodes\Php\Expression\InRangeNode - | | | | needle: Latte\Compiler\Nodes\Php\Expression\VariableNode - | | | | | name: 'b' - | | | | | position: 5:6 (offset 55) - | | | | haystack: Latte\Compiler\Nodes\Php\Expression\VariableNode - | | | | | name: 'c' - | | | | | position: 5:12 (offset 61) + | | | expr: Latte\Compiler\Nodes\Php\Expression\NotNode + | | | | expr: Latte\Compiler\Nodes\Php\Expression\InRangeNode + | | | | | needle: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode + | | | | | | left: Latte\Compiler\Nodes\Php\Scalar\IntegerNode + | | | | | | | value: 10 + | | | | | | | kind: 10 + | | | | | | | position: 5:10 (offset 59) + | | | | | | operator: '+' + | | | | | | right: Latte\Compiler\Nodes\Php\Scalar\IntegerNode + | | | | | | | value: 20 + | | | | | | | kind: 10 + | | | | | | | position: 5:15 (offset 64) + | | | | | | position: 5:10 (offset 59) + | | | | | haystack: Latte\Compiler\Nodes\Php\Expression\VariableNode + | | | | | | name: 'c' + | | | | | | position: 5:21 (offset 70) + | | | | | position: 5:10 (offset 59) | | | | position: 5:6 (offset 55) | | | byRef: false | | | position: 5:1 (offset 50) diff --git a/tests/phpParser/logic.phpt b/tests/phpParser/logic.phpt index 49acf98d2..5f76e907e 100644 --- a/tests/phpParser/logic.phpt +++ b/tests/phpParser/logic.phpt @@ -26,6 +26,8 @@ $test = <<<'XX' $a = $b || $c, $a = $b or $c, + + not $a > $b && $c == $d, XX; $node = parseCode($test); @@ -37,7 +39,7 @@ Assert::same( __halt_compiler(); Latte\Compiler\Nodes\Php\Expression\ArrayNode - items: array (11) + items: array (12) | 0 => Latte\Compiler\Nodes\Php\Expression\ArrayItemNode | | value: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode | | | left: Latte\Compiler\Nodes\Php\Expression\VariableNode @@ -222,4 +224,32 @@ Latte\Compiler\Nodes\Php\Expression\ArrayNode | | byRef: false | | unpack: false | | position: 17:1 (offset 180) + | 11 => Latte\Compiler\Nodes\Php\Expression\ArrayItemNode + | | value: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode + | | | left: Latte\Compiler\Nodes\Php\Expression\NotNode + | | | | expr: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode + | | | | | left: Latte\Compiler\Nodes\Php\Expression\VariableNode + | | | | | | name: 'a' + | | | | | | position: 19:5 (offset 200) + | | | | | operator: '>' + | | | | | right: Latte\Compiler\Nodes\Php\Expression\VariableNode + | | | | | | name: 'b' + | | | | | | position: 19:10 (offset 205) + | | | | | position: 19:5 (offset 200) + | | | | position: 19:1 (offset 196) + | | | operator: '&&' + | | | right: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode + | | | | left: Latte\Compiler\Nodes\Php\Expression\VariableNode + | | | | | name: 'c' + | | | | | position: 19:16 (offset 211) + | | | | operator: '==' + | | | | right: Latte\Compiler\Nodes\Php\Expression\VariableNode + | | | | | name: 'd' + | | | | | position: 19:22 (offset 217) + | | | | position: 19:16 (offset 211) + | | | position: 19:1 (offset 196) + | | key: null + | | byRef: false + | | unpack: false + | | position: 19:1 (offset 196) position: null diff --git a/tests/phpPrint/operators.phpt b/tests/phpPrint/operators.phpt index 45e71e635..4e646846c 100644 --- a/tests/phpPrint/operators.phpt +++ b/tests/phpPrint/operators.phpt @@ -78,6 +78,10 @@ $test = <<<'XX' $a instanceof $b, $a in $b, + !$a in $b && not $a + 2 in $b, + + not $a, + not $a > $b && not $c == not $d, XX; $node = parseCode($test); @@ -150,4 +154,7 @@ $a xor $b, $a or $b, $a instanceof Foo, $a instanceof $b, -in_array($a, $b, true) +in_array($a, $b, true), +in_array(!$a, $b, true) && !in_array($a + 2, $b, true), +!$a, +!($a > $b) && !($c == !$d) From 9f8324cba3587ea34745a49295f4568b66ef1c1d Mon Sep 17 00:00:00 2001 From: David Grudl Date: Wed, 19 Oct 2022 04:59:48 +0200 Subject: [PATCH 3/5] operator 'in' supports strings - InRangeNode renamed to InNode --- .../{InRangeNode.php => InNode.php} | 6 ++--- src/Latte/Compiler/TagParserData.php | 2 +- src/Latte/Runtime/Filters.php | 11 ++++++++ tests/common/TagParser.parseArguments().phpt | 8 +++--- tests/filters/contains.phpt | 26 +++++++++++++++++++ tests/phpParser/in.phpt | 8 +++--- tests/phpPrint/operators.phpt | 4 +-- 7 files changed, 51 insertions(+), 14 deletions(-) rename src/Latte/Compiler/Nodes/Php/Expression/{InRangeNode.php => InNode.php} (90%) create mode 100644 tests/filters/contains.phpt diff --git a/src/Latte/Compiler/Nodes/Php/Expression/InRangeNode.php b/src/Latte/Compiler/Nodes/Php/Expression/InNode.php similarity index 90% rename from src/Latte/Compiler/Nodes/Php/Expression/InRangeNode.php rename to src/Latte/Compiler/Nodes/Php/Expression/InNode.php index 8bf51ef6b..c865cf9b2 100644 --- a/src/Latte/Compiler/Nodes/Php/Expression/InRangeNode.php +++ b/src/Latte/Compiler/Nodes/Php/Expression/InNode.php @@ -14,7 +14,7 @@ use Latte\Compiler\PrintContext; -class InRangeNode extends ExpressionNode +class InNode extends ExpressionNode { public function __construct( public ExpressionNode $needle, @@ -26,11 +26,11 @@ public function __construct( public function print(PrintContext $context): string { - return 'in_array(' + return 'LR\Filters::contains(' . $this->needle->print($context) . ', ' . $this->haystack->print($context) - . ', true)'; + . ')'; } diff --git a/src/Latte/Compiler/TagParserData.php b/src/Latte/Compiler/TagParserData.php index 1850a4f24..af658697f 100644 --- a/src/Latte/Compiler/TagParserData.php +++ b/src/Latte/Compiler/TagParserData.php @@ -482,7 +482,7 @@ protected function reduce(int $rule, int $pos): void 124 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '<<', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), 125 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '>>', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), 126 => fn() => $this->semValue = new Expression\BinaryOpNode($this->semStack[$pos - 2], '**', $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), - 127 => fn() => $this->semValue = new Expression\InRangeNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), + 127 => fn() => $this->semValue = new Expression\InNode($this->semStack[$pos - 2], $this->semStack[$pos], $this->startTokenStack[$pos - 2]->position), 128 => fn() => $this->semValue = new Expression\UnaryOpNode($this->semStack[$pos], '+', $this->startTokenStack[$pos - 1]->position), 129 => fn() => $this->semValue = new Expression\UnaryOpNode($this->semStack[$pos], '-', $this->startTokenStack[$pos - 1]->position), 130, 131 => fn() => $this->semValue = new Expression\NotNode($this->semStack[$pos], $this->startTokenStack[$pos - 1]->position), diff --git a/src/Latte/Runtime/Filters.php b/src/Latte/Runtime/Filters.php index 6509ce1e0..1e128e914 100644 --- a/src/Latte/Runtime/Filters.php +++ b/src/Latte/Runtime/Filters.php @@ -174,6 +174,17 @@ public static function escapeHtmlRawText($s): string } + /** + * Determine if a string or array contains a given needle. + */ + public static function contains(mixed $needle, array|string $haystack): bool + { + return is_array($haystack) + ? in_array($needle, $haystack, true) + : str_contains($haystack, (string) $needle); + } + + /** * Converts ... to ... */ diff --git a/tests/common/TagParser.parseArguments().phpt b/tests/common/TagParser.parseArguments().phpt index 28420d5e8..f1c6a226e 100644 --- a/tests/common/TagParser.parseArguments().phpt +++ b/tests/common/TagParser.parseArguments().phpt @@ -94,10 +94,10 @@ test('inline modifiers', function () { test('in operator', function () { - Assert::same("in_array(\$a, ['a', 'b'], true), 1", formatArgs('$a in [a, b], 1')); - Assert::same('$a, in_array($b->func(), [1, 2], true)', formatArgs('$a, $b->func() in [1, 2]')); - Assert::same('$a, in_array($b[1], [1, 2], true)', formatArgs('$a, $b[1] in [1, 2]')); - Assert::same('in_array($b, [1, [2], 3], true)', formatArgs('$b in [1, [2], 3]')); + Assert::same("LR\\Filters::contains(\$a, ['a', 'b']), 1", formatArgs('$a in [a, b], 1')); + Assert::same('$a, LR\Filters::contains($b->func(), [1, 2])', formatArgs('$a, $b->func() in [1, 2]')); + Assert::same('$a, LR\Filters::contains($b[1], [1, 2])', formatArgs('$a, $b[1] in [1, 2]')); + Assert::same('LR\Filters::contains($b, [1, [2], 3])', formatArgs('$b in [1, [2], 3]')); }); diff --git a/tests/filters/contains.phpt b/tests/filters/contains.phpt new file mode 100644 index 000000000..17f700293 --- /dev/null +++ b/tests/filters/contains.phpt @@ -0,0 +1,26 @@ + Latte\Compiler\Nodes\Php\Expression\ArrayItemNode - | | value: Latte\Compiler\Nodes\Php\Expression\InRangeNode + | | value: Latte\Compiler\Nodes\Php\Expression\InNode | | | needle: Latte\Compiler\Nodes\Php\Expression\VariableNode | | | | name: 'a' | | | | position: 1:1 (offset 0) @@ -41,7 +41,7 @@ Latte\Compiler\Nodes\Php\Expression\ArrayNode | | position: 1:1 (offset 0) | 1 => Latte\Compiler\Nodes\Php\Expression\ArrayItemNode | | value: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode - | | | left: Latte\Compiler\Nodes\Php\Expression\InRangeNode + | | | left: Latte\Compiler\Nodes\Php\Expression\InNode | | | | needle: Latte\Compiler\Nodes\Php\Expression\VariableNode | | | | | name: 'a' | | | | | position: 4:1 (offset 28) @@ -50,7 +50,7 @@ Latte\Compiler\Nodes\Php\Expression\ArrayNode | | | | | position: 4:7 (offset 34) | | | | position: 4:1 (offset 28) | | | operator: '||' - | | | right: Latte\Compiler\Nodes\Php\Expression\InRangeNode + | | | right: Latte\Compiler\Nodes\Php\Expression\InNode | | | | needle: Latte\Compiler\Nodes\Php\Expression\VariableNode | | | | | name: 'c' | | | | | position: 4:13 (offset 40) @@ -69,7 +69,7 @@ Latte\Compiler\Nodes\Php\Expression\ArrayNode | | | | name: 'a' | | | | position: 5:1 (offset 50) | | | expr: Latte\Compiler\Nodes\Php\Expression\NotNode - | | | | expr: Latte\Compiler\Nodes\Php\Expression\InRangeNode + | | | | expr: Latte\Compiler\Nodes\Php\Expression\InNode | | | | | needle: Latte\Compiler\Nodes\Php\Expression\BinaryOpNode | | | | | | left: Latte\Compiler\Nodes\Php\Scalar\IntegerNode | | | | | | | value: 10 diff --git a/tests/phpPrint/operators.phpt b/tests/phpPrint/operators.phpt index 4e646846c..40c912dfc 100644 --- a/tests/phpPrint/operators.phpt +++ b/tests/phpPrint/operators.phpt @@ -154,7 +154,7 @@ $a xor $b, $a or $b, $a instanceof Foo, $a instanceof $b, -in_array($a, $b, true), -in_array(!$a, $b, true) && !in_array($a + 2, $b, true), +LR\Filters::contains($a, $b), +LR\Filters::contains(!$a, $b) && !LR\Filters::contains($a + 2, $b), !$a, !($a > $b) && !($c == !$d) From f18ec0465a49d08d208d0ab69d2fd01cd22b9bde Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 1 Nov 2022 16:57:35 +0100 Subject: [PATCH 4/5] Add namespace loader --- src/Latte/Loaders/NamespaceLoader.php | 87 +++++++++++++++++++++++ tests/common/Loaders.NamespaceLoader.phpt | 30 ++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/Latte/Loaders/NamespaceLoader.php create mode 100644 tests/common/Loaders.NamespaceLoader.phpt diff --git a/src/Latte/Loaders/NamespaceLoader.php b/src/Latte/Loaders/NamespaceLoader.php new file mode 100644 index 000000000..803614b91 --- /dev/null +++ b/src/Latte/Loaders/NamespaceLoader.php @@ -0,0 +1,87 @@ +loaders = $loaders; + } + + /** + * Returns template source code. + */ + public function getContent(string $name): string + { + [$loader, $name] = $this->extractLoaderAndName($name); + + return $loader->getContent($name); + } + + + public function isExpired(string $file, int $time): bool + { + [$loader, $name] = $this->extractLoaderAndName($file); + + return $loader->isExpired($name, $time); + } + + + /** + * Returns referred template name. + */ + public function getReferredName(string $name, string $referringName): string + { + [$loader, $name] = $this->extractLoaderAndName($name); + + return $loader->getReferredName($name, $referringName); + } + + + /** + * Returns unique identifier for caching. + */ + public function getUniqueId(string $name): string + { + [$loader, $name] = $this->extractLoaderAndName($name); + + return $loader->getUniqueId($name); + } + + + private function extractLoaderAndName(string $name): array + { + $namespaceParts = \explode('::', $name, 2); + + if (count($namespaceParts) === 2) { + return [ + $this->loaders[$namespaceParts[0]], + $namespaceParts[1], + ]; + } + + return [ + $this->loaders[''], + $name, + ]; + } +} diff --git a/tests/common/Loaders.NamespaceLoader.phpt b/tests/common/Loaders.NamespaceLoader.phpt new file mode 100644 index 000000000..532722951 --- /dev/null +++ b/tests/common/Loaders.NamespaceLoader.phpt @@ -0,0 +1,30 @@ + 'defaultcontent']); + $appLoader = new StringLoader(['main' => 'appcontent']); + $otherLoader = new StringLoader(['main' => 'othercontent']); + + $loader = new NamespaceLoader([ + '' => $defaultLoader, + 'app' => $appLoader, + 'other' => $otherLoader, + ]); + + Assert::same('defaultcontent', $loader->getContent('main')); + Assert::same('appcontent', $loader->getContent('app::main')); + Assert::same('othercontent', $loader->getContent('other::main')); +}); From ac829d380bbff64aeaf2267b9b1a5fca8d01e78e Mon Sep 17 00:00:00 2001 From: Alexander Schranz Date: Tue, 1 Nov 2022 16:58:30 +0100 Subject: [PATCH 5/5] Use tabs instead of spaces like in FileLoader --- src/Latte/Loaders/NamespaceLoader.php | 102 +++++++++++----------- tests/common/Loaders.NamespaceLoader.phpt | 26 +++--- 2 files changed, 64 insertions(+), 64 deletions(-) diff --git a/src/Latte/Loaders/NamespaceLoader.php b/src/Latte/Loaders/NamespaceLoader.php index 803614b91..c450bbfa2 100644 --- a/src/Latte/Loaders/NamespaceLoader.php +++ b/src/Latte/Loaders/NamespaceLoader.php @@ -17,71 +17,71 @@ */ class NamespaceLoader implements Latte\Loader { - /** - * @var Latte\Loader[] - */ - private array $loaders; + /** + * @var Latte\Loader[] + */ + private array $loaders; - public function __construct(array $loaders) - { - $this->loaders = $loaders; - } + public function __construct(array $loaders) + { + $this->loaders = $loaders; + } - /** - * Returns template source code. - */ - public function getContent(string $name): string - { - [$loader, $name] = $this->extractLoaderAndName($name); + /** + * Returns template source code. + */ + public function getContent(string $name): string + { + [$loader, $name] = $this->extractLoaderAndName($name); - return $loader->getContent($name); - } + return $loader->getContent($name); + } - public function isExpired(string $file, int $time): bool - { - [$loader, $name] = $this->extractLoaderAndName($file); + public function isExpired(string $file, int $time): bool + { + [$loader, $name] = $this->extractLoaderAndName($file); - return $loader->isExpired($name, $time); - } + return $loader->isExpired($name, $time); + } - /** - * Returns referred template name. - */ - public function getReferredName(string $name, string $referringName): string - { - [$loader, $name] = $this->extractLoaderAndName($name); + /** + * Returns referred template name. + */ + public function getReferredName(string $name, string $referringName): string + { + [$loader, $name] = $this->extractLoaderAndName($name); - return $loader->getReferredName($name, $referringName); - } + return $loader->getReferredName($name, $referringName); + } - /** - * Returns unique identifier for caching. - */ - public function getUniqueId(string $name): string - { - [$loader, $name] = $this->extractLoaderAndName($name); + /** + * Returns unique identifier for caching. + */ + public function getUniqueId(string $name): string + { + [$loader, $name] = $this->extractLoaderAndName($name); - return $loader->getUniqueId($name); - } + return $loader->getUniqueId($name); + } - private function extractLoaderAndName(string $name): array - { - $namespaceParts = \explode('::', $name, 2); + private function extractLoaderAndName(string $name): array + { + $namespaceParts = \explode('::', $name, 2); - if (count($namespaceParts) === 2) { - return [ - $this->loaders[$namespaceParts[0]], - $namespaceParts[1], - ]; - } + if (count($namespaceParts) === 2) { + return [ + $this->loaders[$namespaceParts[0]], + $namespaceParts[1], + ]; + } - return [ - $this->loaders[''], - $name, - ]; - } + return [ + $this->loaders[''], + $name, + ]; + } } diff --git a/tests/common/Loaders.NamespaceLoader.phpt b/tests/common/Loaders.NamespaceLoader.phpt index 532722951..018434a24 100644 --- a/tests/common/Loaders.NamespaceLoader.phpt +++ b/tests/common/Loaders.NamespaceLoader.phpt @@ -14,17 +14,17 @@ require __DIR__ . '/../bootstrap.php'; test('', function () { - $defaultLoader = new StringLoader(['main' => 'defaultcontent']); - $appLoader = new StringLoader(['main' => 'appcontent']); - $otherLoader = new StringLoader(['main' => 'othercontent']); - - $loader = new NamespaceLoader([ - '' => $defaultLoader, - 'app' => $appLoader, - 'other' => $otherLoader, - ]); - - Assert::same('defaultcontent', $loader->getContent('main')); - Assert::same('appcontent', $loader->getContent('app::main')); - Assert::same('othercontent', $loader->getContent('other::main')); + $defaultLoader = new StringLoader(['main' => 'defaultcontent']); + $appLoader = new StringLoader(['main' => 'appcontent']); + $otherLoader = new StringLoader(['main' => 'othercontent']); + + $loader = new NamespaceLoader([ + '' => $defaultLoader, + 'app' => $appLoader, + 'other' => $otherLoader, + ]); + + Assert::same('defaultcontent', $loader->getContent('main')); + Assert::same('appcontent', $loader->getContent('app::main')); + Assert::same('othercontent', $loader->getContent('other::main')); });