如果我有一个测试语法TestGrammar.g4,
grammar TestGrammar;
startRule : compilationUnit EOF;
compilationUnit
: programUnit*
;
programUnit
: execSqlStatement
;
execSqlStatement
: EXEC SQL EXECSQLLINE+ END_EXEC DOT?
;
freeText
//: ~NL*
: STRING+
;
EXECSQLLINE : EXECSQLTAG WS ~('n' | 'r' | '}')* ('n' | 'r' | '}');
EXECSQLTAG : '*>EXECSQL';
END_EXEC : E N D '-' E X E C;
EXEC : E X E C;
SQL : S Q L;
// symbols
STRING : .+?;
NL : 'r'? 'n' | 'r';
//NEWLINE : 'r'? 'n' -> channel(HIDDEN);
DOT : '.';
WS : [ tf;]+ -> channel(HIDDEN);
输入一个简单的文本,
const input = `
EXEC SQL
somethig goes here
END-EXEC.
`
如果我运行这些数据,我得到了抽象语法树(AST(,它似乎没有被完全解析,
programUnit
(
execSqlStatement EXEC SQL n s o m e t h i g g o e s h e r e n s o m e t h i g g o e s h e r e n END-EXEC
)
预期输出为
(
startRule
(
compilationUnit
(
programUnit
(
execSqlStatement EXEC SQL
(
freeText
(
something goes here
)
)
(
END EXEC
)
)
)
)
)
因为它必须解析CCD_ 1内部的内容,而我无法检索到这些内容。提前感谢
这里有几件事:
- ANTLR4不生成语法树(AST(,而是解析树。AST是由以(或多或少(树状方式匹配的输入符号组成的。解析树由解析上下文节点组成,这些节点描述语法中匹配的路径。它们还包含匹配的符号,所以它们有点像AST的超集
- 你的语法不完整,例如,它错过了规则
S
、Q
、E
、X
等的定义。问题中的例子应该是自包含的,并且可以在没有额外调整的情况下进行转换 - 您从不使用您的规则
freeText
。那么它如何对产出做出贡献呢 - 您将整个SQL代码编码到单个lexer规则
EXECSQLLINE
中。当然,这将作为单个lexer标记出现在输出中。如果这是您的意图,那么可以,但通常需要掌握查询的各个部分