diff options
author | Michal Čihař <michal@cihar.com> | 2016-10-25 09:59:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-10-25 09:59:20 +0200 |
commit | 394fe168538da054afc69f8e9401591d0d8ed6f8 (patch) | |
tree | fbe93e7bffe8a65b6f3fa49315b68f50dc48795d /src | |
parent | 8463b6d18190fa9a95a6de0c416cd39f740e310a (diff) | |
parent | a54adc82d185722d36a0d1350c3ce80298aa15a4 (diff) | |
download | sql-parser-394fe168538da054afc69f8e9401591d0d8ed6f8.zip sql-parser-394fe168538da054afc69f8e9401591d0d8ed6f8.tar.gz sql-parser-394fe168538da054afc69f8e9401591d0d8ed6f8.tar.bz2 |
Merge pull request #94 from devenbansod/fix_57
Enable Lexing of begin_label in the in-procedure statements
Diffstat (limited to 'src')
-rw-r--r-- | src/Context.php | 10 | ||||
-rw-r--r-- | src/Lexer.php | 57 | ||||
-rw-r--r-- | src/Token.php | 12 |
3 files changed, 78 insertions, 1 deletions
diff --git a/src/Context.php b/src/Context.php index 0bdc696..3685857 100644 --- a/src/Context.php +++ b/src/Context.php @@ -30,6 +30,16 @@ abstract class Context const KEYWORD_MAX_LENGTH = 30; /** + * The maximum length of a label. + * + * @see static::$TOKEN_LABEL + * Ref: https://dev.mysql.com/doc/refman/5.7/en/statement-labels.html + * + * @var int + */ + const LABEL_MAX_LENGTH = 16; + + /** * The maximum length of an operator. * * @see static::$TOKEN_OPERATOR 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 diff --git a/src/Token.php b/src/Token.php index 3181a44..e5001ef 100644 --- a/src/Token.php +++ b/src/Token.php @@ -119,6 +119,18 @@ class Token */ const TYPE_DELIMITER = 9; + /** + * Labels in LOOP statement, ITERATE statement etc. + * For example (only for begin label): + * begin_label: BEGIN [statement_list] END [end_label] + * begin_label: LOOP [statement_list] END LOOP [end_label] + * begin_label: REPEAT [statement_list] ... END REPEAT [end_label] + * begin_label: WHILE ... DO [statement_list] END WHILE [end_label] + * + * @var int + */ + const TYPE_LABEL = 10; + // Flags that describe the tokens in more detail. // All keywords must have flag 1 so `Context::isKeyword` method doesn't // require strict comparison. |