|
28 | 28 | */ |
29 | 29 | class Lexer extends Core |
30 | 30 | { |
31 | | - /** |
32 | | - * A list of methods that are used in lexing the SQL query. |
33 | | - */ |
34 | | - private const PARSER_METHODS = [ |
35 | | - // It is best to put the parsers in order of their complexity |
36 | | - // (ascending) and their occurrence rate (descending). |
37 | | - // |
38 | | - // Conflicts: |
39 | | - // |
40 | | - // 1. `parseDelimiter`, `parseUnknown`, `parseKeyword`, `parseNumber` |
41 | | - // They fight over delimiter. The delimiter may be a keyword, a |
42 | | - // number or almost any character which makes the delimiter one of |
43 | | - // the first tokens that must be parsed. |
44 | | - // |
45 | | - // 1. `parseNumber` and `parseOperator` |
46 | | - // They fight over `+` and `-`. |
47 | | - // |
48 | | - // 2. `parseComment` and `parseOperator` |
49 | | - // They fight over `/` (as in ```/*comment*/``` or ```a / b```) |
50 | | - // |
51 | | - // 3. `parseBool` and `parseKeyword` |
52 | | - // They fight over `TRUE` and `FALSE`. |
53 | | - // |
54 | | - // 4. `parseKeyword` and `parseUnknown` |
55 | | - // They fight over words. `parseUnknown` does not know about |
56 | | - // keywords. |
57 | | - |
58 | | - 'parseDelimiter', |
59 | | - 'parseWhitespace', |
60 | | - 'parseNumber', |
61 | | - 'parseComment', |
62 | | - 'parseOperator', |
63 | | - 'parseBool', |
64 | | - 'parseString', |
65 | | - 'parseSymbol', |
66 | | - 'parseKeyword', |
67 | | - 'parseLabel', |
68 | | - 'parseUnknown', |
69 | | - ]; |
70 | | - |
71 | 31 | /** |
72 | 32 | * A list of keywords that indicate that the function keyword |
73 | 33 | * is not used as a function |
@@ -203,26 +163,11 @@ public function lex(): void |
203 | 163 |
|
204 | 164 | /** |
205 | 165 | * Last processed token. |
206 | | - * |
207 | | - * @var Token |
208 | 166 | */ |
209 | 167 | $lastToken = null; |
210 | 168 |
|
211 | 169 | for ($this->last = 0, $lastIdx = 0; $this->last < $this->len; $lastIdx = ++$this->last) { |
212 | | - /** |
213 | | - * The new token. |
214 | | - * |
215 | | - * @var Token |
216 | | - */ |
217 | | - $token = null; |
218 | | - |
219 | | - foreach (self::PARSER_METHODS as $method) { |
220 | | - $token = $this->$method(); |
221 | | - |
222 | | - if ($token) { |
223 | | - break; |
224 | | - } |
225 | | - } |
| 170 | + $token = $this->parse(); |
226 | 171 |
|
227 | 172 | if ($token === null) { |
228 | 173 | // @assert($this->last === $lastIdx); |
@@ -1043,4 +988,42 @@ public function parseDelimiter(): Token|null |
1043 | 988 |
|
1044 | 989 | return new Token($this->delimiter, TokenType::Delimiter); |
1045 | 990 | } |
| 991 | + |
| 992 | + private function parse(): Token|null |
| 993 | + { |
| 994 | + // It is best to put the parsers in order of their complexity |
| 995 | + // (ascending) and their occurrence rate (descending). |
| 996 | + // |
| 997 | + // Conflicts: |
| 998 | + // |
| 999 | + // 1. `parseDelimiter`, `parseUnknown`, `parseKeyword`, `parseNumber` |
| 1000 | + // They fight over delimiter. The delimiter may be a keyword, a |
| 1001 | + // number or almost any character which makes the delimiter one of |
| 1002 | + // the first tokens that must be parsed. |
| 1003 | + // |
| 1004 | + // 1. `parseNumber` and `parseOperator` |
| 1005 | + // They fight over `+` and `-`. |
| 1006 | + // |
| 1007 | + // 2. `parseComment` and `parseOperator` |
| 1008 | + // They fight over `/` (as in ```/*comment*/``` or ```a / b```) |
| 1009 | + // |
| 1010 | + // 3. `parseBool` and `parseKeyword` |
| 1011 | + // They fight over `TRUE` and `FALSE`. |
| 1012 | + // |
| 1013 | + // 4. `parseKeyword` and `parseUnknown` |
| 1014 | + // They fight over words. `parseUnknown` does not know about |
| 1015 | + // keywords. |
| 1016 | + |
| 1017 | + return $this->parseDelimiter() |
| 1018 | + ?? $this->parseWhitespace() |
| 1019 | + ?? $this->parseNumber() |
| 1020 | + ?? $this->parseComment() |
| 1021 | + ?? $this->parseOperator() |
| 1022 | + ?? $this->parseBool() |
| 1023 | + ?? $this->parseString() |
| 1024 | + ?? $this->parseSymbol() |
| 1025 | + ?? $this->parseKeyword() |
| 1026 | + ?? $this->parseLabel() |
| 1027 | + ?? $this->parseUnknown(); |
| 1028 | + } |
1046 | 1029 | } |
0 commit comments