First of all, this is a homework. I have to make a program which can parse the language described here: http://www.cs.princeton.edu/courses/archive/spring12/cos320/resources/fun_language_definition.html
This is an example of the Fun language:
fun id(x:<int,int>):<int,int> = x
fun main(arg:int):int = id(3)
This should be parsed as:
[((1,1),(id"id",id"x",Tupletp([Inttp,Inttp]),Tupletp([Inttp,Inttp]),Id(id"x"))),
((2,1),(id"main",id"arg",Inttp,Inttp, Call (Id(id"id"),Int 3)))]
I will give a snapshot of some part of my code:
prog: fundeclist EOF (fundeclist)
fundeclist: fundec ([fundec])
| fundeclist fundec (fundeclist @ [fundec])
fundec: FUN ID LPAREN ID COLON ftype RPAREN COLON ftype EQ exp
( ((FUNleft, expright), (Symbol.symbol ID1,
Symbol.symbol ID2, A.Inttp, A.Inttp, exp)) ) (* FIXME types *)
exp:
LPAREN exp RPAREN (exp)
| ID (A.Pos((IDleft, IDright),
A.Id (Symbol.symbol(ID)) ))
| INT (A.Pos((INTleft,INTright),
A.Int(INT)))
Exp will then continue with all kinds of expression possible in Fun language. I also have some upper part where I declare the terminals, non-terminals, assoc rules.
Now the biggest issue I am running into are these SML messages right after compiling my code:
fun.grm.sml:342.60-346.5 Error: operator and operand don't agree [tycon mismatch]
operator domain: unit -> Absyn.prog
operand: unit -> unit
in expression:
prog (fn _ => let val <binding> in fundeclist end)
fun.grm.sml:362.6-362.27 Error: operator and operand don't agree [tycon mismatch]
operator domain: 'Z list * 'Z list
operand: unit * Absyn.fundec list
in expression:
fundeclist @ fundec :: nil
val it = false : bool
Is it something wrong in the way I use my non-terminals? What does this error usually say, in parsing? This error was propagating from bottom to top so I've been trying all kinds of replacements with dummy values to make the error disappear - until I got here. How to fix this?
I finally found the error. (may be useful for others)
The %nonterm declarations for fundec and fundeclist were wrong. I was just omitting the token "of ..." to specify that fundec/ fundeclist actually have a value.
Correct version:
My initial version:
Obviously, fundec and fundeclist's values were unit in that case.