@@ -34,13 +34,13 @@ public class ParserKeywordsUtils {
3434 public final static int RESTRICTED_SQL2016 = 64 ;
3535
3636 public final static int RESTRICTED_JSQLPARSER = 128
37- | RESTRICTED_FUNCTION
38- | RESTRICTED_SCHEMA
39- | RESTRICTED_TABLE
40- | RESTRICTED_COLUMN
41- | RESTRICTED_EXPRESSION
42- | RESTRICTED_ALIAS
43- | RESTRICTED_SQL2016 ;
37+ | RESTRICTED_FUNCTION
38+ | RESTRICTED_SCHEMA
39+ | RESTRICTED_TABLE
40+ | RESTRICTED_COLUMN
41+ | RESTRICTED_EXPRESSION
42+ | RESTRICTED_ALIAS
43+ | RESTRICTED_SQL2016 ;
4444
4545
4646 // Classification follows http://www.h2database.com/html/advanced.html#keywords
@@ -238,14 +238,22 @@ public static TreeSet<String> getAllKeywordsUsingRegex(File file) throws IOExcep
238238 Pattern tokenBlockPattern = Pattern .compile (
239239 "TOKEN\\ s*:\\ s*/\\ *.*\\ */*(?:\\ r?\\ n|\\ r)\\ {(?:[^}{]+|\\ {(?:[^}{]+|\\ {[^}{]*})*})*}" ,
240240 Pattern .MULTILINE );
241+
242+ // Also match the NonReservedWord() BNF production which contains
243+ // inline token declarations after the token restructuring
244+ Pattern nonReservedWordPattern = Pattern .compile (
245+ "String\\ s+NonReservedWord\\ s*\\ (\\ s*\\ )\\ s*:\\ s*\\ {(?:[^}{]+|\\ {(?:[^}{]+|\\ {[^}{]*})*})*}\\ s*\\ {(?:[^}{]+|\\ {(?:[^}{]+|\\ {[^}{]*})*})*}" ,
246+ Pattern .MULTILINE );
247+
241248 Pattern tokenStringValuePattern = Pattern .compile ("\" (\\ w{2,})\" " , Pattern .MULTILINE );
242249
243250 TreeSet <String > allKeywords = new TreeSet <>();
244251
245252 Path path = file .toPath ();
246253 Charset charset = Charset .defaultCharset ();
247- String content = new String ( Files .readAllBytes (path ) , charset );
254+ String content = Files .readString (path , charset );
248255
256+ // Scan TOKEN blocks (reserved keywords, operators, data types)
249257 Matcher tokenBlockmatcher = tokenBlockPattern .matcher (content );
250258 while (tokenBlockmatcher .find ()) {
251259 String tokenBlock = tokenBlockmatcher .group (0 );
@@ -266,6 +274,25 @@ public static TreeSet<String> getAllKeywordsUsingRegex(File file) throws IOExcep
266274 }
267275 }
268276 }
277+
278+ // Scan NonReservedWord() BNF production (inline token declarations)
279+ Matcher nonReservedMatcher = nonReservedWordPattern .matcher (content );
280+ while (nonReservedMatcher .find ()) {
281+ String block = nonReservedMatcher .group (0 );
282+ for (String tokenDefinition : getTokenDefinitions (block )) {
283+ if (tokenDefinition .matches ("(?sm)^<\\ s*[^#].*" )) {
284+ Matcher tokenStringValueMatcher =
285+ tokenStringValuePattern .matcher (tokenDefinition );
286+ while (tokenStringValueMatcher .find ()) {
287+ String tokenValue = tokenStringValueMatcher .group (1 );
288+ if (CHARSET_ENCODER .canEncode (tokenValue ) && tokenValue .matches ("\\ w+" )) {
289+ allKeywords .add (tokenValue );
290+ }
291+ }
292+ }
293+ }
294+ }
295+
269296 return allKeywords ;
270297 }
271298
@@ -331,11 +358,11 @@ public static void buildGrammarForRelObjectNameWithoutValue(File file) throws Ex
331358
332359 StringBuilder builder = new StringBuilder ();
333360 builder .append ("String RelObjectNameWithoutValue() :\n "
334- + "{ Token tk = null; }\n "
335- + "{\n "
336- // @todo: find a way to avoid those hardcoded compound tokens
337- + " ( tk=<DATA_TYPE> | tk=<S_IDENTIFIER> | tk=<S_QUOTED_IDENTIFIER> | tk=<K_DATE_LITERAL> | tk=<K_DATETIMELITERAL> | tk=<K_STRING_FUNCTION_NAME> | tk=<K_ISOLATION> | tk=<K_TIME_KEY_EXPR> | tk=<K_TEXT_LITERAL> \n "
338- + " " );
361+ + "{ Token tk = null; }\n "
362+ + "{\n "
363+ // @todo: find a way to avoid those hardcoded compound tokens
364+ + " ( tk=<DATA_TYPE> | tk=<S_IDENTIFIER> | tk=<S_QUOTED_IDENTIFIER> | tk=<K_DATE_LITERAL> | tk=<K_DATETIMELITERAL> | tk=<K_STRING_FUNCTION_NAME> | tk=<K_ISOLATION> | tk=<K_TIME_KEY_EXPR> | tk=<K_TEXT_LITERAL> \n "
365+ + " " );
339366
340367 for (String keyword : allKeywords ) {
341368 builder .append (" | tk=\" " ).append (keyword ).append ("\" " );
@@ -361,10 +388,10 @@ public static void buildGrammarForRelObjectName(File file) throws Exception {
361388
362389 StringBuilder builder = new StringBuilder ();
363390 builder .append ("String RelObjectName() :\n "
364- + "{ Token tk = null; String result = null; }\n "
365- + "{\n "
366- + " (result = RelObjectNameWithoutValue()\n "
367- + " " );
391+ + "{ Token tk = null; String result = null; }\n "
392+ + "{\n "
393+ + " (result = RelObjectNameWithoutValue()\n "
394+ + " " );
368395
369396 for (String keyword : allKeywords ) {
370397 builder .append (" | tk=\" " ).append (keyword ).append ("\" " );
@@ -411,19 +438,19 @@ public static void writeKeywordsDocumentationFile(File file) throws IOException
411438
412439 for (Object [] keywordDefinition : ALL_RESERVED_KEYWORDS ) {
413440 builder .append ("| " ).append (rightPadding (keywordDefinition [0 ].toString (), ' ' , 20 ))
414- .append (" | " );
441+ .append (" | " );
415442
416443 int value = (int ) keywordDefinition [1 ];
417444 int restriction = RESTRICTED_JSQLPARSER ;
418445 String s = (value & restriction ) == restriction || (restriction & value ) == value
419- ? "Yes"
420- : "" ;
446+ ? "Yes"
447+ : "" ;
421448 builder .append (rightPadding (s , ' ' , 11 )).append (" | " );
422449
423450 restriction = RESTRICTED_SQL2016 ;
424451 s = (value & restriction ) == restriction || (restriction & value ) == value
425- ? "Yes"
426- : "" ;
452+ ? "Yes"
453+ : "" ;
427454 builder .append (rightPadding (s , ' ' , 9 )).append (" | " );
428455
429456 builder .append ("\n " );
@@ -434,4 +461,4 @@ public static void writeKeywordsDocumentationFile(File file) throws IOException
434461 fileWriter .flush ();
435462 }
436463 }
437- }
464+ }
0 commit comments