[erlang-questions] Issues with Erlang's Yecc precedences
ccamacho
carloscamachoucv@REDACTED
Thu Jan 9 17:03:03 CET 2014
Hi list!!
First thanks for this information resource for learning Erlang XD..
I’m trying to write an Erlang parser with Yecc, but I’m having some troubles
with the precedence of the semantic rules. In my case I defined the grammar,
the terminal and non-terminal symbols, the rules and the associated code.
This is what I wrote for testing.
%File starts here stack.yrl
%Grammar non terminals
Nonterminals product require require1 mandatory mandatory1.
%Grammar terminals
Terminals 'tick' 'feature' '(' ')' 'req' 'mand' ';' 'nil'.
%Initial symbol
Rootsymbol product.
%Operands priority
Left 200 require.
Left 190 require1.
Left 180 mandatory.
Left 170 mandatory1.
Left 80 'req'.
Left 60 'mand'.
Left 50 ';'. %Secuence
Left 40 'feature'. %Optional feature
%--------------------------------------------------
%Grammar with operational rules
%[req1 & req2]
product -> require: '$1'.
require -> feature req feature '(' feature ';' product ')' : if
'$1' ==
'$5' -> {'$5', {'$4', '$7', '$8', {mand,1}, '$3'}};
true
-> {'$5', {'$1', '$2', '$3', '$4', '$7', '$8'}}
end.
%[req3]
product -> require1 : '$1'.
require1 -> feature req feature '(' tick ')' : {nil,1}.
%[mand2 & mand3]
product -> mandatory : '$1'.
mandatory -> '(' feature ';' product ')' mand feature : if
'$2' == '$7' ->
{'$2', {'$4'}};
true ->
{'$2',{'$1', '$4', '$5', '$6', '$7'}}
end.
%[mand1]
product -> mandatory1: '$1'.
mandatory1 -> '(' tick ')' mand feature : {$5, {tick,1}}.
%[tick]
product -> feature ';' tick : {'$1', {nil,1}}.
product -> nil.
product -> feature ';' product : {'$1', {'$3'}}.
Erlang code.
%To remove brackets and return only the third parameter, right now is not
used.
unwrap_feature({_,_,V}) -> V.
%%How to compile and use
%Save this as stack.yrl
%Run erl and then
%yecc:yecc("stack.yrl","stack.erl").
%c(stack).
%File ends here stack.yrl
Now lets execute a specific term to check how rules are applied.
stack:parse([{feature,1,'A'},{'req',1},{feature,1,'C'},{'(',1},{feature,1,'A'},{';',1},{feature,1,'B'},{';',1},{feature,1,'C'},{';',1},{tick,1},{')',1}]).
The parser output is:
{ok,{{feature,1,'A'},
{{'(',1},
{{feature,1,'B'},{{{feature,1,'C'},{nil,1}}}},
{')',1},
{mand,1},
{feature,1,'C'}}}}
But I need this. I’m writing the output as long the parser process the term
(like a debug output).
Initial term.
{feature,1,'A'},{'req',1},{feature,1,'C'},{'(',1},{feature,1,'A'},{';',1},{feature,1,'B'},{';',1},{feature,1,'C'},{';',1},{tick,1},{')',1}
Rule %[req1 & req2]. (This is applied correctly – Case '$1' == '$5')
{feature,1,'A'},{{'(',1},{feature,1,'B'},{';',1},{feature,1,'C'},{';',1},{tick,1},{')',1},{mand,1},{feature,1,'C'}}
Now, I don’t know what happens, but the output should be as this.
Rule %[mand2 & mand3]. (Case true)
{feature,1,'A'},{{feature,1,'B'},{{'(',1},{feature,1,'C'},{';',1},{tick,1},{')',1},{mand,1},{feature,1,'C'}}}
Rule %[mand2 & mand3]. (Case '$2' == '$7')
{feature,1,'A'},{{feature,1,'B'},{{feature,1,'C'},{{tick,1}}}}
Rule %[tick] – And final result.
{feature,1,'A'},{{feature,1,'B'},{{feature,1,'C'},{{{tick,1},{nil,1}}}}}
I already tried this:
As is explained in Yecc manual, I was able to do this:
Playing with the operator precedences.
Applying precedence to rules. From the documentation (It is also possible to
declare precedence for non-terminals, "one level up". This is practical when
an operator is overloaded (see also example 3 below)).
But it doesn’t seem to work for me. Any help???
Thanks!
--
View this message in context: http://erlang.2086793.n4.nabble.com/Issues-with-Erlang-s-Yecc-precedences-tp4655350.html
Sent from the Erlang Questions mailing list archive at Nabble.com.
More information about the erlang-questions
mailing list