Skip to content

Commit dc34999

Browse files
committed
Generate context files with Token const instead of hard-coded numbers.
1 parent c661e3a commit dc34999

File tree

2 files changed

+60
-76
lines changed

2 files changed

+60
-76
lines changed

src/Token.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ class Token
129129
// Flags that describe the tokens in more detail.
130130
// All keywords must have flag 1 so `Context::isKeyword` method doesn't
131131
// require strict comparison.
132+
public const FLAG_KEYWORD = 1;
132133
public const FLAG_KEYWORD_RESERVED = 2;
133134
public const FLAG_KEYWORD_COMPOSED = 4;
134135
public const FLAG_KEYWORD_DATA_TYPE = 8;

src/Tools/ContextGenerator.php

Lines changed: 59 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace PhpMyAdmin\SqlParser\Tools;
66

7+
use PhpMyAdmin\SqlParser\Token;
8+
79
use function array_map;
810
use function array_merge;
911
use function array_slice;
@@ -15,11 +17,9 @@
1517
use function implode;
1618
use function ksort;
1719
use function preg_match;
18-
use function round;
1920
use function scandir;
2021
use function sort;
2122
use function sprintf;
22-
use function str_repeat;
2323
use function str_replace;
2424
use function str_split;
2525
use function strlen;
@@ -43,10 +43,10 @@ class ContextGenerator
4343
* @var array<string, int>
4444
*/
4545
public static $LABELS_FLAGS = [
46-
'(R)' => 2, // reserved
47-
'(D)' => 8, // data type
48-
'(K)' => 16, // keyword
49-
'(F)' => 32, // function name
46+
'(R)' => Token::FLAG_KEYWORD_RESERVED,
47+
'(D)' => Token::FLAG_KEYWORD_DATA_TYPE,
48+
'(K)' => Token::FLAG_KEYWORD_KEY,
49+
'(F)' => Token::FLAG_KEYWORD_FUNCTION,
5050
];
5151

