2016-04-07 5 views
1

私の文法の私のいくつかの規則には問題があります。GPPG-Grammar - 規則が使用されない

文法は次のようなものです:

defLINES : carrRet 
     | defLine carrRet 
     | defLines defLine carrRet 
     ; 

defLine : error carrRet        {yyerrok();} 
     | "DEF" kwType attrbt ID 
     | "DEF" kwType ID fieldSuff 
     ; 

kwType : "INT" 
     | "REAL" 
     ; 

fieldSuff: "[" expr "]" 
     | "[" expr "," expr "]" 
     ; 

attrbt : /* nothing */ 
     | "PHU" intValue 
     ; 

入力に確認する:

DEF INT testvar1 
DEF REAL testvar2 

この入力の頭「defLine」と生産の二番目のルールを使用する必要があります。

なぜですか? 3番目のルールは、常に確実に少なくとも一つのシフト/生産attrbt: /* nothing */があることを警告とともに競合を減らすを生成文法の助けを

Unexpected 'carRet', '[' expected. 

どうもありがとう、 アレックス

答えて

1

を使用して、エラーをスローします紛争のために役に立たない。 (そうでない場合は、GPPGがbisonと同じくらい多くの警告を出さないからです。しかし、少なくともシフト/競合の兆候はないと確信しています)

ルールに矛盾が生じます:

defLine : "DEF" kwType attrbt ID 
defLine : "DEF" kwType ID fieldSuff 

attrbtは空であってもよいが、第二のルールでIDに先行することができないからです。パーサーがDEF INTに遭遇し、次のシンボルがIDであるとします。この時点で、パーサはdefLineの2つのプロダクションのどちらを使用するのかを知りませんが、その違いは重要です。最初のケースでは、パーサーはを移動する前に空のattrbtを減らさなければなりません。 2番目のケースでは、attrbtを作成するのは間違いです。

Yaccのようなパーサジェネレータは、優先順位の宣言がない限り、常にシフト/リダクションの競合を解決します(この場合、IDは常にシフトされます)。つまり、これまで生産量を減らすことは不可能です。attrbt: /* nothing */ (バイソンは、少なくとも、この事実についての警告を表示します。

をさらに、IDのずれが、その場合に発生しますので、パーサはIDに従うことをfieldStuffが必要になりますので、defLineための唯一の第二の製造は、利用できるようになります、およびfieldStuff[で開始する必要があります。あなたが遭遇したがって、解析エラー。

これを修正するには、シフト/競合を減らすを削除する必要がある。一つの簡単な方法は、両方のdefLine作品でattrbtができるようになります(あなたは検出することができますセマンティックアクションのエラー)。もう1つの可能性は、空のプロダクションを削除してattrbtとし、それを明示的に許可することです紛失する:

attrbt : "PHU" intValue 

defLine : "DEF" kwType ID 
     | "DEF" kwType attrbt ID 
     | "DEF" kwType ID fieldSuff 
+0

ありがとう、あなたの大きな助けをありがとう!私はセマンティックアクションの問題を解決し、attrbtを許可することにしました。ありがとう... =) – Alex

関連する問題