首页 > 解决方案 > Antlr 解析器没有发生

问题描述

如果我有一个测试语法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 : [ \t\f;]+ -> 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
  )
      )
    )
  )
)

因为它必须解析execSqlStatement我无法检索的内容。提前致谢

标签: javascriptantlr4

解决方案


这里有几件事:

  1. ANTLR4 不生成语法树 (AST),而是解析树。AST 由以(或多或少)类似树的方式匹配的输入符号组成。解析树由解析上下文节点组成,这些节点描述了语法中匹配的路径。它们还包含匹配的符号,因此它们是 AST 的超集。
  2. 你的语法不完整,例如它错过了规则、、、等的定义SQ问题E中的X例子应该是自包含的,并且可以在没有额外调整的情况下进行转换。
  3. 你从不使用你的规则freeText。那么它对输出有何贡献呢?
  4. 您将整个 SQL 代码编码到单个词法分析器规则EXECSQLLINE中。当然,这将在输出中显示为单个词法分析器标记。如果这是您的意图,那么可以,但通常人们想要掌握查询的各个部分。

推荐阅读