我正在尝试解析 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/