diff options
Diffstat (limited to 'src/ste/Parser.php')
-rw-r--r-- | src/ste/Parser.php | 114 |
1 files changed, 94 insertions, 20 deletions
diff --git a/src/ste/Parser.php b/src/ste/Parser.php index 40f5f20..0280f6d 100644 --- a/src/ste/Parser.php +++ b/src/ste/Parser.php @@ -1,20 +1,25 @@ <?php -// File: Parser.php - -// Namespace: kch42\ste namespace kch42\ste; -/* - * Class: Parser +use LogicException; + +/** * The class, where the parser lives in. Can not be constructed manually. * Use the static method parse. */ class Parser { + /** @var string */ private $text; + + /** @var string */ private $name; + + /** @var int */ private $off; + + /** @var int */ private $len; const PARSE_SHORT = 1; @@ -22,6 +27,10 @@ class Parser const ESCAPES_DEFAULT = '$?~{}|\\'; + /** + * @param string $text + * @param string $name + */ private function __construct($text, $name) { $this->text = $text; @@ -30,6 +39,10 @@ class Parser $this->len = mb_strlen($text); } + /** + * @param int $n + * @return string + */ private function next($n = 1) { if ($n <= 0) { @@ -40,11 +53,17 @@ class Parser return $c; } + /** + * @return bool + */ private function eof() { return ($this->off == $this->len); } + /** + * @param int $n + */ private function back($n = 1) { if ($n <= 0) { @@ -53,11 +72,19 @@ class Parser $this->off = max($this->off - $n, 0); } + /** + * @param string $needle + * @return false|int + */ private function search_off($needle) { return mb_strpos($this->text, $needle, $this->off); } + /** + * @param string[] $needles + * @return array 4-tuple of found key, offset, text preceding offset, old offset + */ private function search_multi($needles) { $oldoff = $this->off; @@ -81,6 +108,10 @@ class Parser return array($which, $minoff, mb_substr($this->text, $oldoff, $minoff - $oldoff), $oldoff); } + /** + * @param string $needle + * @return array 3-tuple of offset (or false), text preceding offset, old offset + */ private function search($needle) { $oldoff = $this->off; @@ -95,7 +126,11 @@ class Parser return array($off, mb_substr($this->text, $oldoff, $off - $oldoff), $oldoff); } - private function take_while($cb) + /** + * @param callable $cb + * @return string + */ + private function take_while(callable $cb) { $s = ""; while (($c = $this->next()) !== "") { @@ -113,6 +148,10 @@ class Parser $this->take_while("ctype_space"); } + /** + * @return string + * @throws ParseCompileError + */ private function get_name() { $off = $this->off; @@ -125,21 +164,16 @@ class Parser return $name; } - /* - * Function: parse + /** * Parses the input into an AST. * - * You only need this function, if you want to manually trnascompile a template. + * You only need this function, if you want to manually compile a template. * - * Parameters: - * $text - The input code. - * $name - The name of the template. + * @param string $text The input code. + * @param string $name The name of the template. * - * Returns: - * An array of <ASTNode> objects. - * - * Throws: - * <ParseCompileError> + * @return ASTNode[] + * @throws ParseCompileError */ public static function parse($text, $name) { @@ -151,10 +185,15 @@ class Parser return self::tidyup_ast($res[0]); } + /** + * @param ASTNode[] $ast + * @return ASTNode[] + */ private static function tidyup_ast($ast) { $out = array(); + /** @var TextNode|null $prevtext */ $prevtext = null; $first = true; @@ -206,6 +245,17 @@ class Parser return $out; } + /** + * @param string $escapes + * @param int $flags + * @param string|null $breakon + * @param string|null $separator + * @param null $nullaction + * @param string|null $opentag + * @param int $openedat + * @return ASTNode[][] + * @throws ParseCompileError + */ private function parse_text($escapes, $flags, $breakon = null, $separator = null, $nullaction = null, $opentag = null, $openedat = -1) { $elems = array(); @@ -250,14 +300,14 @@ class Parser } break; case "commentopen": - list($off, $before, $offbefore) = $this->search("</ste:comment>"); + list($off, , $offbefore) = $this->search("</ste:comment>"); if ($off === false) { throw new ParseCompileError("ste:comment was not closed", $this->name, $offbefore); } break; case "rawopen": $off_start = $off; - list($off, $before, $offbefore) = $this->search("</ste:rawtext>"); + list($off, $before, ) = $this->search("</ste:rawtext>"); if ($off === false) { throw new ParseCompileError("ste:rawtext was not closed", $this->name, $off_start); } @@ -352,6 +402,12 @@ class Parser return $elems; } + /** + * @param string $shortname + * @param int $openedat + * @return ASTNode[][] + * @throws ParseCompileError + */ private function parse_short($shortname, $openedat) { $tplname = $this->name; @@ -369,6 +425,12 @@ class Parser ); } + /** + * @param int $openedat + * @param bool $curly + * @return VariableNode + * @throws ParseCompileError + */ private function parse_var($openedat, $curly) { $varnode = new VariableNode($this->name, $openedat); @@ -377,12 +439,16 @@ class Parser $varnode->arrayfields = $this->parse_array(); } - if (($curly) && ($this->next() != "}")) { + if ($curly && ($this->next() != "}")) { throw new ParseCompileError("Unclosed '\${'", $this->name, $openedat); } return $varnode; } + /** + * @return ASTNode[] + * @throws ParseCompileError + */ private function parse_array() { $tplname = $this->name; @@ -409,6 +475,11 @@ class Parser return $arrayfields; } + /** + * @param int $openedat + * @return TagNode + * @throws ParseCompileError + */ private function parse_tag($openedat) { $tplname = $this->name; @@ -475,5 +546,8 @@ class Parser $tag->params[$param] = $paramval[0]; } } + + // Help PhpStorm detect that we shouldn't be here + throw new LogicException("Somehow we left the infinite loop?"); } } |