我编写了一个程序,它将解析树作为输入并对其进行评估。它在树中的标识符不再出现时起作用。我希望评估者接受多个语句,并在我解决后面的语句时使用分配给标识符的值。这是我的程序。
add_op --> ['+'].
assign_op --> ['='].
ident(ident(Ident)) --> [Ident], {atom(Ident)}. /* True if an identifier */
int(int(Int)) --> [Int], {integer(Int)}. /* True if an integer */
semicolon --> [';'].
evaluator(statements(Assignment),VariablesOut):-
evaluator(Assignment,VariablesOut).
evaluator(statements(Assignment,Statements),VariablesOut):-
evaluator(Assignment,List1),
evaluator(Statements,List2),
merge(List1,List2,VariablesOut).
evaluator(assignment(ident(Ident),assign_op,int(Int),add_op,int(Int2),semicolon),Answer5):-
Answer2 is Int + Int2,
atom_concat(Ident,' = ',Answer1),
atom_concat(Answer1,Answer2,Answer3),
read_term_from_atom(Answer3, (Answer4), []), /*removes quotation marks*/
Answer5 = [Answer4].
以下执行使用解析树 a = 2 + 3 ;b = 3 + 4 ; 此执行有效,因为我的程序仅评估 a 和 b 的答案,而 b 的评估不包含 a。
evaluator(statements(assignment(ident(a), assign_op, int(2), add_op, int(3), semicolon), statements(assignment(ident(b), assign_op, int(3), add_op, int(4), semicolon))), Answer).
Answer = [a=5, b=7].
以下使用解析树 a = 2 + 3 ;b = a + 4 ;
这个不起作用,因为 b 必须是 4 添加到 a 的结果,并且 a 没有在程序中分配给值 5。
evaluator(statements(assignment(ident(a), assign_op, int(2), add_op, int(3), semicolon), statements(assignment(ident(b), assign_op, int(a), add_op, int(4), semicolon))), Answer).
ERROR: Arithmetic: `a/0' is not a function
ERROR: In:
ERROR: [11] _2952 is a+4
...
更新
我找到了一个类似的解决方案,但我不确定它是如何工作的。我不知道在哪里进行任何评估,也看不到 maplist 和 WithSym =.. 行是如何需要的。
exp_symbols(Symbols, Expr, WithSym) :-
Expr =.. [F|Args], /*F is sent to the first element of Expr which in my case would be a = 5 */
( member(F=V, Symbols) -> G = V ; G = F ), /* if F followed by a colon and some element V is in the equation, set G to be assign to both V and F */
maplist(exp_symbols(Symbols), Args, ArgsSWithSym), /*perform the current function on all elements left **/
WithSym =.. [G|ArgsSWithSym]. /** Set WithSym to be the first element in ArgsSWithSym /**
evaluate(Exp, LstVars, Val) :-
exp_symbols(LstVars, Exp, NewExp),
Val is NewExp.