summaryrefslogtreecommitdiffstats
path: root/src/Lexer.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Lexer.php')
-rw-r--r--src/Lexer.php57
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