Разделите вашу грамматику на несколько составных грамматик .Будьте осторожны, где вы размещаете.Например, вы не хотите помещать правило NAME
в свою топ-грамматику и ключевые слова в импортированную грамматику: NAME
"перезапишет" ключевые слова из совпадения.
Это работает:
Ag
lexer grammar A;
SELECT: 'SELECT';
SET: 'SET';
SMALLINT: 'SMALLINT';
TABLE: 'TABLE';
THEN: 'THEN';
TINYINT: 'TINYINT';
UPDATE: 'UPDATE';
USE: 'USE';
VALUES: 'VALUES';
VARCHAR: 'VARCHAR';
WHEN: 'WHEN';
WHERE: 'WHERE';
QUOTED: '\'' ('\'\'' | ~'\'')* '\'';
EQUALS: '=';
NOT_EQUALS: '!=';
SEMICOLON: ';';
COMMA: ',';
OPEN: '(';
CLOSE: ')';
VARIABLE: '@' NAME;
NAME:
( LETTER | '#' | '_' ) ( LETTER | NUMBER | '#' | '_' | '.' )*
;
NUMBER: DIGIT+;
fragment LETTER: 'a'..'z' | 'A'..'Z';
fragment DIGIT: '0'..'9';
SPACE
:
( ' ' | '\t' | '\n' | '\r' )+
{ skip(); }
;
SqlServerDialectLexer.g
lexer grammar SqlServerDialectLexer;
import A;
AND: 'AND';
BIGINT: 'BIGINT';
BIT: 'BIT';
CASE: 'CASE';
CHAR: 'CHAR';
COUNT: 'COUNT';
CREATE: 'CREATE';
CURRENT_TIMESTAMP: 'CURRENT_TIMESTAMP';
DATETIME: 'DATETIME';
DECLARE: 'DECLARE';
ELSE: 'ELSE';
END: 'END';
FLOAT: 'FLOAT';
FROM: 'FROM';
GO: 'GO';
IMAGE: 'IMAGE';
INNER: 'INNER';
INSERT: 'INSERT';
INT: 'INT';
INTO: 'INTO';
IS: 'IS';
JOIN: 'JOIN';
NOT: 'NOT';
NULL: 'NULL';
NUMERIC: 'NUMERIC';
NVARCHAR: 'NVARCHAR';
ON: 'ON';
OR: 'OR';
И он прекрасно компилируется:
java -cp antlr-3.3.jar org.antlr.Tool SqlServerDialectLexer.g
javac -cp antlr-3.3.jar *.java
Как видите, вызывая org.antlr.Tool
на вашем "top-lexer" достаточно: ANTLR автоматически генерирует классы для импортированной грамматики.Если вам нужно импортировать больше грамматик, сделайте это следующим образом:
import A, B, C;
EDIT
Гюнтер прав: достаточно изменить правило QUOTED
.Я оставлю свой ответ, потому что, когда вы собираетесь добавить больше ключевых слов или добавить довольно много правил синтаксического анализа (неизбежно для грамматик SQL), вы, скорее всего, снова наткнетесь на ошибку «слишком большой код».В этом случае вы можете использовать предложенное мной решение.
Если вы собираетесь принять ответ, пожалуйста, примите решение Гюнтера.