![](/img/trans.png)
[英]javacc Expansion within "(...)+" can be matched by empty string error
[英]Java CC issue - “Expansion within ”(…)*“ can be matched by empty string”
我们已经获得了使用Java CC进行修补和解析的语法。 它的问题之一是“(...)*内的扩展可以通过空字符串匹配。我理解此错误是由于某些内容可以匹配零次或多次而在其他可以匹配的内容中引起的零次或多次。
我不明白的是如何解决它。 (我们的讲师并没有说太多,“您必须谨慎使用。”
语法的问题区域及其相关的Java CC代码如下所示。 任何想法或建议,将不胜感激。
program := ( decl )*
( function ) *
main_prog
decl := ( var_decl | const_decl )*
var_decl := var ident_list : type ( , ident_list : type)* ;
const_decl := const identifier : type = expression ( , identifier : type = expression)* ;
function :=
type identifier ( param_list)
( decl )*
( statement ; )*
return ( expression | e ); //e is greek epsilon character
main_prog :=
main
( decl ) *
(statement ; )*
问题在于我认为decl的声明方式。 它是在实际的Java CC代码中声明的:
void decl():{}
{
( var_decl() | const_decl())*
}
如果我将上述Kleene闭包更改为+,则其他所有由此引起的错误都会消失。 但是,讲师说应该保留星星,并且我们应该谨慎对待它。 我在左因子分解,左递归删除等方面发现了很多资源,但是在这个特定问题上很少。 上面的代码实际上在Java CC中没有错误,但是是导致进一步错误的原因,如下所示:
void program():{}
{
( decl() )* //error here - Expansion within "(...)*" can be matched by empty string
( function() )*
main_prog()
}
void main_prog(): {}
{
< MAIN >
( decl() )* //same error on this line
(statement() < SCOLON >)*
}
void function(): {}
{
type() < ID > <LPARENT > param_list() < RPARENT >
( decl() )* //same error on this line
( statement() < SCOLON > )*
< RET> ( expression() | {} ) <SCOLON > // {} is epsilon
}
任何有关如何解决此问题的想法将不胜感激。
就目前而言,您的语法是模棱两可的-它表示decl
表示零个或多个声明,并且在许多地方您允许零个或多个decl
。 您在这两个地方都不需要*
,只需选择一个或另一个,这两种方法都可以解析相同的程序,但是它们在概念上略有不同。
您可以在decl
取出*
:
decl := ( var_decl | const_decl )
program := ( decl )*
( function ) *
main_prog
因此decl
表示单个声明, program
可以以decl
s序列开头,但不一定要这样。 或者,您可以将*
保留为decl
但从引用它的地方将其取出:
decl := ( var_decl | const_decl )*
program := decl
( function ) *
main_prog
因此,现在decl
代表的是“声明块”之类的东西,而不是单个声明-每个program
必须以声明块开头,但该块本身允许为空。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.