1

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プロダクションはイプシロン プロダクションを表し$、最初のルールの はファイルの終わりマーカーです。

4

2 に答える 2

2

私は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(*) を選びます。なぜなら、より保守しやすい文法を書くことができるからです。

于 2012-06-30T22:04:25.090 に答える
0

IDENTIFIER が予約語の 1 つと同じになるのを防ぐ方法はありますか? そうでなければ、あなたの文法はあいまいになります。私は他に何も見ていません。

他のすべてが失敗した場合は、文法の最後の行以外をすべて削除して、それをテストします。それが成功したら、問題のある行が見つかるまで、一度に 1 行ずつ追加します。

于 2012-06-30T20:19:27.943 に答える