5252
/**
@@ -83,6 +83,20 @@ class ContextGenerator
8383
'MariaDb110400' => 'https://mariadb.com/kb/en/reserved-words/',
8484
];
8585

86+
/**
87+
* Reversed const <=> int from {@see Token} class to write the constant name instead of its value.
88+
*
89+
* @var array<int, string>
90+
*/
91+
private static $typesNumToConst = [
92+
1 => 'Token::FLAG_KEYWORD',
93+
2 => 'Token::FLAG_KEYWORD_RESERVED',
94+
4 => 'Token::FLAG_KEYWORD_COMPOSED',
95+
8 => 'Token::FLAG_KEYWORD_DATA_TYPE',
96+
16 => 'Token::FLAG_KEYWORD_KEY',
97+
32 => 'Token::FLAG_KEYWORD_FUNCTION',
98+
];
99+
86100
/**
87101
* The template of a context.
88102
*
@@ -117,9 +131,7 @@ class %2$s extends Context
117131
*
118132
* The value associated to each keyword represents its flags.
119133
*
120-
* @see Token::FLAG_KEYWORD_RESERVED Token::FLAG_KEYWORD_COMPOSED
121-
* Token::FLAG_KEYWORD_DATA_TYPE Token::FLAG_KEYWORD_KEY
122-
* Token::FLAG_KEYWORD_FUNCTION
134+
* @see Token
123135
*
124136
* @var array<string,int>
125137
* @phpstan-var non-empty-array<non-empty-string,Token::FLAG_KEYWORD_*|int>
@@ -140,12 +152,9 @@ class %2$s extends Context
140152
public static function sortWords(array &$arr)
141153
{
142154
ksort($arr);
143-
foreach ($arr as &$wordsByLen) {
144-
ksort($wordsByLen);
145-
foreach ($wordsByLen as &$words) {
146-
sort($words, SORT_STRING);
147-
}
148-
}
155+
foreach ($arr as &$words) {
156+
sort($words, SORT_STRING);
157+
} unset($words);
149158

150159
return $arr;
151160
}
@@ -159,17 +168,23 @@ public static function sortWords(array &$arr)
159168
*/
160169
public static function readWords(array $files)
161170
{
162-
$words = [];
163-
foreach ($files as $file) {
164-
$words = array_merge($words, file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES));
165-
}
171+
$wordsByFile = array_map(
172+
static function (string $file): array {
173+
return file($file, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
174+
},
175+
$files
176+
);
177+
$words = array_merge(...$wordsByFile);
166178

167179
/** @var array<string, int> $types */
168180
$types = [];
169181

170182
for ($i = 0, $count = count($words); $i !== $count; ++$i) {
171-
$type = 1;
172183
$value = trim($words[$i]);
184+
if ($value === '') {
185+
continue;
186+
}
187+
$type = Token::FLAG_KEYWORD;
173188

174189
// Reserved, data types, keys, functions, etc. keywords.
175190
foreach (static::$LABELS_FLAGS as $label => $flags) {
@@ -183,13 +198,8 @@ public static function readWords(array $files)
183198

184199
// Composed keyword.
185200
if (strstr($value, ' ') !== false) {
186-
$type |= 2; // Reserved keyword.
187-
$type |= 4; // Composed keyword.
188-
}
189-
190-
$len = strlen($words[$i]);
191-
if ($len === 0) {
192-
continue;
201+
$type |= Token::FLAG_KEYWORD_RESERVED;
202+
$type |= Token::FLAG_KEYWORD_COMPOSED;
193203
}
194204

195205
$value = strtoupper($value);
@@ -200,18 +210,10 @@ public static function readWords(array $files)
200210
}
201211
}
202212

213+
// Prepare an array in a way to sort by type, then by word.
203214
$ret = [];
204215
foreach ($types as $word => $type) {
205-
$len = strlen($word);
206-
if (! isset($ret[$type])) {
207-
$ret[$type] = [];
208-
}
209-
210-
if (! isset($ret[$type][$len])) {
211-
$ret[$type][$len] = [];
212-
}
213-
214-
$ret[$type][$len][] = $word;
216+
$ret[$type][] = $word;
215217
}
216218

217219
return static::sortWords($ret);
@@ -220,53 +222,34 @@ public static function readWords(array $files)
220222
/**
221223
* Prints an array of a words in PHP format.
222224
*
223-
* @param array<int, array<int, array<int, string>>> $words the list of words to be formatted
224-
* @param int $spaces the number of spaces that starts every line
225-
* @param int $line the length of a line
226-
*
227-
* @return string
225+
* @param array<int, list<string>> $words the list of words to be formatted
228226
*/
229-
public static function printWords($words, $spaces = 8, $line = 140)
227+
public static function printWords(array $words): string
230228
{
231-
$typesCount = count($words);
232229
$ret = '';
233-
$j = 0;
234-
235230
foreach ($words as $type => $wordsByType) {
236-
foreach ($wordsByType as $len => $wordsByLen) {
237-
$count = round(($line - $spaces) / ($len + 9)); // strlen("'' => 1, ") = 9
238-
$i = 0;
239-
240-
foreach ($wordsByLen as $word) {
241-
if ($i === 0) {
242-
$ret .= str_repeat(' ', $spaces);
243-
}
244-
245-
$ret .= sprintf('\'%s\' => %s, ', $word, $type);
246-
if (++$i !== $count && ++$i <= $count) {
247-
continue;
248-
}
249-
250-
$ret .= "\n";
251-
$i = 0;
252-
}
253-
254-
if ($i === 0) {
255-
continue;
256-
}
257-
258-
$ret .= "\n";
231+
foreach ($wordsByType as $word) {
232+
$ret .= sprintf(" '%s' => %s,\n", $word, self::numTypeToConst($type));
259233
}
234+
}
235+
return $ret;
236+
}
260237

261-
if (++$j >= $typesCount) {
262-
continue;
238+
/**
239+
* Convert a numeric value representing a set of const to a textual const value.
240+
*
241+
* @param int $type The numeric value.
242+
* @return string The text to write considering the given numeric value.
243+
*/
244+
private static function numTypeToConst(int $type): string
245+
{
246+
$matchingFlags = [];
247+
foreach (self::$typesNumToConst as $num => $value) {
248+
if ($type & $num) {
249+
$matchingFlags[] = $value;
263250
}
264-
265-
$ret .= "\n";
266251
}
267-
268-
// Trim trailing spaces and return.
269-
return str_replace(" \n", "\n", $ret);
252+
return implode(' | ', $matchingFlags);
270253
}
271254

272255
/**

0 commit comments

Comments
 (0)