diff options
-rw-r--r-- | src/ste/Parser.php | 9 | ||||
-rw-r--r-- | src/ste/TagNode.php | 6 | ||||
-rw-r--r-- | src/ste/VariableNode.php | 16 | ||||
-rw-r--r-- | tests/unit/ParserTest.php | 176 |
4 files changed, 202 insertions, 5 deletions
diff --git a/src/ste/Parser.php b/src/ste/Parser.php index a588203..a2f966c 100644 --- a/src/ste/Parser.php +++ b/src/ste/Parser.php @@ -443,12 +443,15 @@ class Parser */ private function parse_var(int $openedat, bool $curly): VariableNode { - $varnode = new VariableNode($this->name, $openedat); - $varnode->name = $this->get_name(); + $varname = $this->get_name(); + + $arrayfields = []; if (!$this->eof()) { - $varnode->arrayfields = $this->parse_array(); + $arrayfields = $this->parse_array(); } + $varnode = new VariableNode($this->name, $openedat, $varname, $arrayfields); + if ($curly && ($this->next() != "}")) { throw new ParseCompileError("Unclosed '\${'", $this->name, $openedat); } diff --git a/src/ste/TagNode.php b/src/ste/TagNode.php index 4adcad8..ce713c0 100644 --- a/src/ste/TagNode.php +++ b/src/ste/TagNode.php @@ -17,10 +17,14 @@ class TagNode extends ASTNode * @param string $tpl * @param int $off * @param string $name + * @param ASTNode[][] $params + * @param ASTNode[] $sub */ - public function __construct(string $tpl, int $off, string $name = "") + public function __construct(string $tpl, int $off, string $name = "", array $params = [], array $sub = []) { parent::__construct($tpl, $off); $this->name = $name; + $this->params = $params; + $this->sub = $sub; } } diff --git a/src/ste/VariableNode.php b/src/ste/VariableNode.php index f5a0b26..cdffc3f 100644 --- a/src/ste/VariableNode.php +++ b/src/ste/VariableNode.php @@ -8,7 +8,21 @@ class VariableNode extends ASTNode public $name; /** @var ASTNode[][] */ - public $arrayfields = []; + public $arrayfields; + + /** + * @param string $tpl + * @param int $off + * @param string $name + * @param ASTNode[][] $arrayfields + */ + public function __construct(string $tpl, int $off, string $name, array $arrayfields) + { + parent::__construct($tpl, $off); + + $this->name = $name; + $this->arrayfields = $arrayfields; + } /** * @return string diff --git a/tests/unit/ParserTest.php b/tests/unit/ParserTest.php new file mode 100644 index 0000000..0a5ccb8 --- /dev/null +++ b/tests/unit/ParserTest.php @@ -0,0 +1,176 @@ +<?php + + +namespace tests\unit; + +use PHPUnit\Framework\TestCase; +use kch42\ste\Parser; +use kch42\ste\TextNode; +use kch42\ste\VariableNode; +use kch42\ste\TagNode; + +class ParserTest extends TestCase +{ + /** + * @dataProvider successfulParsingDataProvider + */ + public function testSuccessfulParsing(string $source, array $expected) + { + $actual = Parser::parse($source, '-'); + + self::assertEquals($expected, $actual); + } + + public function successfulParsingDataProvider() + { + return [ + ['', []], + + ['Hello', [ + new TextNode('-', 0, 'Hello'), + ]], + + ['$foo', [ + new VariableNode('-', 0, 'foo', []), + ]], + + //01234567890 + ['foo$bar$baz', [ + new TextNode('-', 0, 'foo'), + new VariableNode('-', 3, 'bar', []), + new VariableNode('-', 7, 'baz', []), + ]], + + //012345678 + ['${foo}bar', [ + new VariableNode('-', 0, 'foo', []), + new TextNode('-', 6, 'bar'), + ]], + + //012345678 + ['$foo[bar]', [ + new VariableNode('-', 0, 'foo', [ + [new TextNode('-', 5, 'bar')], + ]), + ]], + + //01234567890 + ['${foo[bar]}', [ + new VariableNode('-', 0, 'foo', [ + [new TextNode('-', 6, 'bar')], + ]), + ]], + + //012345678 + ['$foo[$bar]', [ + new VariableNode('-', 0, 'foo', [ + [new VariableNode('-', 5, 'bar', [])], + ]), + ]], + + //012345678901234 + ['$foo[$bar[baz]]', [ + new VariableNode('-', 0, 'foo', [ + [new VariableNode('-', 5, 'bar', [ + [new TextNode('-', 10, 'baz')], + ])], + ]), + ]], + + //012345678901234 + ['$foo[$bar][baz]', [ + new VariableNode('-', 0, 'foo', [ + [new VariableNode('-', 5, 'bar', [])], + [new TextNode('-', 11, 'baz')] + ]), + ]], + + //0123456789012345678901 + ['a${b[c$d[e${f}g]][h]}i', [ + new TextNode('-', 0, 'a'), + new VariableNode('-', 1, 'b', [ + [ + new TextNode('-', 5, 'c'), + new VariableNode('-', 6, 'd', [ + [ + new TextNode('-', 9, 'e'), + new VariableNode('-', 10, 'f', []), + new TextNode('-', 14, 'g') + ] + ]) + ], + [new TextNode('-', 18, 'h')], + ]), + new TextNode('-', 21, 'i'), + ]], + + ['<ste:foo />', [ + new TagNode('-', 0, 'foo'), + ]], + + ['<ste:foo></ste:foo>', [ + new TagNode('-', 0, 'foo'), + ]], + + //0123456789012345678901 + ['<ste:foo>bar</ste:foo>', [ + new TagNode('-', 0, 'foo', [], [ + new TextNode('-', 9, 'bar'), + ]), + ]], + + //0 1 2 3 4 5 6 7 8 9 0 + //012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234 + ['<ste:foo a="$b[0][$x]" c="\"" d="${e}f"><ste:foo><ste:xyz>abc</ste:xyz><ste:foo />$x</ste:foo></ste:foo>x', [ + new TagNode('-', 0, 'foo', [ + 'a' => [ + new VariableNode('-', 12, 'b', [ + [new TextNode('-', 15, '0')], + [new VariableNode('-', 18, 'x', [])], + ]), + ], + 'c' => [ + new TextNode('-', 26, '"'), + ], + 'd' => [ + new VariableNode('-', 33, 'e', []), + new TextNode('-', 37, 'f'), + ] + ], [ + new TagNode('-', 40, 'foo', [], [ + new TagNode('-', 49, 'xyz', [], [ + new TextNode('-', 58, 'abc'), + ]), + new TagNode('-', 71, 'foo'), + new VariableNode('-', 82, 'x', []), + ]), + ]), + new TextNode('-', 104, 'x'), + ]], + + //0 1 2 3 + //01234567890123456789012345678901234567 + ['foo?{~{$x|eq|\}$y}|b|<ste:foo/>\}}$bar', [ + new TextNode('-', 0, 'foo'), + new TagNode('-', 3, 'if', [], [ + new TagNode('-', 5, 'cmp', [ + 'text_a' => [new VariableNode('-', 7, 'x', [])], + 'op' => [new TextNode('-', 10, 'eq')], + 'text_b' => [ + new TextNode('-', 13, '}'), + new VariableNode('-', 15, 'y', []), + ], + ], []), + new TagNode('-', 3, 'then', [], [ + new TextNode('-', 19, 'b'), + ]), + new TagNode('-', 3, 'else', [], [ + new TagNode('-', 21, 'foo'), + new TextNode('-', 31, '}'), + ]), + ]), + new VariableNode('-', 34, 'bar', []), + ]], + ]; + } +} |