我试图找到解析器问题的底部,但首先,我想知道为什么会这样:
Encountered "" at line 1, column 1.
Was expecting one of:
以下是导致问题的语法子集:
options {
STATIC = false;
DEBUG_PARSER = true;
DEBUG_LOOKAHEAD = true;
LOOKAHEAD = 64;
}
PARSER_BEGIN(MyParser)
package myparser;
public class MyParser {
}
PARSER_END(MyParser)
/* skip whitespace */
SKIP : {
" "
| "\t"
| "\n"
| "\r"
}
/* other symbols */
TOKEN : {
< COMMA: "," >
| < SEMICOLON: ";" >
| < LEFT_PAREN: "(" >
| < RIGHT_PAREN: ")" >
| < LEFT_BRACKET: "[" >
| < RIGHT_BRACKET: "]" >
| < LEFT_BRACE: "{" >
| < RIGHT_BRACE: "}" >
}
/* type specifiers */
TOKEN : {
< TYPE_SPECIFIER:
"void"
| "int"
| "float"
>
}
/* identifiers */
TOKEN [IGNORE_CASE] : {
<IDENTIFIER: ["_","a"-"z"] (["_","a"-"z","0"-"9"])* >
}
SimpleNode Start() : {}
{
/* begin here */
Declaration()
{ return jjtThis; }
}
void Declaration() : {}
{
FunctionPrototype() <SEMICOLON>
| InitDeclaratorList() <SEMICOLON>
}
void FunctionPrototype() : {}
{
FunctionDeclarator() <RIGHT_PAREN>
}
void FunctionDeclarator() : {}
{
FunctionHeaderWithParameters()
| FunctionHeader()
}
void FunctionHeaderWithParameters() : {}
{
/* recursive version:
FunctionHeader() ParameterDeclaration()
FunctionHeaderWithParameters() <COMMA> ParameterDeclaration()
*/
FunctionHeader() ParameterDeclaration() [FunctionHeaderWithParametersPrime()]
}
void FunctionHeaderWithParametersPrime() : {}
{
<COMMA> ParameterDeclaration() [FunctionHeaderWithParametersPrime()]
}
void FunctionHeader() : {}
{
FullySpecifiedType() <IDENTIFIER> <LEFT_PAREN>
}
void FullySpecifiedType() : {}
{
TypeSpecifier()
}
void TypeSpecifier() : {}
{
TypeSpecifierNonArray() [ArraySpecifier()]
}
void ArraySpecifier() : {}
{
/* recursive version:
<LEFT_BRACKET> <RIGHT_BRACKET>
| <LEFT_BRACKET> ConstantExpression() <RIGHT_BRACKET>
| ArraySpecifier() <LEFT_BRACKET> <RIGHT_BRACKET>
| ArraySpecifier() <LEFT_BRACKET> ConstantExpression() <RIGHT_BRACKET>
*/
<LEFT_BRACKET> <RIGHT_BRACKET> [ArraySpecifierPrime()]
}
void ArraySpecifierPrime() : {}
{
<LEFT_BRACKET> <RIGHT_BRACKET> [ArraySpecifierPrime()]
}
void TypeSpecifierNonArray() : {}
{
<TYPE_SPECIFIER>
| TypeName()
}
void TypeName() : {}
{ /* user defined type e.g struct or typedef */
<IDENTIFIER>
}
void ParameterDeclaration() : {}
{
ParameterDeclarator()
| ParameterTypeSpecifier()
}
void ParameterTypeSpecifier() : {}
{
TypeSpecifier()
}
void ParameterDeclarator() : {}
{
TypeSpecifier() <IDENTIFIER>
| TypeSpecifier() <IDENTIFIER> ArraySpecifier()
}
void InitDeclaratorList() : {}
{
/* recursive version:
SingleDeclaration()
| InitDeclaratorList() <COMMA> <IDENTIFIER>
| InitDeclaratorList() <COMMA> <IDENTIFIER> ArraySpecifier()
| InitDeclaratorList() <COMMA> <IDENTIFIER> ArraySpecifier() <EQUAL> Initializer()
| InitDeclaratorList() <COMMA> <IDENTIFIER> <EQUAL> Initializer()
*/
SingleDeclaration() [InitDeclaratorListPrime()]
}
void InitDeclaratorListPrime() : {}
{
<COMMA> <IDENTIFIER> [InitDeclaratorListPrime()]
| <COMMA> <IDENTIFIER> ArraySpecifier() [InitDeclaratorListPrime()]
}
void SingleDeclaration() : {}
{
FullySpecifiedType()
| FullySpecifiedType() <IDENTIFIER>
| FullySpecifiedType() <IDENTIFIER> ArraySpecifier()
}
函数声明工作正常
void main(int a, int b);
但声明语句在完整语法中的函数体中不起作用
float myvar;
此破坏示例的解析器和前瞻的调试输出如下
Call: Start
Call: Declaration
Call: FunctionPrototype(LOOKING AHEAD...)
Call: FunctionDeclarator(LOOKING AHEAD...)
Call: FunctionHeaderWithParameters(LOOKING AHEAD...)
Call: FunctionHeader(LOOKING AHEAD...)
Call: FullySpecifiedType(LOOKING AHEAD...)
Call: TypeSpecifier(LOOKING AHEAD...)
Call: TypeSpecifierNonArray(LOOKING AHEAD...)
Visited token: <<TYPE_SPECIFIER>: "float" at line 1 column 1>; Expected token: <<TYPE_SPECIFIER>>
Return: TypeSpecifierNonArray(LOOKAHEAD SUCCEEDED)
Call: ArraySpecifier(LOOKING AHEAD...)
Visited token: <<IDENTIFIER>: "myvar" at line 1 column 7>; Expected token: <"[">
Return: ArraySpecifier(LOOKAHEAD FAILED)
Return: TypeSpecifier(LOOKAHEAD SUCCEEDED)
Return: FullySpecifiedType(LOOKAHEAD SUCCEEDED)
Visited token: <<IDENTIFIER>: "myvar" at line 1 column 7>; Expected token: <<IDENTIFIER>>
Visited token: <";" at line 1 column 12>; Expected token: <"(">
Return: FunctionHeader(LOOKAHEAD FAILED)
Return: FunctionHeaderWithParameters(LOOKAHEAD FAILED)
Call: FunctionHeader(LOOKING AHEAD...)
Call: FullySpecifiedType(LOOKING AHEAD...)
Call: TypeSpecifier(LOOKING AHEAD...)
Call: TypeSpecifierNonArray(LOOKING AHEAD...)
Visited token: <<TYPE_SPECIFIER>: "float" at line 1 column 1>; Expected token: <<TYPE_SPECIFIER>>
Return: TypeSpecifierNonArray(LOOKAHEAD SUCCEEDED)
Call: ArraySpecifier(LOOKING AHEAD...)
Visited token: <<IDENTIFIER>: "myvar" at line 1 column 7>; Expected token: <"[">
Return: ArraySpecifier(LOOKAHEAD FAILED)
Return: TypeSpecifier(LOOKAHEAD SUCCEEDED)
Return: FullySpecifiedType(LOOKAHEAD SUCCEEDED)
Visited token: <<IDENTIFIER>: "myvar" at line 1 column 7>; Expected token: <<IDENTIFIER>>
Visited token: <";" at line 1 column 12>; Expected token: <"(">
Return: FunctionHeader(LOOKAHEAD FAILED)
Return: FunctionDeclarator(LOOKAHEAD FAILED)
Return: FunctionPrototype(LOOKAHEAD FAILED)
Call: InitDeclaratorList(LOOKING AHEAD...)
Call: SingleDeclaration(LOOKING AHEAD...)
Call: FullySpecifiedType(LOOKING AHEAD...)
Call: TypeSpecifier(LOOKING AHEAD...)
Call: TypeSpecifierNonArray(LOOKING AHEAD...)
Visited token: <<TYPE_SPECIFIER>: "float" at line 1 column 1>; Expected token: <<TYPE_SPECIFIER>>
Return: TypeSpecifierNonArray(LOOKAHEAD SUCCEEDED)
Call: ArraySpecifier(LOOKING AHEAD...)
Visited token: <<IDENTIFIER>: "myvar" at line 1 column 7>; Expected token: <"[">
Return: ArraySpecifier(LOOKAHEAD FAILED)
Return: TypeSpecifier(LOOKAHEAD SUCCEEDED)
Return: FullySpecifiedType(LOOKAHEAD SUCCEEDED)
Return: SingleDeclaration(LOOKAHEAD SUCCEEDED)
Call: InitDeclaratorListPrime(LOOKING AHEAD...)
Visited token: <<IDENTIFIER>: "myvar" at line 1 column 7>; Expected token: <",">
Visited token: <<IDENTIFIER>: "myvar" at line 1 column 7>; Expected token: <",">
Return: InitDeclaratorListPrime(LOOKAHEAD FAILED)
Return: InitDeclaratorList(LOOKAHEAD SUCCEEDED)
Visited token: <<IDENTIFIER>: "myvar" at line 1 column 7>; Expected token: <";">
Return: Declaration
Return: Start
Encountered "" at line 1, column 1.
Was expecting one of:
问题似乎出现在SingleDeclaration
制作中,它预期
FullySpecifiedType()
| FullySpecifiedType() <IDENTIFIER>
其中FullySpecifiedType
是类型常量( void , int , float )或其他标识符(以方便用户)定义的类型)。
如果我交换这些线以便它读取
FullySpecifiedType() <IDENTIFIER>
| FullySpecifiedType()
然后它按预期运行。为什么订单有所不同?
答案 0 :(得分:1)
首先将LOOAHEAD选项设置为1,以便JavaCC将警告您前瞻性冲突。
你的语法有预见的冲突。 JavaCC处理器应将这些报告为警告。你应该留意这些警告。
默认情况下,JavaCC使用下一个输入标记来做出选择。有关详细信息,请参阅documentation和FAQ。取
void SingleDeclaration() : {}
{
FullySpecifiedType()
| FullySpecifiedType() <IDENTIFIER>
| FullySpecifiedType() <IDENTIFIER> ArraySpecifier()
}
作为一个例子。有一个三向选择。显然不能根据下一个令牌的种类做出选择,因为任何可以启动第一个选择的令牌也可以从第二个或第三个开始。
有两种方法可以解决问题。最好的,通常是重写语法。
void SingleDeclaration() : {}
{
FullySpecifiedType()
[
<IDENTIFIER>
[
ArraySpecifier()
]
]
}
第二种是使用先行规范。
void SingleDeclaration() : {}
{
LOOKAHEAD(FullySpecifiedType() <IDENTIFIER> "[")
FullySpecifiedType() <IDENTIFIER> ArraySpecifier()
|
LOOKAHEAD(FullySpecifiedType() <IDENTIFIER>)
FullySpecifiedType() <IDENTIFIER>
|
FullySpecifiedType()
}
还有一件事,你的开始制作应该是这样的:
SimpleNode Start() : {}
{
/* begin here */
Declaration() <EOF>
{ return jjtThis; }
}