Best way to express recursive rules in yecc parsers

Hello,

When parsing a custom language I can define a list of expressions in the following way, inspired by the Elixir parser:

expr_list -> expr : ['$1'].
expr_list -> expr_list expr : ['$2' | '$1'].

The list is reversed later.

But the parsetools doc has an example where the recursion is inverse:

expr_list -> expr : ['$1'].
expr_list -> expr expr_list : ['$1' | '$2'].

In this case, no need to reverse.

I wonder what are the differences between the two forms. Are there specific cases where you would chose one over the other?

Thank you.

Pinging @rvirding to the rescue! Hope you do not mind :slight_smile:

Sorry, I can’t really help you here. I checked the Erlang syntax parser and it does something like this:

list -> '[' ']' : {nil,?anno('$1')}.
list -> '[' expr tail : {cons,?anno('$1'),'$2','$3'}.

tail -> ']' : {nil,?anno('$1')}.
tail -> '|' expr ']' : '$2'.
tail -> ',' expr tail : {cons,first_anno('$2'),'$2','$3'}.

Though in the cases I could see there is a separator between the elements. Though I don’t think the extra reverse would normally cost much.

Alright thank you :slight_smile:

I don’t mind the cost of reverse, it’s just that I am not sure how declaring recursive rules works in regard to other rules. For now it seems to be equally working. Let’s see someday if I add more clauses that would make expr more complicated.