I'm trying to write a mini-compiler of a given language using flex & bison. It was working fine until I found out I forgot about a rule which has recursion in it, the rule being:

 liste_data : liste_data declar | declar;

As I added it, I had shift/reduce conflicts which I don't understand. My grammar is not ambiguous

Here's a simplified version of my grammar:

s:idf bloc_data mc_end   { printf ("programme juste (lexique+syntaxe)\n"); YYACCEPT;}
;
bloc_data:mc_data liste_data mc_end
|mc_data mc_end
;
liste_data : declar
|liste_data declar
;
declar: liste_const
|liste_type
;
liste_type:liste_type def_type
|def_type
;
def_type:mc_char ':' liste_var ';'
;
liste_var:idf
|liste_var '|' idf
;
liste_const:liste_const constante
|constante
;
constante:mc_const ':' idf affect entier ';'
;

It basically says that I could define characters along with constants in the DATA bloc

Here's my .output

État 11 conflits: 1 décalage/réduction
État 13 conflits: 1 décalage/réduction


Grammaire

0 $accept: s $end

1 s: idf bloc_data mc_end

2 bloc_data: mc_data liste_data mc_end
3          | mc_data mc_end

4 liste_data: declar
5           | liste_data declar

6 declar: liste_const
7       | liste_type

8 liste_type: liste_type def_type
9           | def_type

10 def_type: mc_char ':' liste_var ';'

11 liste_var: idf
12          | liste_var '|' idf

13 liste_const: liste_const constante
14            | constante

15 constante: mc_const ':' idf affect entier ';'
.
.
.

état 11

7 declar: liste_type .
8 liste_type: liste_type . def_type

mc_char  décalage et aller à l'état 7

mc_char   [réduction par utilisation de la règle 7 (declar)]
$défaut  réduction par utilisation de la règle 7 (declar)

def_type  aller à l'état 20


état 13

6 declar: liste_const .
13 liste_const: liste_const . constante

mc_const  décalage et aller à l'état 8

mc_const  [réduction par utilisation de la règle 6 (declar)]
$défaut  réduction par utilisation de la règle 6 (declar)

constante  aller à l'état 21

It says my shift/reduce conflicts are in State 11 & 13 but I couldn't figure out why exactly. It's supposed to recognize something like this:

DATA
CONST: Er=5;
CONST: H=56;
CHAR: Hg|rt;
END
有帮助吗?

解决方案

A liste_const is just a list of constante with no intervening punctuation:

constante constante constante constante

And a declar might be a liste_const

What then happens if you have a liste_data (which is really a liste_declar, no?). That could be a list of lists of constante, but there is no way to know where the first list of constante ends and the next one begins. So the above could be parsed as

<list_const <constante constante>> <list_const <constante>> <list_const <constante>>

or

<list_const <constante constante constante constante>>

or a large number of other possibilities.

The situation with liste_type is analogous.

In other words, you don't want a liste_data to be a list of lists of constants and types; you want it to be a list of (constant or type).

Personally, I'd just change:

declar: def_type | constante;

and get rid of liste_type and list_const.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top