Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
437 views
in Technique[技术] by (71.8m points)

compilation - Prolog evaluator that uses previously solved information as input

I have written a program that takes a parse tree as input and evaluates it. It works when the identifiers in the tree do not reoccur. I want the evaluator to take in multiple statements, and use the values assigned to identfiers when I solve later statements. Here is my program.

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].

The following execution uses a parse tree for a = 2 + 3 ; b = 3 + 4 ; This execution works because my program is only evaluating the answers to a and b, and the evaluation of b does not contain 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].

The following uses a parse tree for a = 2 + 3 ; b = a + 4 ;
This one does not work, because b must be the result of 4 added to a, and a is not assigned to the value 5 within the program.

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
...

Update

I found a similar solution, but I'm not sure exactly how it works. I don't know where any evaluation is happening and I don't see how the maplist and WithSym =.. lines are needed.

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.
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...