ANTLR 相同解析器规则的零到多次出现

标签 antlr

我正在尝试解析 javadoc 风格的注释。我如何表明相同的解析器规则可能被触发零次或多次?

doc_comment            :    '/**' (param_declaration)* '*/'         ;

param_declaration      :    OUTERWS '@param' OUTERWS ID OUTERWS;

ID                     :    ('a'..'z')+ ;

OUTERWS                :     ('\n' | '\r' | ' ' |'\t')*;

param_declaration 规则包含在 ()* 中似乎不起作用,因为它不是 token 。

我希望:

/**
  @param one
  @param two
 */

可以。但相反,我得到: 无关的输入 '@param' 期待 {'/' 如果 (param_declaration) 匹配零个或多个实例,这对我来说没有意义。似乎将 ()* 添加到 param_declaration 没有任何作用。无论哪种方式:

/**
 @param one
*/

工作正常;带或不带 ()*。

最佳答案

您的问题的答案是,要匹配规则 foo 零次或多次,请使用 (foo)* 或简单地使用 foo*

如果这没有产生可用的结果,那么问题在于您如何构建词法分析器和/或解析器,要解决它,您需要提出一个更具体的问题并将您的语法与 特定的不是您所希望的输入和输出,以及所需输出的描述。

编辑: 由于 param_declaration 规则以所需的 OUTERWS token 开始和结束,因此出现两个参数错误。这意味着两个 OUTERWS 标记必须连续出现才能解析两个参数。这是不可能的,因为输入文件中的任何两个空白字符序列都会匹配一个长 OUTERWS 标记,并且将始终使用该较长标记而不是两个较短标记.

另请注意,您的 OUTERWS token 的编写方式可以匹配 0 个字符。如果您的输入序列包含数字(例如 0),则出现在 0 之前的最长标记将是零长度的 OUTERWS 标记。由于匹配 0 个字符后输入不会前进,这意味着包含数字的输入应生成无限长的空 OUTERWS 标记流。 不要忽略您在为此语法生成代码时看到的相关警告。

编辑 2:如果注释以 /***/ 形式出现,您的输入可以匹配零个参数。但是,如果您的评论以 /** */ 形式出现,则 /** 之间将有一个 OUTERWS 标记*/,当没有 param_declaration 时,您的解析器规则不允许这样做。

关于ANTLR 相同解析器规则的零到多次出现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21445099/

相关文章:

intellij-idea - 构建ANTLR4源以获取源jar

java - 在 Gradle 构建中兼顾 Scala、Antlr 和 Java

ANTLR:空条件不起作用

clojure - 如何在 Clojure 中使用尾递归遍历 AST

java - ANTLR 可以隐藏自动生成的文件中的第一行消息吗?

c - 如何用 | 转换表达式(或)在 AST 中?

javascript - 我可以将为 java 创建的语法文件转换为为 javascript 创建的语法文件吗?

compiler-construction - 使用 Antlr 创建语言

java - ANTLR4 中的树语法在哪里?

antlr - 接受单引号语法