0

私は単純なプログラミング言語用にこの文法を構築しています(以前のあいまいさの問題はすでに解決されています:Bisonが「競合のためパーサーで役に立たないルール」をスローしている理由がわかりません)。 これは私

の完全な文法です: http://pastebin.com/yBHLSP0z
そして、これは Bison からの出力ファイルです: http://pastebin.com/eAma3gWy
-説明)

問題は、状態 107 でまだ 1 つの shift/reduce エラーが発生していることです (翻訳中です):

state 107

31 factor: ID .
48 concatenacion: ID . OPERADOR_SUMA ID
49              | ID . OPERADOR_SUMA literal_string

OPERADOR_SUMA  shift and go to state 140
OPERADOR_SUMA  [reduce using rule 31 (factor)]
$default       reduce using rule 31 (factor)


ここで、状態 107 が状態 70 から呼び出されます。

estado 70

   45 asignacion: ID OPERADOR_ASIGNACION . concatenacion
   46           | ID OPERADOR_ASIGNACION . expresion
   47           | ID OPERADOR_ASIGNACION . literal_string

    OPERADOR_RESTA   desplazar e ir al estado 55
    PARENTESIS_ABRE  desplazar e ir al estado 56
    COMILLA          desplazar e ir al estado 67
    ID               desplazar e ir al estado 107

    expresion       ir al estado 108
    termino         ir al estado 61
    factor          ir al estado 62
    concatenacion   ir al estado 109
    literal_string  ir al estado 110
    literal_real    ir al estado 63
    literal_entero  ir al estado 64
    signo           ir al estado 65

私が考えていることは(私が間違っている場合は修正してください)、次のような「放棄」のルールが見つかったときです。

asignacion: ID OPERADOR_ASIGNACION concatenacion | ID OPERADOR_ASIGNACION expresion

「式」から ID トークンを取得できることがわかり (式 > 用語 > 因子 > ID)、ID OPERADOR_ASIGNACION IDが作成されます。

expresion:  
        expresion OPERADOR_SUMA termino
        | expresion OPERADOR_RESTA termino
        | termino
        ;


termino:
        termino OPERADOR_MULTIPLICACION factor
        | termino OPERADOR_DIVISION factor
        | factor
        ;


factor:     
        ID
        | literal_entero
        | literal_real
        | PARENTESIS_ABRE expresion PARENTESIS_CIERRA
        ;

ここで、ID OPERADOR_ASIGNACION 連結に到達し、「連結」のルールを調べると、次のようになります。

concatenacion:
        ID OPERADOR_SUMA ID 
        | ID OPERADOR_SUMA literal_string 
        | literal_string OPERADOR_SUMA ID 
        | literal_string OPERADOR_SUMA literal_string
        ;

そのうちの 2 つは「ID」で始まります。そのため、これら 2 つのルールのいずれかが選択された場合、 ID OPERADOR_ASIGNACION IDを取得できる状態になりますが、「連結」ルールの場合のみ、後で「OPERADOR_SUMA」トークンを見つける必要があります。しかし、「連結」と「式」の両方からID OPERADOR_ASIGNACION ID式を形成できることがわかるとすぐに、窒息していると思います。
これが正確に起こっていることではない場合、何が問題なのか知りたいです。
そして、エラーが発生した場所が正しければ、それを解決する方法が本当にわかりません。
助けてください:)

ありがとう!

4

1 に答える 1

2

問題は次のことから発生します。

asignacion
    :   ID OPERADOR_ASIGNACION concatenacion
    |   ID OPERADOR_ASIGNACION expresion
    ;

および選択された代替案:

expresion
    :   expresion OPERADOR_SUMA termino
    ;

termino
    :   factor
    ;

factor
    :   ID
    ;

concatenacion
    :   ID OPERADOR_SUMA ID
    ;

つまり、パーサーが遭遇したとき:

x = y + z

の 1 番目または 2 番目の選択肢を処理しているかどうかはわかりませんasignacion

それは簡単な部分です。直し方?最も簡単な修正 (うまくいく場合、テストはしていません) は、concatenacion私が示したルールを削除し、ルールでは、構文的に同一であるため、対expresiona を扱っていることを認識することです。concatenacionexpresion

ID OPERADOR_SIGNACION ID OPERADOR_SUM ID

の 2 つのオペランドの型を見て、expresionどちらも文字列型の場合はconcatenacion、そうでない場合はexpresion.

concatenacionただし、ルール全体を確認することをお勧めします。文字列をルールに通す必要があるfactorと思うので、別の代替手段を追加しますfactor

factor
   :   literal_string
   ;

ただし、他のルールでリテラル文字列を拒否する必要があることを意味するため、より多くのセマンティック チェックを行います。+別の方法は、 「文字列連結」を意味する以外の別の演算子を導入することです。SQL は||;を使用します。一部の言語では が使用されてい,ます。など、別のトークンをまとめて使用できます@。から離れたら、多くのオプションがあります+。「2 つの隣接する文字列式は連結操作を意味する」だけで、その間に演算子を使用できませんか?

それでもうまくいかない場合は、私に戻ってください。

于 2013-11-13T03:28:19.323 に答える