Вопрос

Here is a grammar wrote for the lemon parser generator :

%left  PostDecrementation.
%right PreDecrementation.

program ::= expression.
expression ::= Terminal.
expression ::= unaryoperation.
unaryoperation ::= Decrementation expression. [PreDecrementation]
unaryoperation ::= expression Decrementation. [PostDecrementation]

When trying to compile it, the generator produces the following conflict :

State 0:
      program ::= * expression
      expression ::= * Null
      expression ::= * unaryoperation
      unaryoperation ::= * Decrementation expression
      unaryoperation ::= * expression Decrementation

                      Null shift  5
            Decrementation shift  1
                   program accept
                expression shift  2
            unaryoperation shift  4

State 1:
      expression ::= * Null
      expression ::= * unaryoperation
      unaryoperation ::= * Decrementation expression
      unaryoperation ::= Decrementation * expression
      unaryoperation ::= * expression Decrementation

                      Null shift  5
            Decrementation shift  1
                expression shift  3
            unaryoperation shift  4

State 2:
  (0) program ::= expression *
      unaryoperation ::= expression * Decrementation

                         $ reduce 0
            Decrementation shift  6

State 3:
  (3) unaryoperation ::= Decrementation expression *
      unaryoperation ::= expression * Decrementation

            Decrementation shift  6
            Decrementation reduce 3   ** Parsing conflict **
                 {default} reduce 3

State 4:
  (2) expression ::= unaryoperation *

                         {default} reduce 2

State 5:
  (1) expression ::= Null *

                 {default} reduce 1

State 6:
  (4) unaryoperation ::= expression Decrementation *

                 {default} reduce 4

Why is there a conflict, since the precedence and associativity of both PreIncrementation and PostDecrementation has been explicitely specified in the grammar ?

Это было полезно?

Решение

You are only defining precedence rules for pseudoterminals (PostDecrementation and PreDecrementation). Nowhere do you define the precedence of the actual terminal Decrementation.

Precedence is always compared between a production (which could be reduced) and a terminal (which could be shifted). So you need to specify the precedence of Decrementation to resolve the conflict.

Personally, I wouldn't use precedence declarations in this case. But if you really want to, you should probably just use one pseudoterminal, and let Decrementation be the precedence of one of the two productions which uses it.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top