我正在使用JavaCC制作规范以识别语言。我遇到的问题是JavaCC给了我一个警告,因为public是Member()声明的公共前缀。 Member()可以有Attributes()和/或Method()但必须至少有一个Method,顺序无关紧要。
JavaCC给我的警告是:
第66行第26行的(......)+构造中的选择冲突。 嵌套在构造和扩展之后的构造具有共同的前缀,其中之一是:“public”。考虑使用2或更多的前瞻来进行嵌套扩展。
第66行是Member()的唯一一行。此外,我需要这样做没有变化前瞻值。
以下是代码:
void Member() : {}
{
(Attribute())* (Method())+ (Attribute() | Method())*
}
void Attribute() : {}
{
"private" Type() <Id> [":=" Expr()]";"
}
void Method() : {}
{
MethodHead() MethodBody()
}
void MethodHead() : {}
{
("public")? (<Id> | Type() | "void") <Id> "(" Parameter() ")"
}
感谢。
答案 0 :(得分:0)
问题在于这个正则表达式
(Method())+ (Attribute() | Method())*
含糊不清。设M的缩写方法和A的属性。如果输入是MAM,则没有问题。 (Method())+
匹配前M个,(Attribute() | Method())*
匹配剩余的AM。但如果输入是MMA,那么除法应该在哪里? (Method())+
匹配M且(Attribute() | Method())*
匹配MA或(Method())+
匹配MM和(Attribute() | Method())*
匹配A.两种解析都是可能的。 JavaCC并不知道你想要哪个解析,所以它会抱怨。
你能做什么:
(Method())+
将识别尽可能多的方法,(Attribute() | Method())*
只能识别第一个属性后的方法。(Method())+
更改为(LOOKAHEAD(1) Method())+
。这不会改变解析器的行为,但会抑制警告。违规行可以重写为
(Attribute())* Method() (Attribute() | Method())*
或
(Attribute())* (Method())+ [Attribute() (Attribute() | Method())*]