Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parsing function application with Happy

How would I parse something like

f x y

Into

APPLY (APPLY f x) y

using Happy? Right now I have a rule that says

%left APP
Expr : Expr Expr %prec APP { APPLY $1 $2 }

But that parses the above as

APPLY f (APPLY x y)
like image 374
spacepotato Avatar asked Apr 30 '26 08:04

spacepotato


1 Answers

The accepted answer is not satisfactory.

The correct way of solving this problem is:

%nonassoc VAR LPAREN -- etc...
%nonassoc APP

Expr : Expr Expr %prec APP { APPLY $1 $2 }

That is:

  • Adding a ghost precedence token called APP, and no need to make it left or right since it won't be relevant, so you can keep it nonassoc to not get the wrong intuition that it matters

  • Marking your Expr rule with %prec APP like you did

  • and most importantly and often forgotten, you need to give all tokens that may appear as the first token of an Expr production a precedence lower than that of APP, usually achieved by listing them somewhere above, either with left, right, or nonassoc for the ones that don't associate

The reason why your trial failed is probably that you missed the last step.

The reason why the last step is needed is that the algorithm, in deciding whether to shift the next token or to reduce the APP rule, will compare the precedence of the APP rule with the precedence of the incoming token. And by default, tokens that you don't mention have high precedence. So when faced with:

Expr Expr . LPAREN VAR RPAREN

for instance, it would compare the precedence of the APP rule (to reduce), with the precedence of LPAREN (to shift), and unless you set it up correctly, it will shift, and do the wrong thing.


Staging your grammar is just ugly and unpleasant.

like image 132
Ptival Avatar answered May 03 '26 16:05

Ptival