我对Mini Java的子语法有26条规则语法。该语法应该是非面向对象的。无论如何,我一直在尝试左击它并删除左递归。但是我用JFLAP测试它,但它告诉我它不是LL(1)。我已经按照Aho-Sethi书中的算法的每一步进行了操作。
你能给我一些提示吗?
Goal ::= MainClass $
MainClass ::= class <IDENTIFIER> { MethodDeclarations public static void main ( ) {
VarDeclarations Statements } }
VarDeclarations ::= VarDeclaration VarDeclarations | e
VarDeclaration ::= Type <IDENTIFIER> ;
MethodDeclarations ::= MethodDeclaration MethodDeclarations | e
MethodDeclaration ::= public static Type <IDENTIFIER> ( Parameters ) {
VarDeclarations Statements return GenExpression ; }
Parameters ::= Type <IDENTIFIER> Parameter | e
Parameter ::= , Type <IDENTIFIER> Parameter | e
Type ::= boolean | int
Statements ::= Statement Statements | e
Statement ::= { Statements }
| if ( GenExpression ) Statement else Statement
| while ( GenExpression ) Statement
| System.out.println ( GenExpression ) ;
| <IDENTIFIER> = GenExpression ;
GenExpression ::= Expression | RelExpression
Expression ::= Term ExpressionRest
ExpressionRest ::= e | + Term ExpressionRest | - Term ExpressionRest
Term ::= Factor TermRest
TermRest ::= e | * Factor TermRest
Factor ::= ( Expression )
| true
| false
| <INTEGER-LITERAL>
| <IDENTIFIER> ArgumentList
ArgumentList ::= e | ( Arguments )
RelExpression ::= RelTerm RelExpressionRest
RelExpressionRest ::= e | && RelTerm RelExpressionEnd
RelExpressionEnd ::= e | RelExpressionRest
RelTerm ::= Term RelTermRest
RelTermRest ::= == Expression | < Expression | ExpressionRest RelTermEnding
RelTermEnding ::= == Expression | < Expression
Arguments ::= Expression Argument | RelExpression Argument | e
Argument ::= , GenExpression Argument | e
每个<IDENTIFIER>
都是有效的Java标识符,<INTEGER-LITERAL>
是一个简单的整数。每个e
生产代表epsilon生产,第一个规则中的$
代表文件结束标记。
答案 0 :(得分:2)
我想我发现了两个问题(可能还有更多):
问题#1
在MainClass中你有
MethodDeclarations public static void main
MethodDeclaration是
public static Type | e
这不是LL(1),因为当解析器看到“public”时,它无法判断它是MethodDeclaration还是“public static void main”方法。
问题#2
Arguments ::= Expression Argument | RelExpression Argument | e
表达式:
Expression ::= Term ExpressionRest
...和RelExpression:
RelExpression ::= RelTerm RelExpressionRest
RelTerm ::= Term RelTermRest
...以“Term”开头,这样也不是LL(1)。
我只是选择LL(k)或LL(*),因为它们允许你编写更多可维护的语法。
答案 1 :(得分:0)
有什么可以防止IDENTIFIER与你的一个保留字相同吗?如果没有,那么你的语法就会模棱两可。我没有看到任何其他东西。
如果所有其他方法都失败了,我会删除除语法最后一行之外的所有内容,并对其进行测试。如果通过,我会一次添加一行,直到找到问题行。