summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDeven Bansod <devenbansod.bits@gmail.com>2016-10-25 19:29:15 +0530
committerDeven Bansod <devenbansod.bits@gmail.com>2016-10-25 19:29:15 +0530
commit94e550e4a9b359332bab257a5f4aa6dfb8e48ea7 (patch)
tree333f35e531cd1f18011e95bc6f1c974adae7b096 /src
parentc70914ac7e54904bb7e0ed0e3a9511481f69168d (diff)
parentdccefe437ad94182a22376807950b7bf5e0b9a47 (diff)
downloadsql-parser-94e550e4a9b359332bab257a5f4aa6dfb8e48ea7.zip
sql-parser-94e550e4a9b359332bab257a5f4aa6dfb8e48ea7.tar.gz
sql-parser-94e550e4a9b359332bab257a5f4aa6dfb8e48ea7.tar.bz2
Merge branch 'master' of https://github.com/phpmyadmin/sql-parser
Diffstat (limited to 'src')
-rw-r--r--src/Components/JoinKeyword.php20
-rw-r--r--src/Context.php10
-rw-r--r--src/Contexts/ContextMySql50000.php15
-rw-r--r--src/Contexts/ContextMySql50100.php15
-rw-r--r--src/Contexts/ContextMySql50500.php15
-rw-r--r--src/Contexts/ContextMySql50600.php15
-rw-r--r--src/Contexts/ContextMySql50700.php15
-rw-r--r--src/Lexer.php57
-rw-r--r--src/Parser.php22
-rw-r--r--src/Statements/SelectStatement.php49
-rw-r--r--src/Token.php12
11 files changed, 184 insertions, 61 deletions
diff --git a/src/Components/JoinKeyword.php b/src/Components/JoinKeyword.php
index 7062783..548a64e 100644
--- a/src/Components/JoinKeyword.php
+++ b/src/Components/JoinKeyword.php
@@ -30,6 +30,7 @@ class JoinKeyword extends Component
* @var array
*/
public static $JOINS = array(
+ 'CROSS JOIN' => 'CROSS',
'FULL JOIN' => 'FULL',
'FULL OUTER JOIN' => 'FULL',
'INNER JOIN' => 'INNER',
@@ -38,6 +39,12 @@ class JoinKeyword extends Component
'LEFT OUTER JOIN' => 'LEFT',
'RIGHT JOIN' => 'RIGHT',
'RIGHT OUTER JOIN' => 'RIGHT',
+ 'NATURAL JOIN' => 'NATURAL',
+ 'NATURAL LEFT JOIN' => 'NATURAL LEFT',
+ 'NATURAL LEFT JOIN' => 'NATURAL LEFT',
+ 'NATURAL RIGHT JOIN' => 'NATURAL RIGHT',
+ 'NATURAL LEFT OUTER JOIN' => 'NATURAL LEFT OUTER',
+ 'NATURAL RIGHT OUTER JOIN' => 'NATURAL RIGHT OUTER',
'STRAIGHT_JOIN' => 'STRAIGHT',
);
@@ -147,8 +154,17 @@ class JoinKeyword extends Component
} elseif ($token->value === 'USING') {
$state = 4;
} else {
- /* Next clause is starting */
- break;
+ if (($token->type === Token::TYPE_KEYWORD)
+ && (!empty(static::$JOINS[$token->value]))
+ ) {
+ $ret[] = $expr;
+ $expr = new JoinKeyword();
+ $expr->type = static::$JOINS[$token->value];
+ $state = 1;
+ } else {
+ /* Next clause is starting */
+ break;
+ }
}
}
} elseif ($state === 3) {
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/Contexts/ContextMySql50000.php b/src/Contexts/ContextMySql50000.php
index 4931faa..f8afd18 100644
--- a/src/Contexts/ContextMySql50000.php
+++ b/src/Contexts/ContextMySql50000.php
@@ -145,20 +145,21 @@ class ContextMySql50000 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
- 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7,
- 'RIGHT JOIN' => 7,
+ 'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
+ 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
- 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7,
- 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
+ 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
+ 'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
- 'START TRANSACTION' => 7,
- 'SELECT TRANSACTION' => 7,
+ 'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
+ 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
- 'WITH CONSISTENT SNAPSHOT' => 7,
+ 'NATURAL LEFT OUTER JOIN' => 7,
+ 'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,
'BIT' => 9, 'XML' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
diff --git a/src/Contexts/ContextMySql50100.php b/src/Contexts/ContextMySql50100.php
index a547e64..dd2b677 100644
--- a/src/Contexts/ContextMySql50100.php
+++ b/src/Contexts/ContextMySql50100.php
@@ -159,20 +159,21 @@ class ContextMySql50100 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
- 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7,
- 'RIGHT JOIN' => 7,
+ 'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
+ 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
- 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7,
- 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
+ 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
+ 'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
- 'START TRANSACTION' => 7,
- 'SELECT TRANSACTION' => 7,
+ 'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
+ 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
- 'WITH CONSISTENT SNAPSHOT' => 7,
+ 'NATURAL LEFT OUTER JOIN' => 7,
+ 'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,
'BIT' => 9, 'XML' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
diff --git a/src/Contexts/ContextMySql50500.php b/src/Contexts/ContextMySql50500.php
index a15744a..02acdac 100644
--- a/src/Contexts/ContextMySql50500.php
+++ b/src/Contexts/ContextMySql50500.php
@@ -163,20 +163,21 @@ class ContextMySql50500 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
- 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7,
- 'RIGHT JOIN' => 7,
+ 'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
+ 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
- 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7,
- 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
+ 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
+ 'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
- 'START TRANSACTION' => 7,
- 'SELECT TRANSACTION' => 7,
+ 'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
+ 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
- 'WITH CONSISTENT SNAPSHOT' => 7,
+ 'NATURAL LEFT OUTER JOIN' => 7,
+ 'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,
'BIT' => 9, 'XML' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
diff --git a/src/Contexts/ContextMySql50600.php b/src/Contexts/ContextMySql50600.php
index 7a0cf56..1143978 100644
--- a/src/Contexts/ContextMySql50600.php
+++ b/src/Contexts/ContextMySql50600.php
@@ -169,20 +169,21 @@ class ContextMySql50600 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
- 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7,
- 'RIGHT JOIN' => 7,
+ 'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
+ 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
- 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7,
- 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
+ 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
+ 'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
- 'START TRANSACTION' => 7,
- 'SELECT TRANSACTION' => 7,
+ 'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
+ 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
- 'WITH CONSISTENT SNAPSHOT' => 7,
+ 'NATURAL LEFT OUTER JOIN' => 7,
+ 'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,
'BIT' => 9, 'XML' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
diff --git a/src/Contexts/ContextMySql50700.php b/src/Contexts/ContextMySql50700.php
index 8682032..04f410b 100644
--- a/src/Contexts/ContextMySql50700.php
+++ b/src/Contexts/ContextMySql50700.php
@@ -175,20 +175,21 @@ class ContextMySql50700 extends Context
'AND CHAIN' => 7, 'FULL JOIN' => 7, 'IF EXISTS' => 7, 'LEFT JOIN' => 7,
'LESS THAN' => 7, 'NO ACTION' => 7, 'ON DELETE' => 7, 'ON UPDATE' => 7,
'UNION ALL' => 7,
- 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7, 'OR REPLACE' => 7,
- 'RIGHT JOIN' => 7,
+ 'CROSS JOIN' => 7, 'INNER JOIN' => 7, 'LINEAR KEY' => 7, 'NO RELEASE' => 7,
+ 'OR REPLACE' => 7, 'RIGHT JOIN' => 7,
'LINEAR HASH' => 7,
- 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'PARTITION BY' => 7,
- 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
+ 'AND NO CHAIN' => 7, 'FOR EACH ROW' => 7, 'NATURAL JOIN' => 7,
+ 'PARTITION BY' => 7, 'SET PASSWORD' => 7, 'SQL SECURITY' => 7,
'CHARACTER SET' => 7, 'IF NOT EXISTS' => 7,
'DATA DIRECTORY' => 7, 'UNION DISTINCT' => 7,
'DEFAULT CHARSET' => 7, 'DEFAULT COLLATE' => 7, 'FULL OUTER JOIN' => 7,
'INDEX DIRECTORY' => 7, 'LEFT OUTER JOIN' => 7, 'SUBPARTITION BY' => 7,
'GENERATED ALWAYS' => 7, 'RIGHT OUTER JOIN' => 7,
- 'START TRANSACTION' => 7,
- 'SELECT TRANSACTION' => 7,
+ 'NATURAL LEFT JOIN' => 7, 'START TRANSACTION' => 7,
+ 'NATURAL RIGHT JOIN' => 7, 'SELECT TRANSACTION' => 7,
'DEFAULT CHARACTER SET' => 7,
- 'WITH CONSISTENT SNAPSHOT' => 7,
+ 'NATURAL LEFT OUTER JOIN' => 7,
+ 'NATURAL RIGHT OUTER JOIN' => 7, 'WITH CONSISTENT SNAPSHOT' => 7,
'BIT' => 9, 'XML' => 9,
'ENUM' => 9, 'JSON' => 9, 'TEXT' => 9,
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/Parser.php b/src/Parser.php
index 21e1b39..0d48a41 100644
--- a/src/Parser.php
+++ b/src/Parser.php
@@ -154,6 +154,10 @@ class Parser
'field' => 'tables',
'options' => array('parseField' => 'table'),
),
+ 'CROSS JOIN' => array(
+ 'class' => 'SqlParser\\Components\\JoinKeyword',
+ 'field' => 'join',
+ ),
'DROP' => array(
'class' => 'SqlParser\\Components\\ExpressionArray',
'field' => 'fields',
@@ -213,7 +217,23 @@ class Parser
'class' => 'SqlParser\\Components\\JoinKeyword',
'field' => 'join',
),
- 'STRAIGHT_JOIN' => array(
+ 'NATURAL JOIN' => array(
+ 'class' => 'SqlParser\\Components\\JoinKeyword',
+ 'field' => 'join',
+ ),
+ 'NATURAL LEFT JOIN' => array(
+ 'class' => 'SqlParser\\Components\\JoinKeyword',
+ 'field' => 'join',
+ ),
+ 'NATURAL RIGHT JOIN' => array(
+ 'class' => 'SqlParser\\Components\\JoinKeyword',
+ 'field' => 'join',
+ ),
+ 'NATURAL LEFT OUTER JOIN' => array(
+ 'class' => 'SqlParser\\Components\\JoinKeyword',
+ 'field' => 'join',
+ ),
+ 'NATURAL RIGHT OUTER JOIN' => array(
'class' => 'SqlParser\\Components\\JoinKeyword',
'field' => 'join',
),
diff --git a/src/Statements/SelectStatement.php b/src/Statements/SelectStatement.php
index 34a68c3..8ff0b45 100644
--- a/src/Statements/SelectStatement.php
+++ b/src/Statements/SelectStatement.php
@@ -82,30 +82,35 @@ class SelectStatement extends Statement
* @var array
*/
public static $CLAUSES = array(
- 'SELECT' => array('SELECT', 2),
+ 'SELECT' => array('SELECT', 2),
// Used for options.
- '_OPTIONS' => array('_OPTIONS', 1),
+ '_OPTIONS' => array('_OPTIONS', 1),
// Used for selected expressions.
- '_SELECT' => array('SELECT', 1),
- 'INTO' => array('INTO', 3),
- 'FROM' => array('FROM', 3),
- 'PARTITION' => array('PARTITION', 3),
-
- 'JOIN' => array('JOIN', 1),
- 'FULL JOIN' => array('FULL JOIN', 1),
- 'INNER JOIN' => array('INNER JOIN', 1),
- 'LEFT JOIN' => array('LEFT JOIN', 1),
- 'LEFT OUTER JOIN' => array('LEFT OUTER JOIN', 1),
- 'RIGHT JOIN' => array('RIGHT JOIN', 1),
- 'RIGHT OUTER JOIN' => array('RIGHT OUTER JOIN', 1),
-
- 'WHERE' => array('WHERE', 3),
- 'GROUP BY' => array('GROUP BY', 3),
- 'HAVING' => array('HAVING', 3),
- 'ORDER BY' => array('ORDER BY', 3),
- 'LIMIT' => array('LIMIT', 3),
- 'PROCEDURE' => array('PROCEDURE', 3),
- 'UNION' => array('UNION', 1),
+ '_SELECT' => array('SELECT', 1),
+ 'INTO' => array('INTO', 3),
+ 'FROM' => array('FROM', 3),
+ 'PARTITION' => array('PARTITION', 3),
+
+ 'JOIN' => array('JOIN', 1),
+ 'FULL JOIN' => array('FULL JOIN', 1),
+ 'INNER JOIN' => array('INNER JOIN', 1),
+ 'LEFT JOIN' => array('LEFT JOIN', 1),
+ 'LEFT OUTER JOIN' => array('LEFT OUTER JOIN', 1),
+ 'RIGHT JOIN' => array('RIGHT JOIN', 1),
+ 'RIGHT OUTER JOIN' => array('RIGHT OUTER JOIN', 1),
+ 'NATURAL JOIN' => array('NATURAL JOIN', 1),
+ 'NATURAL LEFT JOIN' => array('NATURAL LEFT JOIN', 1),
+ 'NATURAL RIGHT JOIN' => array('NATURAL RIGHT JOIN', 1),
+ 'NATURAL LEFT OUTER JOIN' => array('NATURAL LEFT OUTER JOIN', 1),
+ 'NATURAL RIGHT OUTER JOIN' => array('NATURAL RIGHT JOIN', 1),
+
+ 'WHERE' => array('WHERE', 3),
+ 'GROUP BY' => array('GROUP BY', 3),
+ 'HAVING' => array('HAVING', 3),
+ 'ORDER BY' => array('ORDER BY', 3),
+ 'LIMIT' => array('LIMIT', 3),
+ 'PROCEDURE' => array('PROCEDURE', 3),
+ 'UNION' => array('UNION', 1),
// These are available only when `UNION` is present.
// 'ORDER BY' => array('ORDER BY', 3),
// 'LIMIT' => array('LIMIT', 3),
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.