summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Čihař <michal@cihar.com>2016-10-25 09:59:20 +0200
committerGitHub <noreply@github.com>2016-10-25 09:59:20 +0200
commit394fe168538da054afc69f8e9401591d0d8ed6f8 (patch)
treefbe93e7bffe8a65b6f3fa49315b68f50dc48795d /src
parent8463b6d18190fa9a95a6de0c416cd39f740e310a (diff)
parenta54adc82d185722d36a0d1350c3ce80298aa15a4 (diff)
downloadsql-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.php10
-rw-r--r--src/Lexer.php57
-rw-r--r--src/Token.php12
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.