ANTLR零到多个同一解析器规则的次数

时间:2014-01-29 23:42:03

标签: antlr

好。这可能是一个简单的问题。我正在尝试解析javadoc样式的注释。如何指示相同的解析器规则可能被触发零次或多次:

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

param_declaration   :   OUTERWS '@param' OUTERWS ID OUTERWS;

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

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

param_declaration规则括在()*中似乎不起作用,因为它不是令牌。

我希望如此:

/**
  @param one
  @param two
 */

会奏效。但相反,我得到:无关输入'@param'期待{'* /'如果(param_declaration)*匹配零个或多个实例,对我来说没有意义。似乎对param_declaration添加()*什么都不做。无论哪种方式:

/** 
 @param one
*/

工作正常;有或没有()*。

1 个答案:

答案 0 :(得分:4)

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

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

修改:您发生了包含两个参数的错误,因为param_declaration规则以必需的OUTERWS令牌开头和结尾。这意味着两个OUTERWS标记必须出现在一行中,以便解析两个参数。这是不可能的,因为输入文件中的任何两个空格字符序列都会匹配一个长OUTERWS标记,而较长的标记将始终而不是两个较短的标记。

另请注意,您的OUTERWS令牌的编写方式可以匹配0个字符。如果您的输入序列包含一个数字,例如0,那么0之前出现的最长标记将是一个零长度OUTERWS标记。由于输入不会因为匹配0个字符而前进,这意味着包含数字的输入应该产生无限长的空OUTERWS标记流。 生成此语法代码时看到的相关警告不容忽视。

编辑2 :如果评论显示在/***/表单中,您的输入可以匹配零参数。但是,如果您的评论显示在/** */表单中,则OUTERWS/**之间会有一个*/令牌,当您没有时,解析器规则不允许这样做param_declaration