你好的程序员,
我在happy(haskell)中构建了以下语法:
P : program C {Prog $2}
E : int {Num $1}
| ident {Id $1}
| true {BoolConst True}
| false {BoolConst False}
| read {ReadInput}
| '(' E ')' {Parens $2}
| E '+' E { Add $1 $3 }
| E '-' E { Sub $1 $3 }
| E '*' E { Mult $1 $3 }
| E '/' E { Div $1 $3 }
| E '=' E { Eq $1 $3 }
| E '>' E { Gt $1 $3 }
| E '<' E { Lt $1 $3 }
C : '(' C ')' {$2}
| ident assign E {Assign $1 $3}
| if E then C else C {Cond $2 $4 $6}
| output E {OutputComm $2}
| while E do C {While $2 $4 }
| begin D ';' C end {Declare $2 $4}
| C ';' C {Seq $1 $3 }
D : D ';' D {DSeq $1 $3 }
| '(' D ')' {$2}
| var ident assign E {Var $2 $4}
现在,While循环包含'do'之后的所有命令。如何改变这种行为?我已经尝试了%左,右对...... :(
答案 0 :(得分:2)
发明两种C
,一种允许排序,另一种不允许。这样的事情,也许是:
Cnoseq : '(' Cseq ')'
| ident assign E
| while E do Cnoseq
Cseq : Cnoseq ';' Cseq
| Cnoseq
答案 1 :(得分:2)
考虑以下代码片段:
while True do output 1 ; output 2
这可以解析为
(while True do output 1) ; (output 2)
或
while True do (output 1 ; output 2)
这种含糊不清是冲突的根源。
如果您不想像@DanielWagner建议的那样更改语法,可以使用precedence rules来解决歧义。究竟如何取决于优先级应该是什么,但它可能是这样的:
%right do
%right then else
%right ';'
优先级从低到高列出,因此在这种情况下,上述示例将以后一种方式进行解析。只需在令牌下方但在%%
行之前添加优先规则。