1

私はプログラミング言語の文法を書いていますが、真っ先にシフト/リデュースの問題に直面しています。問題は次の状態にあります。

fn_call -> ID . L_PAREN fn_args R_PAREN
assignment -> ID . ASSIGN value
assignment -> ID . ASSIGN container
value -> ID

もう少し詳しく説明する前に、次のことを明確にしたいと思います。

関数を呼び出しているのか、ID を値 (定数または変数など) として使用しているかをプログラムが判断できないため、これはシフト/リデュースですか?

続けて、これを修正することは可能ですか?私の言語では現在、行区切り記号 (C の ';' や Python の '\n' など) を使用していません。パーサーは LALR(1) です。

関数呼び出しと行区切り文字を含む変数を解読する最も効率的な (文法に追加する規則が最も少ない) 方法は何ですか?

編集: これがその状態の先読みです。

  ! shift/reduce conflict for L_PAREN resolved as shift
    L_PAREN         shift and go to state 60
    ASSIGN          shift and go to state 61
    COMMA           reduce using rule 43 (value -> ID .)
    R_PAREN         reduce using rule 43 (value -> ID .)
    DASH            reduce using rule 43 (value -> ID .)
    R_BRACE         reduce using rule 43 (value -> ID .)
    NONE            reduce using rule 43 (value -> ID .)
    DEFN            reduce using rule 43 (value -> ID .)
    FOR             reduce using rule 43 (value -> ID .)
    INT_T           reduce using rule 43 (value -> ID .)
    DBL_T           reduce using rule 43 (value -> ID .)
    STR_T           reduce using rule 43 (value -> ID .)
    ID              reduce using rule 43 (value -> ID .)
    INT             reduce using rule 43 (value -> ID .)
    DBL             reduce using rule 43 (value -> ID .)
    STR             reduce using rule 43 (value -> ID .)
    COMMENT_LINE    reduce using rule 43 (value -> ID .)
    L_BRACE         reduce using rule 43 (value -> ID .)
    SET             reduce using rule 43 (value -> ID .)

  ! L_PAREN         [ reduce using rule 43 (value -> ID .) ]
4

2 に答える 2

2

文法の多くを示していないため、以下は当て推量です。関数呼び出しだけでなく、式をステートメントとして許可することを前提としています。その場合、式は で開始でき(、ステートメントは で終了できIDます。ステートメント区切り文字がないため (私が思うに)、以下は本当にあいまいです。

a = b
(c + d)

b( )を読んだ後、 の一部としてに縮小するか、ID として残して の一部としてをシフトIDするかは不明です。valueassignment(fn_call

プロダクションを追加してもあいまいさを取り除くことはできません。:)

于 2013-07-16T07:08:43.107 に答える
1

これがパーサーの「状態」を形成する項目のセットである場合、正しく書き留めていません。

fn_call -> ID . L_PAREN fn_args R_PAREN
assignment -> ID . ASSIGN value
assignment -> ID . ASSIGN container
value -> ID .  *missing lookahead set*

あなたの言語の残りの部分は表示されないため、ルールの先読みセットが何であるかを知ることができません

 value -> ID

実際にこの状態で shift-reduce 競合があると仮定すると、先読みセットには「ASSIGN」または「L_PAREN」が含まれている必要があります。詳細を知らずに問題を解決する方法を教えることはできません。

現在の文法にこれらの問題があることを考えると、ルールを追加しても先読みセットに既に含まれているものは変更されないため、行区切り記号が含まれているかどうかに関係なく、この単純な「ルールの追加」を修正することはできません (既存のトークンにさらにトークンを追加する可能性があります)。セット)。

編集: 問題を解決する方法の 1 つは、解析テクノロジを切り替えることです。あなたの問題は、LALRパーサーが、あなたが持っていると思われる局所的な曖昧さを処理できないことです. ただし、さらに先を見れば、全体的な文法には実際のあいまいさがない場合があります。それはあなたの言語構文に依存しますが、あなたは自分自身を転がしているので、好きなようにすることができます. 任意の先読みを処理できる GLR 解析テクノロジを検討することをお勧めします。Bison の最近のバージョンをチェックしてください。

于 2013-07-16T07:02:32.687 に答える