1

正と負の小数を解析しようとしています。

number(N) ::= pnumber(N1).

number(N) ::= nnumber(N1).

number(N) ::= pnumber(N1) DOT pnumber(N2).

number(N) ::= nnumber(N1) DOT pnumber(N2).

pnumber(N) ::= NUMBER(N1).

nnumber(N) ::= MINUS NUMBER(N1).

最初の 2 つのルールを含めるとシフト/リデュースの競合が発生しますが、競合が発生しないように文法を記述する方法がわかりません。私はレモンパーサーを使用しています。

編集: .out ファイルからの競合

State 79:
     (56) number ::= nnumber *
          number ::= nnumber * DOT pnumber

                           DOT shift        39
                           DOT reduce       56      ** Parsing conflict **
                     {default} reduce       56     number ::= nnumber

State 80:
     (55) number ::= pnumber *
          number ::= pnumber * DOT pnumber

                           DOT shift        40
                           DOT reduce       55      ** Parsing conflict **
                     {default} reduce       55     number ::= pnumber
State 39:
          number ::= nnumber DOT * pnumber
          pnumber ::= * NUMBER

                        NUMBER shift-reduce 59     pnumber ::= NUMBER
                       pnumber shift-reduce 58     number ::= nnumber DOT pnumber

State 40:
          number ::= pnumber DOT * pnumber
          pnumber ::= * NUMBER

                        NUMBER shift-reduce 59     pnumber ::= NUMBER
                       pnumber shift-reduce 57     number ::= pnumber DOT pnumber

編集 2: 問題を引き起こす最小限の文法

start ::= prog.
prog ::= rule.
rule ::= REVERSE_IMPLICATION body DOT.
body ::= bodydef.
body ::= body CONJUNCTION bodydef.
bodydef ::= literal.
literal ::= variable.
variable ::= number.
number ::= pnumber.
number ::= nnumber.
number ::= pnumber DOT pnumber.
number ::= nnumber DOT pnumber.
pnumber ::= NUMBER.
nnumber ::= MINUS NUMBER.
4

2 に答える 2

0

orを使用DOTして、演算子トークンの結合性を宣言する必要があります。%left%right

または、別のアイデアは、この中間削減を削除することです。あなたの文法の明らかな特徴は、数字DOTの後に数字が続くということです。これは、次の 1 つのルールでキャプチャできます。

number : number DOT NUMBER

数値の後にトークンがDOT続くNUMBER場合でも、数値です。

この規則DOTでは、あいまいさがないため、結合性を宣言する必要はありません。ルールは純粋に左再帰であり、 の右手DOTは終端トークンです。numberパーサーは、ステート マシンがこの時点にあるときまでスタックのトップを減らしてから、次のようにシフトする必要がありDOTます。

number : number DOT NUMBER

ここで解析している言語は正規のものです。再帰なしで正規表現で解析できます。そのため、左再帰と右再帰の両方があり、結合性を宣言する必要があるルールは、やや「大きなハンマー」です。

于 2016-08-19T00:29:55.673 に答える