summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/ste/Parser.php9
-rw-r--r--src/ste/TagNode.php6
-rw-r--r--src/ste/VariableNode.php16
-rw-r--r--tests/unit/ParserTest.php176
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', []),
+ ]],
+ ];
+ }
+}