> { $item[1] || $item[3] } but that would not work as the parser would
These two variables hold the TEXT that was matched by the appropriate rule. What you need to do is maintain a symbol table. (A hash, I believe you already have that). Then when you have a statement like (b|c) you would return {$return = $symbols{$item[1]} || $symbols{$item[2]}; 1;} The 1 is there only because I'm not really sure what your doing (I admit I didn't read your code that closely) and it ensure that the rule succeeds. You could avoid it if you knew for sure that $symbols{$item[1]} and [2] as well would return defined values. Actually on that note you might do something like this: (assuming that there is a declaration phase in your language, oh and this UNTESTED code in particular I cant remember if im using <error> correctly, check the docs.) my $grammar=<<'GRAMMER'; { # Init code for grammar... Handles a symbol table my %symbols; sub symbol_add{ my $symbol=shift; my $value =shift; if ($symbols{$symbol}) { warn "Attempt to declare $symbol more than once\n"; return undef; } $symbols{$symbol}=$value; return $value } sub symbol_fetch{ my $symbol=shift; unless (exists $symbols{$symbol}) { warn "Attempt to fetch from undeclared $symbol\n"; return undef; } return $symbols{$symbol} } sub symbol_store{ my $symbol=shift; my $value =shift; unless (exists $symbols{$symbol}) { warn "Attempt to store to an undeclared $symbol\n"; return undef; } $symbols{$symbol}=$value; return $value } } conjunction :l_identifier '|' r_identifier {$return=symbol_fetch($item{l_identifier})||symbol_fetch($item{r_identifier} )} |<error> declaration :'set' identifier '=' value {$return=symbol_add($item{identifier},$item{value});} | <error> l_identifier:identifier {$return=$item[1]} r_identifier:identifier {$return=$item[1]} identifier :/[A-Za-z]+/ value :/\w+/ GRAMMER BTW: This is basically how the red-dragon suggest one should handle symbols, (with a perlish flavour) HTH (even though it only addresses 1 line of your question) Yves