0

I have the following minimized grammar

Exp : let var '=' Exp in Exp end                     { App (Fn $2 $6) $4 }
    | Exp Exp                                        { App $1 $2 }
    | Exp OpCode Exp                                 { Op $1 Add $3 }
    | '(' Exp ')'                                    { $2 }
    | num                                            { Num $1 }
    | var                                            { Ident $1 }
    | '\\' var '.' Exp                               { Fn $2 $4 }

The Exp Exp rule is used to apply a function in a value. But if I have something like myFunc 1 2 it defaults to precendence myFunc (1 2), which is not what I want. I want (myFunc 1) 2, for currying.

But how can I define the association if I don't have a non-terminal symbol? Trying to do %left Exp don't seems to help.

fotanus
  • 19,618
  • 13
  • 77
  • 111

1 Answers1

1

You can't really apply precedence or associativity unless you have a terminal to shift, because precedence and associativity rules are used to resolve shift/reduce conflicts. You don't necessarily need a terminal in the reduction, so you could use a fake terminal and write:

Exp: Exp Exp %prec CURRY

But that won't help you because there is no terminal to compare precedence with. Precedence relations are always a comparison between the precedence of the lookahead symbol (a terminal) and possible reductions (by default, the precedence of a reduction is based on the rightmost terminal in the rule, but as above you can explicitly specify).

Since you can't do it the short-hand way, you need to fallback to the old-fashioned style where you write an unambiguous grammar with explicit precedence rules:

Curry: Term
     | Curry Term

(That's left-associative, by the away. If func 1 2 is parsed as ((func 1) 2), then application is associating to the left.)

Assuming that infix binds tighter than application, you'd then have:

Term: Value
    | Term Opcode Value

Value: '(' Exp ')'
     | num
     | var

Exp: Curry

(You'll have to figure out how to integrate lambdas into that. It depends on how you expect them to group, but hopefully the model above is clear.)

rici
  • 234,347
  • 28
  • 237
  • 341
  • Why do you use Term, Value and Exp? Can you point me something to read to help me organize better my grammar? – fotanus May 19 '15 at 05:20
  • @fotanus: Because I wasn't planning ahead. The names are really irrelevant: in complex grammars, I just number them. But they are essentially different precedence levels. Here's an example of a C grammar with precedence fully written out: http://www.lysator.liu.se/%28nobg%29/c/ANSI-C-grammar-y.html – rici May 19 '15 at 05:41