我正在编写一个JavaCC解析器/词法分析器,用于识别属于以下任何一种语言L0或L1的所有输入字符串:
L0
来自L0的字符串由几个由空格字符分隔的块组成。
必须至少存在一个块(即,不允许仅包含一定数量的空格的输入)。
L1
L1中的字符串由多个由空格字符分隔的块组成。
必须至少有一个街区。
value_vars
。一块
第二种必须具有(A-Z)
形状,其中<2U>. . .</2U>
代表
来自L0的任何字符串。到目前为止,这是我的代码:
. . .
问题:
我遇到的问题是,当我在PARSER_BEGIN(Assignment)
/** A parser which determines if user's input belongs to L0 or L1. */
public class Assignment {
public static void main(String[] args) {
String returnString = null;
boolean toPrintEmptyInput = false;
try {
Assignment parser = new Assignment(System.in);
if(parser.Input()) {
System.out.println("YES"); // If the user's input belongs to L0, print YES.
} else {
System.out.println("NO");
}
} catch (ParseException e) {
System.out.println("NO"); // If the user's input does not belong to L0, print NO.
}
}
}
PARSER_END(Assignment)
//** A token which matches any lowercase letter from the English alphabet. */
TOKEN :
{
< IDLOWER: (["a"-"z"]) >
}
//* A token which matches any uppercase letter from the English alphabet. */
TOKEN:
{
< IDUPPER: (["A"-"Z"]) >
}
//* A token which matches a single white space. */
TOKEN :
{
<WHITESPACE: " ">
}
/** This production is the basis for the construction of strings which belong to language L0. */
boolean Input() :
{}
{
<IDLOWER>(<IDLOWER><IDLOWER>)* ((<WHITESPACE>(<WHITESPACE><WHITESPACE>)*)<IDLOWER>(<IDLOWER><IDLOWER>)*)* ("\n"|"\r") <EOF>
{
return true;
}
|
{
return false;
}
}
/** This production is the basis for the construction of strings which belong to language L1. */
void Input2() :
{}
{
Input() ((<WHITESPACE> Input())* (<WHITESPACE> (<IDUPPER><IDUPPER>)+)*)* ("\n"|"\r") <EOF>
|
(<IDUPPER><IDUPPER>)+ ((<WHITESPACE> (<IDUPPER><IDUPPER>)+)* (<WHITESPACE> Input())*)* ("\n"|"\r") <EOF>
}
上运行javacc
时,终端上会打印出以下内容:Assignment.jj
我查看了以下链接,以便尝试为了更好地理解这个错误:
第二个链接建议修改扩展中的Expansion within "(. . .)*" can be matched by empty string.
,使其无法与零匹配。但是,我仍在努力做到这一点,同时仍然有一个接受L1中的字符串的生产。
我希望提示或更正!
答案 0 :(得分:2)
在Input2()
的规则中,(...)*
中包含的模式位于:
((<WHITESPACE> Input())* (<WHITESPACE> (<IDUPPER><IDUPPER>)+)*)*
可以与空字符串匹配。
您可以将展开缩小为(A* B*)*
格式,其中A
为<WHITESPACE> Input()
且B
为<WHITESPACE> (<IDUPPER><IDUPPER>)+
,A* B*
可以匹配空字符串,无论A
和B
是什么。
如果封闭的表达式可以匹配空字符串,那么JavaCC不允许(...)*
扩展,这就是错误消息试图告诉您的内容。
合理的替代方案可能是:
(A | B)*
由于在这种情况下,A
和B
都以<WHITESPACE>
开头,因此有必要将其考虑在内:
(<WHITESPACE> ( Input() | (<IDUPPER><IDUPPER>)+ ) )*