I'm taking a class in software semantics, and we are supposed to create a small compiler and runtime for a toy language called while. We were given a code skeleton for Java, but we are allowed to use whatever language we want. I saw this as an opportunity to rehearse grammars, and thought it'd be cool to do the lab in C++ instead.
Now, I'm having some problems setting up the precedence rules for my statements. Here is my BNFC grammar file right now:
SSkip. Stmt ::= "skip";
SAss. Stmt ::= VarName ":=" AExp;
SIf. Stmt1 ::= "if" BExp "then" Stmt "else" Stmt;
SWhile. Stmt1 ::= "while" BExp "do" Stmt;
SComp. Stmt ::= Stmt ";" Stmt;
coercions Stmt 1;
token VarName (letter (letter | digit) *);
EAdd. AExp ::= AExp "+" AExp1;
ESub. AExp ::= AExp "-" AExp1;
EMul. AExp1 ::= AExp1 "*" AExp2;
EDiv. AExp1 ::= AExp1 "/" AExp2;
EInt. AExp2 ::= Integer;
EVar. AExp2 ::= VarName;
coercions AExp 2;
BTrue. BExp1 ::= "true";
BFalse. BExp1 ::= "false";
BNeg. BExp ::= "not" BExp;
BConj. BExp ::= BExp "and" BExp;
BLeq. BExp ::= AExp "<=" AExp;
coercions BExp 1;
What I want is the input
while true do skip; x:=y
to be parsed according to my compound rule into something like
(SComp [SWhile [BTrue] [SSkip]] [(SAss "x" [EVar "y"])])
That is, I want the assignment to not be part of the loop body. However, what I get is
(SWhile [BTrue] [(SComp SSkip (SAss "x" [(EVar "y")]))])
As you can see, the body of the while-loop consists of the compound statement, which is not what I wanted. How should I set up my precedence rules to reach this effect?
It turns out I had misunderstood my assignment, sort of. The precedence rules I described are the ones presented in my course book, but since my primary concern is being compatible with the parser we were given from the teacher, I tried it on the code above, and it parses the assignment into the body as well.
The program I wanted to write should "simply" have been:
(while true do skip) ; x := y
But hey, at least it's compatible!