Dank @vladimir lidovski und basierend auf der BNF-Notation (und auf meinen Bedürfnissen) habe ich sie erweitert, um auch logische Ausdrücke einzubeziehen. Hier ist mein Code (Um den vollständigen Interpreter zu sehen, besuchen Sie meine Trottelpaket ):
cond_expre(T) --> and_expre(E1), or_rest(E1,T).
or_rest(E1,T) --> [punct('|'),punct('|')],!, and_expre(E2), {V = (\/,E1,E2)}, or_rest(V,T).
or_rest(T,T) --> [].
and_expre(T) --> equality_expre(E1), and_rest(E1,T).
and_rest(E1,T) --> [punct(&),punct(&)], !, equality_expre(E2), {V = (/\,E1,E2)}, and_rest(V,T).
and_rest(T,T) --> [].
equality_expre(T) --> relat_expre(E1), equality_rest(E1,T).
equality_rest(E1,T) --> equality_op(Op) ,!, relat_expre(E2), { V=(Op,E1,E2)}, equality_rest(V,T).
equality_rest(T,T) --> [].
relat_expre(T) --> atomic_texpre(E1), relat_rest(E1,T).
relat_rest(E1,T) --> relat_op(Op) ,!, atomic_texpre(E2) , { V=(Op,E1,E2) },relat_rest(V,T).
relat_rest(T,T) --> [].
atomic_texpre(T) --> arith_expre(T); [punct('(')], !, cond_expre(T), [punct(')')] .
arith_expre(V) --> expre(V).
equality_op(==) --> [punct(=),punct(=)].
equality_op(\=) --> [punct(!),punct(=)].
relat_op(>=) --> [punct(>),punct(=)].
relat_op(>) --> [punct(>)].
relat_op('=<') --> [punct(<),punct(=)].
relat_op(<) --> [punct(<)].
expre(N) --> multiplicative(N1), additive_rest(N1,N).
additive_rest(N1,N) --> [punct('+')], !, multiplicative(N2), {N3 = (+,N1,N2)}, additive_rest(N3,N);
[punct('-')], !, multiplicative(N2), {N3 = (-,N1,N2)}, additive_rest(N3,N).
additive_rest(N,N) --> [].
multiplicative(N) --> atomic(N1), multiplicative_rest(N1,N).
multiplicative_rest(N1,N) --> [punct('*')], !, atomic(N2), {N3 = (*,N1,N2)}, multiplicative_rest(N3,N);
[punct('/')], !, atomic(N2), {N3 = (/,N1,N2)}, multiplicative_rest(N3,N);
[punct('%')], !, atomic(N2), {N3 = (mod,N1,N2)}, multiplicative_rest(N3,N).
multiplicative_rest(N,N) --> [].
atomic(N) --> [punct('(')], !, expre(N), [punct(')')]; num(N).
num(N) --> pl_constant(N).
pl_constant(num(N)) --> pl_integer(N), !.
pl_constant(id(X)) --> identifier(X), {call(id(X,_)) }. %Not sure if I remember what it does but I think, the right most call I wrote to assure that the variable is already registered in the cache so that a value can later be retrieved from it
pl_integer(X) --> [number(X)]. %the value on the right works together with a tokenizer library -> :- use_module(library(tokenize)). It's basically a token labled as a number. Same with the next line.
identifier(X) --> [word(X)].
0 Stimmen
Ihre Grammatik behandelt den Vorrang von Operatoren nicht korrekt, da sie immer von links nach rechts parst. Versuchen Sie zu parsen
[5, *, 4, +, 7]
und überprüfen Sie den resultierenden Wert.