我必须编写 parse(Tkns, T) ,它接受标记列表形式的数学表达式并找到 T,并返回表示抽象语法的语句,尊重操作顺序和关联性。
例如,
?- parse( [ num(3), plus, num(2), star, num(1) ], T ).
T = add(integer(3), multiply(integer(2), integer(1))) ;
No
我尝试按如下方式实现 + 和 *
parse([num(X)], integer(X)).
parse(Tkns, T) :-
( append(E1, [plus|E2], Tkns),
parse(E1, T1),
parse(E2, T2),
T = add(T1,T2)
; append(E1, [star|E2], Tkns),
parse(E1, T1),
parse(E2, T2),
T = multiply(T1,T2)
).
它找到了正确的答案,但也返回不遵循关联性或运算顺序的答案。
ex)
parse( [ num(3), plus, num(2), star, num(1) ], T ).
也返回
mult(add(integer(3), integer(2)), integer(1))
and
parse([num(1), plus, num(2), plus, num(3)], T)
返回 1+2+3 和 1+(2+3) 的等价物,而它应该只返回前者。
有什么方法可以让它发挥作用吗?
编辑:更多信息:我只需要实现 +、-、*、/、否定(-1、-2 等),并且所有数字都是整数。给出了一个提示,代码的结构将类似于语法
<expression> ::= <expression> + <term>
| <expression> - <term>
| <term>
<term> ::= <term> * <factor>
| <term> / <factor>
| <factor>
<factor> ::= num
| ( <expression> )
仅也实施了否定。
Edit2:我发现了一个用 Prolog 编写的语法解析器(http://www.cs.sunysb.edu/~warren/xsbbook/node10.html)。有没有一种方法可以修改它以打印语法的左手推导(“打印”是指 Prolog 解释器将输出“T=[正确答案]”)