Пример: -(*(+(4,3),5),/(4,9)) => 4 3 + 5 * 4 9 / -
predicates
deistvie(string,string,real)
razdelit(string,string,string)
zakr(string,string,string)
poschitat(string,real,real,real)
clauses
/* Выбираем знак действия, раскладываем выражение на два аргумента и собираем в требуемый вид */
deistvie(S,S2,R):-
frontstr(1,S,Z,ST),
frontchar(ST,'(',SK),
str_len(SK,P),
P1=P-1,
substring(SK,1,P1,S1),
razdelit(S1,AR1,AR2),
deistvie(AR1,S3,R1),
deistvie(AR2,S4,R2),
concat("(",S3,S5),
concat(S5,Z,S6),
concat(S6,S4,S7),
concat(S7,")",S2),
poschitat(Z,R1,R2,R).
deistvie(S,S,R):-str_real(S,R).
/* Подсчет арифметических действий */
poschitat("+",R1,R2,R):-R=R1+R2.
poschitat("-",R1,R2,R):-R=R1-R2.
poschitat("*",R1,R2,R):-R=R1*R2.
poschitat("/",R1,R2,R):-R=R1/R2.
/* Поиск запятой разделяющей аргументы с учетом парных скобок */
razdelit(S,AR1,AR2):-frontchar(S,'(',S1),
zakr(S1,S2,S3),
concat("(",S2,S5),
razdelit(S3,S4,AR2),
concat(S5,S4,AR1).
razdelit(S,"",AR2):-frontchar(S,',',AR2).
razdelit(S,AR1,AR2):-frontstr(1,S,C,S1),
razdelit(S1,S2,AR2),
concat(C,S2,AR1).
/* Поиск закрывающей скобки */
zakr(S,AR1,AR2):-frontchar(S,'(',S1),
zakr(S1,S2,S3),
concat("(",S2,S5),
zakr(S3,S4,AR2),
concat(S5,S4,AR1).
zakr(S,")",AR2):-frontchar(S,')',AR2).
zakr(S,AR1,AR2):-frontstr(1,S,C,S1),
zakr(S1,S2,AR2),
concat(C,S2,AR1).
/* и собсно цель программы */
goal deistvie("-(*(+(1,2),3),/(4,5))",S,R),write(S," = ",R),nl.
|