LL(1) 语法的问题



我有一个26规则语法,用于Mini Java的子语法。这种语法应该是非面向对象的。无论如何,我一直在尝试左因子并删除左递归。但是,我用 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 生产,第一条规则中的$是文件结束标记。

我想我发现了两个问题(可能还有更多):

问题#1

在主类中,你有

MethodDeclarations public static void main

方法声明是

public static Type | e

这不是 LL(1),因为当解析器看到"公共"时,它无法判断它是 MethodStatement 还是 "public static void main" 方法。

问题#2

Arguments ::= Expression Argument | RelExpression Argument | e

两种表达式:

Expression ::= Term ExpressionRest

。和相对表达:

RelExpression ::= RelTerm RelExpressionRest
RelTerm ::= Term RelTermRest

。以"术语"开头,所以也不是LL(1)。

我只会选择LL(k)或LL(*),因为它们允许您编写更易于维护的语法。

有什么可以防止标识符与您的保留字之一相同吗? 如果不是,那么你的语法将是模棱两可的。不过我没有看到其他任何东西。

如果所有其他方法都失败了,我会删除语法的最后一行以外的所有内容,并对其进行测试。如果通过,我会一次添加一行,直到找到问题行。

相关内容

  • 没有找到相关文章

最新更新