2017-02-23 14 views
0

現在、Visual BasicのようなLALR(1)文法を書いていますが、この特定のシフト/リダクションの矛盾に直面しています。括弧のためにLALR(1)の競合が発生する

文法の問題の部分は、(明確化のためにEDIT 1及びEDIT 2を参照してください)である。

Expression 
    : IndexExpression 
    | /* other expressions */ 

IndexExpression 
    : MemberExpression 
    | MemberExpression '(' ArgumentList ')' 

MemberExpression 
    : ParenthesizedExpression 
    | Identifier 

ParenthesizedExpression 
    : '(' Expression ')' 

ArgumentList 
    : Expression 
    | Expression ',' ArgumentList 
    | ',' ArgumentList 

シフト/競合を減らすこのです

State 109 
    237 ParenthesizedExpression: '(' Expression ')' . 
    $default reduce using rule 237 (ParenthesizedExpression) 

... 
State 295 

    231 IndexExpression: MemberExpression '(' . ArgumentList ')' 
    237 ParenthesizedExpression: '(' . Expression ')' 
    ... 
    Expression go to state 352 

... 
State 352 
    182 ArgumentList: Expression . 
    183    | Expression . ',' ArgumentList 
    237 ParenthesizedExpression: '(' Expression . ')' 
    ... 
    ')' shift, and go to state 109 

    ')' [reduce using rule 182 (ArgumentList)] 

言い換えれば、括弧で囲まれた式に直面するとき、パーサは、ArgumentListと1つのexpreまたは括弧内の表現です。

文法をLALR(1)に維持しながら、この競合を修正する方法はありますか?

ありがとうございます。

EDIT 1:

/*他の式*/で私は簡潔にするため、このような方法でそれを書いて、実際には空の式ではありません。実際には、他の代替の表現があります

Expression 
    : IndexExpression 
    | Expression '+' Expression 
    | ... 

EDIT 2:ここ

@riciが問題かもしれない指摘文法(書の特に第1右手の法則の追加部品であります):Expressionが原因コメントルール/* other expressions */で、空に許可されているので

Statement 
    : MemberExpression ArgumentList 
    | MemberExpression '=' Expression 
    | MemberExpression '(' ArgumentList ')' '=' Expression 
    | ... 
+0

文法をもっと表示する必要があります。あるいは、同じ問題を抱えたコンパイル可能な文法を作成し、少数のプロダクションだけを作成することもできます。ところで、その 'argument_list'構文は非常に奇妙です。 LALR(1)パーサーでは一般的に避けるべき左回帰で書くのはなぜ便利なのですか?複数の不足している議論はどういう意味ですか?そして、他のすべての議論を省略することができれば、なぜ最後の議論はできないでしょうか? – rici

+1

1つの引数を取る関数をかっこなしで呼び出せるVB構文を許可しますか?もしそうなら、それはおそらくあなたの問題です。 – rici

+0

@rici **欠けている引数**:この特定のVB方言では、最後のものを除いて、引数リストに空の引数を持たせることができます。私は_Expression_が空であることを本当に望んでいないので、_ArgumentList_にその3番目のルールを置くことになりました。 **括弧付きの引数が1つ**:はい!事実、昨日根本的な原因を見つけようと深く掘り下げた後、私はこれが原因かもしれないという結論に達しました。この構文をどのように組み込むかについてのご意見はありますか? –

答えて

2

エラーは、ありますndは空ではないとみなされます。

2つの同等の規則にExpression結果の使用を以下に示し:

ArgumentList 
    : Expression 
    | Expression ',' ArgumentList /* degenerates into "',' ArgumentList" */ 
    | ',' ArgumentList 
    ; 

シフトの数は/競合を減らす回ArgumentListの数が参照されているがArgumentListに一度IndexExpressionで二回(使用され自身)

競合を削除し、空Expressionの場合のArgumentListを修正するには、次の

ArgumentList 
    : Expression 
    | ArgumentList ',' Expression 
    ; 

またはExpressionが空でないことを確認します(コメント付きのルールを削除してください)。

+0

こんにちはkdhp、私の編集1を参照してください。私の元の投稿であいまいになって申し訳ありません。 –

+1

@SamTatasurya式リストを見ることなく、別の空の値があるか、演算子が '%left' /'%right'として宣言されていないか、 ''(' Expression ' ) ''(これは' IndexExpression-> MemeberExpression-> ParenthesizedExpression'でも存在します) – kdhp

関連する問題