0

EBNF式をモデル化しようとしています

("declare" "namespace" ";")* ("declare" "variable" ";")*

これを表すように見えるyacc(MPPGを使用しています)文法を作成しましたが、テスト式と一致しません。

私が一致させようとしているテストケースは

declare variable;

レクサーからのトークンストリームは

KW_Declare
KW_Variable
Separator

文法解析では、「Shift / Reduce競合、KW_Declareの状態6」があると示されています。「%leftPrologHeaderList PrologBodyList」でこれを解決しようとしましたが、どちらの解決策も機能しません。

Program                     : Prolog;
Prolog                      : PrologHeaderList PrologBodyList;

PrologHeaderList            : /*EMPTY*/
                            | PrologHeaderList PrologHeader;
PrologHeader                : KW_Declare KW_Namespace Separator;

PrologBodyList              : /*EMPTY*/
                            | PrologBodyList PrologBody;
PrologBody                  : KW_Declare KW_Variable Separator;

KW_Declare KW_Namespace KW_Variable Separatorはすべて、値が「declare」、「naemsapce」、「variable」、「;」のトークンです。

4

2 に答える 2

3

私がyaccのようなものを使ってから長い時間が経ちましたが、ここに役立つかもしれないし、役に立たないかもしれないいくつかの提案があります。

この状況では、2トークンの先読みが必要なようです。パーサーは最後のPrologHeaderに到達し、次の構成がPrologHeaderであるかPrologBodyであるかを判別する必要があり、KW_Declareからそれを判別することはできません。この状況で先読みを増やすという指示があれば、おそらく問題は解決するでしょう。

アクションにコンテキストを導入することもできます。PrologHeaderListPrologBodyListを定義するのではなく、 PrologRuleListを定義して、本文の後にヘッダーが表示された場合にアクションでエラーをスローするようにします。醜いですが、時々それをしなければなりません:文法で単純に見えるものは、生成されたパーサーでは単純ではないかもしれません。

ハックなアプローチは、トークンを組み合わせることです。KW_DeclareKW_Variableではなく、レクサーにスペースを認識させ、KW_Declare_Variableを使用させます。どちらもキーワードであるため、名前空間の衝突の問題が発生することはありません。

于 2009-06-04T11:57:37.590 に答える
0

上部の文法は規則的であるため、IIRCはそれをDFA(またはNDAとDFAに変換)としてプロットしてから、DFAを文法に変換できます。しばらく豆なので、読者の練習問題として残しておきます。

于 2009-06-04T16:48:49.440 に答える