JavaCC换行符可能会导致解析问题

JavaCC换行符可能会导致解析问题,java,javacc,Java,Javacc,我的语法如下: PARSER_BEGIN(Parser) package parser; public class Parser {} PARSER_END(Parser) SKIP: { " " | "\t" | "\n" | "\r" | "\f" } TOKEN : { <MIX: "mix"> | <WITH: "with"> | <FUN

我的语法如下:

PARSER_BEGIN(Parser)
    package parser;
    public class Parser {}
PARSER_END(Parser)

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

TOKEN : {
    <MIX: "mix">
    |    <WITH: "with">
    |    <FUNCTION: "function">
    |    <MANIFEST: "manifest">
    |    <REPEAT: "repeat">
    |    <NAT: "nat">
    |    <REAL: "real">
    |    <MAT: "mat">
    |    <FOR: "for">
    |    <INSTRUCTIONS: "instructions">
}

TOKEN : {
    <LPAREN: "(">
    |    <RPAREN: ")">
    |    <LBRACE: "{">
    |    <RBRACE: "}">
    |    <COLON: ":">
    |    <ASSIGN: "=">
}

// Include the necessary <INTEGER_LITERAL> included in most examples

TOKEN : {
    <IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)*>
    // Letter and Digit are the unicode values.
}

void Program() :
{}
{
    ( Manifest() )*
    <INSTRUCTIONS>
    Statement()
    <EOF>
}

void Manifest() :
{}
{
    <MANIFEST> (Type())? PrimaryExpression()
}

void Statement() :
{}
{
    Instruction()
    |    Function()
}

void Instruction() :
{}
{
    (TypingList())* Identifier() <ASSIGN> Expression()
}

void TypingList() :
{}
{
    Type() ( TypingRest() )*
}

void TypingRest() :
{}
{
    <COMMA> Type()
}

void Type() :
{}
{
    <MAT>
    |    <NAT>
    |    <REAL>
}

void Function() :
{}
{
    <FUNCTION> Identifier() <LPAREN> (FormalParameterList())* <RPAREN> (<COLON> TypingList())? <LBRACE>
        Statement()
    <RBRACE>
}

void FormalParemeterList() :
{}
{
    FormalParameter() (FormalParameterRest() )*
}

void FormalParameter() :
{}
{
    (TypingList())* Identifier()
}

void FormalParameterRest() :
{}
{
    <COMMA> FormalParameter()
}

void Instruction() :
{}
{
    (TypingList())* Identifier() <ASSIGN> Expression()
}

void Identifier() :
{}
{
    <IDENTIFIER>
}

void Expression() :
{}
{
    <MIX> Identifier() <WITH> Identifier() <FOR> <INTEGER_LITERAL>
}
但是,当JavaCC在函数
中看到
temp=mix…
语句时,它表示它找到了一个标识符,但实际上还需要其他任何东西:
线程“main”解析器中出现异常。ParseException:在第x行第y列遇到“temp”。
我期待的是:
“为了……”。。。
“}”…


但是,正如您所看到的,我的语法表示可以使用标识符为其分配
mix
的值。但错误是说这是无效的或不正确的。我尝试了几种不同的方法,但似乎都不管用。

问题在于,您告诉JavaCC只有一条
指令()
BranchStatement()| WhileStatement()| Function()
。因此,一旦解析器访问其中一个状态,它就不能再访问那里了

要解决此问题,请将Kleene闭包+放在您的
语句()周围,例如:

void Statement() :
{}
{
    (
    Instruction()
    |    BranchStatement()
    |    WhileStatement()
    |    Function()
    )+
}

+
操作符告诉自动机,此状态必须至少访问一次,但可以重复。

javacc是否显示警告?查看生成的代码,如果它符合您的预期,我认为正在发生的是
two
temp
被视为其各自后续行的延续。这让我相信新台词把事情搞砸了。我真正得到的只是一个例外。它正确地将“temp”标识为
标识符
。但这就是我所能得到的。在调试模式下,转换语句只会让我回到正确的结论:
temp
是一个
标识符。然后它会看到空格(应该被跳过),将其放回原处,然后在说:
*******找到了匹配项(temp)****
后出错,因为函数体中只有一条指令,这并不能解释函数中报告的错误。它将解释最后一行指令上的错误。我想知道这个问题是否有错误。
void Statement() :
{}
{
    (
    Instruction()
    |    BranchStatement()
    |    WhileStatement()
    |    Function()
    )+
}