My question is: Is it possible to safely and cleanly use inherited attributes
within the yacc grammar?
Here's a simple grammar to illustrate what I mean:
(get an integer as either x<hex> or <decimal>)
integer has two values: base is inherited which indicates the base to evaluate
and value which is the value of the integer evaluated.
digit has a single value, the value of the digit.
Convention to unambiguate multiple instances of the same name in the
attribute calculations is to number them 1-n left to right.
number -> "x" integer { integer.base = 16; number.value = integer.value }
-> integer { integer.base = 10; number.value = integer.value }
integer -> digit { integer.value = digit.value }
-> integer digit { integer2.base = integer1.base;
integer1.value = integer2.value * integer1.base
+ digit.value }
digit -> "0" { digit.value = 0 }
.
.
.
digit -> "f" { digit.value = 15 }
---
Granted this is a poor grammar but it does illustrate the concept. Also,
i'm fully aware that this can be accomplished more easily by the use of a
global variable. However, i'm wondering if there is a general way to
make use of inherited attributes within yacc.
Thank you in advance for any advice,
Chris.
[As far as I can tell the answer is "no". The largest part of the problem is
that since yacc is by nature bottom up, you need to introduce hackery in
order to do anything at all in an upper level rule before reducing the lower
level rules. -John]
--
Send compilers articles to comp...@iecc.com,
meta-mail to compiler...@iecc.com.
As a matter of fact, I've recently written a short paper on how to do this.
It does require a hack, but not an obnoxious one, IMO.
I've sent the paper to SIGPLAN Notices, but haven't heard anything about when,
if ever, it might appear. So I'll try to make it available by FTP. I'll post
here again when I've done this.
--
- Allan Stavely, New Mexico Tech, USA
This will involve a lot of dirty tricks (globals etc) in Yacc.
If you need to use inherited attributes and if you would like
to use some other parser generator, try PCCTS. (see
comp.compilers.tools.pccts for details).
This is a (top down parser)-generator that is more or less designed
to make life easy using inherited attributes.
Jan
Depends on what you call cleanly and safely...
... It can be done, and I think any real compiler project using some kind
of yacc will do it. In yacc the way is provided by two things:
1. "Epsilon"-derivations with an action rule, embedded in right sides (not
only at the end)
2. Looking into the stack with negative indices (e.g. $<type>-2) gives you
access to "inherited" attributes.
> (get an integer as either x<hex> or <decimal>)
in yacc syntax (forgive typos, it's some years I last used yacc)
your grammar may become something like:
number: base integer { $$ = $2; }
base: "x" { $$ = 16; }
| { $$ = 10; }
integer: digit
| integer digit { $$ = $1 * $0 + $2 ;
/* $ 0 refers to left context of rule namely base*/ }
> Granted this is a poor grammar but it does illustrate the concept. Also,
> i'm fully aware that this can be accomplished more easily by the use of a
> global variable. However, i'm wondering if there is a general way to
> make use of inherited attributes within yacc.
If you are interested I can try to dig out my modula2 front end, where I
have made heavy use of negative indices for inherited attributes like
record field offsets.
--
+ Peter Sommerlad email: Peter.S...@zfe.siemens.de +
+ ZFE T SE 4 phone: +49-89-636-48148 +
+ Siemens AG fax: +49-89-636-45111 +
+ Otto-Hahn-Ring 6 +
+ D-81739 Munich +
As a matter of fact, I've recently written a short paper on one way of doing
this. It does require a hack, but not an obnoxious one, IMO.
I've made the paper available for ftp at ftp.cs.nmt.edu , in the directory
pub.al . It's in either dvi or ps format, in files inherit.dvi and inherit.ps
respectively.
--
- Allan Stavely, New Mexico Tech, USA
number : digit {$$.base= 10; $$.value= $1;}
| 'x' digit {$$.base= 16; $$.value= $2;}
| number digit {$$.base= $1.base; $$.value= $1.value*$1.base+$2;}
;