如何为这样的抽象语法树构建解释器



cal(cal(1, plus, 2), minus, 3)我需要从中得到一个结果。我该怎么做?我被prolog伤害了。T.T

AST 是通过调用以下内容生成的:

?- calculations(Tree,[1,+,2,-,3],[]).
Tree = cal(cal(1, plus, 2), minus, 3) .

在以下 DCG 代码上:

calculations(VV) --> 
    vv(VV).
calculations(ResultTree) --> 
    vv(VV1), more_calculations(VV1,ResultTree).
more_calculations(VV1,cal(VV1,Operator,VV2)) --> 
    more_calculation(Operator,VV2).
more_calculations(VV1,ResultTree) -->
    more_calculation(Operator1,VV2),
    more_calculations(cal(VV1,Operator1,VV2),ResultTree).   
more_calculation(Operator,VV) --> 
    operator(Operator),vv(VV).
vv(Name) --> var_name(Name).
vv(Value) --> var_value(Value).
operator(plus) --> [+].
operator(minus) --> [-].
var_name(Name) -->
   [Name],{check_name(Name),+member(Name,[write,read,begin,end,while])}.
var_value(Value) -->[Value],{number(Value)}.
check_name(N):-
    catch(atom_chars(N, L), _, fail),
    is_lower(L).
is_lower([]).
is_lower([H|T]) :-
    catch(char_type(H, lower), _, fail),
     is_lower(T).

有很多方法可以做到这一点,这取决于你正在做的事情和你的目标是什么。但这里有一种可能性:

evaluate(cal(X, Op, Y), Result) :-
    evaluate(X, Xr),
    evaluate(Y, Yr),
    Exp =.. [Op, Xr, Yr, Result],
    call(Exp).
evaluate(X, X) :- number(X).
plus(X, Y, R) :- R is X + Y.
minus(X, Y, R) :- R is X - Y.

evaluate/2假设您向其传递看起来像数字或cal/3的东西,其中要cal/3的参数分别是操作数、运算符和另一个操作数。您编写一个谓词来评估每个单独的运算符,它们假定操作数已减少为数字。

例:

evaluate(cal(cal(2, plus, 3), minus, 8), Result).

给:

Result = -3.

在所述示例中:

| ?- calculations(Tree,[1,+,2,-,3],[]), evaluate(Tree, Result).
Result = 0
Tree = cal(cal(1,plus,2),minus,3) ? a
no

最新更新