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()
)+
}