diff options
Diffstat (limited to 'src/Lexer.php')
-rw-r--r-- | src/Lexer.php | 57 |
1 files changed, 56 insertions, 1 deletions
diff --git a/src/Lexer.php b/src/Lexer.php index 7fb2356..9de2a7a 100644 --- a/src/Lexer.php +++ b/src/Lexer.php @@ -76,7 +76,7 @@ class Lexer 'parseDelimiter', 'parseWhitespace', 'parseNumber', 'parseComment', 'parseOperator', 'parseBool', 'parseString', - 'parseSymbol', 'parseKeyword', 'parseUnknown' + 'parseSymbol', 'parseKeyword', 'parseLabel', 'parseUnknown' ); /** @@ -442,6 +442,61 @@ class Lexer } /** + * Parses a label. + * + * @return Token + */ + public function parseLabel() + { + $token = ''; + + /** + * Value to be returned. + * + * @var Token $ret + */ + $ret = null; + + /** + * The value of `$this->last` where `$token` ends in `$this->str`. + * + * @var int $iEnd + */ + $iEnd = $this->last; + + /** + * Whether last parsed character is a whitespace. + * + * @var bool $lastSpace + */ + $lastSpace = false; + + for ($j = 1; $j < Context::LABEL_MAX_LENGTH && $this->last < $this->len; ++$j, ++$this->last) { + // Composed keywords shouldn't have more than one whitespace between + // keywords. + if (Context::isWhitespace($this->str[$this->last])) { + if ($lastSpace) { + --$j; // The size of the keyword didn't increase. + continue; + } else { + $lastSpace = true; + } + } elseif ($this->str[$this->last] === ':') { + $token .= $this->str[$this->last]; + $ret = new Token($token, Token::TYPE_LABEL); + $iEnd = $this->last; + break; + } else { + $lastSpace = false; + } + $token .= $this->str[$this->last]; + } + + $this->last = $iEnd; + return $ret; + } + + /** * Parses an operator. * * @return Token |