Related articles |
---|
When is a typedef name not a typedef name? jwl@sag4.ssl.berkeley.edu (1991-07-09) |
Re: When is a typedef name not a typedef name? henry@zoo.toronto.edu (1991-07-20) |
Re: When is a typedef name not a typedef name? mengel@fnal.fnal.gov (1991-07-31) |
Parsing C jar@florida.HQ.Ileaf.COM (1991-08-07) |
Newsgroups: | comp.lang.c,comp.compilers |
From: | mengel@fnal.fnal.gov (Marc W. Mengel) |
Followup-To: | comp.lang.c |
Summary: | reduce/reduce errors *can* be okay... |
Keywords: | C, parse |
Organization: | Compilers Central |
References: | 91-07-032 |
Date: | 31 Jul 91 16:39:57 GMT |
jwl@sag4.ssl.berkeley.edu (Jim Lewis) writes:
> ...the following code is legal:
>typedef int foo;
>struct bar { foo foo; };
...
>Rewriting the grammar seems hopeless -- every variation I've come up
>with resulted in reduce/reduce conflicts.
True, but if you look at the conflict, (i.e. in a simpler grammar
like
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
%token typename identifier struct
%%
declar_list
: declar
| declar_list declar
;
declar : type decl_list ';'
| type declar '{' '}'
;
type : typename
| struct '{' declar_list '}'
| /*empty*/
;
decl_list
: decl
| decl_list ',' declar
;
decl : typename
| identifier
| '*' decl
| '(' decl ')'
| decl '(' ')'
| decl '[' ']'
;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
which brings out the problem) the reduce/reduce conflict
you get is:
10: reduce/reduce conflict (red'ns 5 and 10 ) on (
state 10
type : typename_ (5)
decl : typename_ (10)
; reduce 10
, reduce 10
[ reduce 10
. reduce 5
which of course breaks code like
fred() {}
i.e. it tries to treat fred as a type, and chokes later. However
since yacc is mindless, if we move the 'decl' rule higher up
in the grammar than the 'type' rule, like
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
%token typename identifier struct
%%
declar_list
: declar
| declar_list declar
;
decl : typename
| identifier
| '*' decl
| '(' decl ')'
| decl '(' ')'
| decl '[' ']'
;
declar : type decl_list ';'
| type declar '{' '}'
;
type : typename
| struct '{' declar_list '}'
| /*empty*/
;
decl_list
: decl
| decl_list ',' declar
;
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
We get the opposite behavior, i.e.
10: reduce/reduce conflict (red'ns 3 and 11 ) on (
state 10
decl : typename_ (3)
type : typename_ (11)
( reduce 3
[ reduce 3
; reduce 3
, reduce 3
. reduce 11
we reduce to a declarator with a '(' in the lookahead, which
is what we really want. So the point is, even if you have
reduce/reduce errors, you can force yacc to pick one resolution
over the other by the order of your rules, and keep on rolling
along...
-------
Marc Mengel
mengel@fnal.fnal.gov
[Lest it not be obvious, this is a part of C syntax which is painfully
context dependent, which means that yacc cannot handle it without some sort
of kludge, be it a reduce/reduce conflict or more typically some sort of
ad-hoc code in the lexer. -John]
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.