当前瞻遇到文件结尾时,JavaCC 出现词法错误

JavaCC got Lexical error when lookahead meet end of file

为什么 JavaCC 总是在使用 lookahead 的终端上报错?就像这个例子一样,

options{
    LOOKAHEAD = 2;
}

PARSER_BEGIN(GS)
    public class GS{
        public static void main(String args[]) throws ParseException {
            GS parser = new GS(System.in);
            parser.q0();
        }
    }
PARSER_END(GS)

void q0():
{}
{
    "a" q1() |
    "c" 
}

void q1():
{}
{
    "b" q0()
    | "b"
}

在 q1() 上有 2 个选项,一个是读取 "b" 并移动到 q0,或者读取 "b" 并结束读取。但是如果我输入 "ab" 它会给出一个错误,即使它有先行选项。但是,如果我给出“(ab)*c”,JavaCC 就会接受它。

Exception in thread "main" TokenMgrError: Lexical error at line 1, column 3.  Encountered: "\r" (13), after : ""

当产生式规则为

时,同样的错误总是发生
{
    "terminal_x" non-terminal()
    | "terminal_x"
}

有什么方法可以不报错做这种产生式规则吗?

我正在使用 JavaCC 版本。 6.0_1.

谢谢。

编辑:

显然,如果产生式规则的形式是

{
    "terminal_x"
    | "terminal_x" non-terminal()
}

错误不会发生。但是,是什么导致了这个错误?

您建议的示例规则:

    {
        "terminal_x"
        | "terminal_x" non-terminal()
    }

实际上是在说 "there must be "terminal_x" followed by either zero or one non-terminal()"。使用 ? 运算符(零或一)可以更轻松地完成此操作,如下所示:

    {
        "terminal_x" (non-terminal())?
    }

这样,就不需要前瞻,因为它总是会寻找 "terminal_x",然后允许零个或一个 "non-terminal()",从而完全消除问题。

问题是您的输入字符串包含词法分析器不期望的 return 字符。它与 lookhahead 无关;前瞻与解析有关,而不是词法分析。我建议加入这样的规则。

SKIP : { " " | "\t" | "\r" | "\n" }