好。这可能是一个简单的问题。我正在尝试解析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
*/
工作正常;有或没有()*。
答案 0 :(得分:4)
您的问题的答案是,要将规则foo
与零次或多次匹配,请使用(foo)*
或仅foo*
。
如果这不会产生可用的结果,那么问题在于你如何构建词法分析器和/或解析器,并解决它你需要提出一个更具体的问题,并将你的语法与特定输入和输出不是您所希望的,以及所需输出的描述。
修改:您发生了包含两个参数的错误,因为param_declaration
规则以必需的OUTERWS
令牌开头和结尾。这意味着两个OUTERWS
标记必须出现在一行中,以便解析两个参数。这是不可能的,因为输入文件中的任何两个空格字符序列都会匹配一个长OUTERWS
标记,而较长的标记将始终而不是两个较短的标记。
另请注意,您的OUTERWS
令牌的编写方式可以匹配0个字符。如果您的输入序列包含一个数字,例如0,那么0
之前出现的最长标记将是一个零长度OUTERWS
标记。由于输入不会因为匹配0个字符而前进,这意味着包含数字的输入应该产生无限长的空OUTERWS
标记流。 生成此语法代码时看到的相关警告不容忽视。
编辑2 :如果评论显示在/***/
表单中,您的输入可以匹配零参数。但是,如果您的评论显示在/** */
表单中,则OUTERWS
和/**
之间会有一个*/
令牌,当您没有时,解析器规则不允许这样做param_declaration
。