1

私はバイソンで完全なパーサーを作成しました(そしてもちろんフレックスで完全なレクサーを作成しました)、そして私は昨日だけパーサーに問題があることに気づきました。実際にはIf構造です。

これが私のパーサーの私のルールです:http://pastebin.com/TneESwUx

ここでは、単一のIFは認識されません。「%precIFX」を「END」に置き換えると、新しいトークン「END」("end" return END;フレックス)を追加することで機能します。しかし、私は新しい「end」キーワードを持ちたくないので、このソリューションを使用しません。

私を助けてください。

4

2 に答える 2

2

'この種のルールを処理する正しい方法は優先順位ではありません。パーサーがトークンの先読みを使用して解析方法を決定できるように、オプションのelse-partを使用するようにリファクタリングしています。私はそれを次のように設計します:

stmt      : IF '(' expression ')' stmts else_part
          | /* other statement productions here */

else_part : /* optional */
          | ELSE stmts

stmts     : stmt
          | '{' stmt_list '}'
          | '{' '}'

stmt_list : stmt
          | stmt_list ';' stmt

stmts(ブロックを含める代わりにこの特殊な構文解析を行う方法は、制作の観点から最適ではない可能性があり、言語に奇妙な点をもたらす可能性がありますstmtが、詳細がないと確実に言うのは難しいです。 bison生成されたパーサーは機能します。調査することをお勧めします。また、予期しないシフト/削減の競合、特に削減/削減の競合にも注意してください。)

この種の文法では、shift/reduceの競合は完全に正常であることに注意してください。LALR(1)パーサーのポイントは、これらの競合を機能として使用し、競合を解決するために1つのトークンで先を見越すことです。それらは、文法を誤ってファクタリングすることによって導入した、不要ものをより簡単に検出できるように、具体的に報告されています。

また、一致するようにリファクタリングIfExpressionする必要があります。秘訣は、else_partに何らかの条件式を生成する必要があることです$$。本番環境では、IFテスト$6(に対応)を行い、適切なコンストラクターelse_partを呼び出します。IfExpression

于 2012-05-13T18:34:22.457 に答える
1

あなたの文法は曖昧なので、あなたはシフト/削減の対立に耐えなければなりません。トークンは、括弧のペアのように、ステートメントが常に適切に閉じられるようENDにすることで、あいまいさを排除します。IF

ここでは、括弧がよく似ています。次のような文法があるとします。

maybe_closed_parens : '(' stuff
                    | '(' stuff ')'
                    ;

stuffそれ自体がいくつかの文法記号を生成し、そのうちの1つはですmaybe_closed_parens

したがって、のような入力がある場合((((((whatever、それは正しいです。括弧を閉じる必要はありません。しかし、追加するとどうなります)か?どちら(が閉まりますか?

IFこれは、どれがに一致するかがわからないのと非常によく似ていELSEます。

(の有無にかかわらず)ENDの構文に追加すると、閉じ括弧を付けるようなものになります。とのようなものです。IFELSEIFEND()

もちろん、あなたはEND自分の言語でその単語を望まないのはスタイル的に正しいです。なぜなら、あなたはすでに中括弧で囲まれたブロックを持っているからです。これは基本的にパスカルBEGINとの代替スペルですEND。あなた}はすでにENDキーワードです。

したがって、できることは、IF複合ステートメントのみを受け入れる(つまり、完全にブレースされている)というルールを課すことです。

if_statement : IF condition compound_statement
             | IF condition compound_statement ELSE compound_statement

現在、中括弧が存在する必要があるため、if x if ywelsezのようなあいまいさを持つことは不可能ですif x { if y { w } else { z } } or if x { if y { w } } else { z }

Perlがこの選択をした言語の一例であることを思い出しているようです。それはあなたの曖昧さを取り除くだけでなく、もっと重要なことにそれはプログラムから曖昧さを取り除くので、それは悪い考えではありません。

ステートメントが直接囲まれcompound_statementたフレーズを生成するため、文法にフレーズ構造規則がないことがわかります。このアプローチを取る場合は、それをハックする必要があります。{}

于 2012-05-14T00:01:36.560 に答える