这是Antlr中的词法分析器(对于长文件很抱歉):
lexer grammar SqlServerDialectLexer;
/* T-SQL words */
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';
SELECT: 'SELECT';
SET: 'SET';
SMALLINT: 'SMALLINT';
TABLE: 'TABLE';
THEN: 'THEN';
TINYINT: 'TINYINT';
UPDATE: 'UPDATE';
USE: 'USE';
VALUES: 'VALUES';
VARCHAR: 'VARCHAR';
WHEN: 'WHEN';
WHERE: 'WHERE';
QUOTE: '\'' { textMode = !textMode; };
QUOTED: {textMode}?=> ~('\'')*;
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(); }
;
Run Code Online (Sandbox Code Playgroud)
JDK 1.6说code too large并且无法编译它.为什么以及如何解决问题?
实际上我不会说这是一个很大的语法,并且必须有一个原因,它不能产生合理大小的代码.
我认为问题与此规则直接相关:
QUOTED: {textMode}?=> ~('\'')*;
Run Code Online (Sandbox Code Playgroud)
有没有什么特别的理由让你想把QUOTED部分作为一个单独的标记,而不是把它与引用结合起来,因为Bart还把它放在他的语法中?这也会使textMode变量过时.
删除QUOTE并替换QUOTED
QUOTED: '\'' (~'\'')* '\'';
Run Code Online (Sandbox Code Playgroud)
最有可能解决问题,即使没有拆分语法.
将您的语法分成几个复合语法.小心你放在哪里.例如,您不希望将NAME规则放在top-grammar中,将关键字放入导入的语法中:NAME将"覆盖"匹配的关键字.
这有效:
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(); }
;
Run Code Online (Sandbox Code Playgroud)
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';
Run Code Online (Sandbox Code Playgroud)
编译很好:
java -cp antlr-3.3.jar org.antlr.Tool SqlServerDialectLexer.g
javac -cp antlr-3.3.jar *.java
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,调用org.antlr.Tool"top-lexer"就足够了:ANTLR会自动为导入的语法生成类.如果要导入更多语法,请执行以下操作:
import A, B, C;
Run Code Online (Sandbox Code Playgroud)
冈瑟是正确的:改变QUOTED规则就足够了.我会留下我的答案,因为当你要添加更多关键字,或添加一些解析器规则(SQL语法不可避免)时,你很可能会再次发现"代码太大"的错误.在这种情况下,您可以使用我提出的解决方案.
如果您要接受答案,请接受Gunther's.
| 归档时间: |
|
| 查看次数: |
1931 次 |
| 最近记录: |