Domains
CharList = Char *
Operator = plus; minus; multiply; divide
Bracket = left; right
Token = identifier(Char); operator(Operator); bracket(Bracket)
TokenList = Token *
Operand = variable(Char); operation(Operation)
OperationType = addition; subtraction; multiplication; division
Operation = operation(OperationType, Operand, Operand)
Predicates
StringToCharList(String, Charlist)
SkipSpaces(CharList, CharList)
IsLetter(Char)
IdentifyToken(Char, Token)
CharListToTokenList(CharList, TokenList)
IsLowPriority(OperationType)
TokenListToBracket(TokenList, Bracket, TokenList)
TokenListToOperand(TokenList, Operand, TokenList)
TokenListToOperationType(TokenList, OperationType, TokenList)
TokenListToPrioritySequence(Operand, TokenList, Operand, TokenList)
TokenListToPriority(TokenList, Operand, TokenList)
TokenListToExpressionSequence(Operand, TokenList, Operand, TokenList)
TokenListToExpression(TokenList, Operand, TokenList)
OperandToString(Operand, String)
OperationTypeToString(OperationType, String)
OperationToString(Operation, String)
Calculator()
Clauses
StringToCharList("", []) :- !.
StringToCharList(S, [H | T]) :-
frontchar(S, H, ST),
StringToCharList(ST, T).
SkipSpaces([], []) :- !.
SkipSpaces([C | T1], T2) :- C = ' ', SkipSpaces(T1, T2), !.
SkipSpaces([C | T1], [C | T2]) :- SkipSpaces(T1, T2).
IsLetter(C) :- C >= 'a', C <= 'z', !.
IsLetter(C) :- C >= 'A', C <= 'Z'.
IdentifyToken(C, identifier(C)) :- IsLetter(C), !.
IdentifyToken('+', operator(plus)).
IdentifyToken('-', operator(minus)).
IdentifyToken('*', operator(multiply)).
IdentifyToken('/', operator(divide)).
IdentifyToken('(', bracket(left)).
IdentifyToken(')', bracket(right)).
CharListToTokenList([], []).
CharListToTokenList([CLH | CLT], [TLH | TLT]) :- IdentifyToken(CLH, TLH), CharListToTokenList(CLT, TLT).
IsLowPriority(addition).
IsLowPriority(subtraction).
TokenListToBracket([bracket(B) | TLT], B, TLT).
TokenListToOperand([identifier(C) | TLT], variable(C), TLT) :- !.
TokenListToOperand(TL1, O, TL) :-
TokenListToBracket(TL1, left, TL2),
TokenListToExpression(TL2, O, TL3),
TokenListToBracket(TL3, right, TL).
TokenListToOperationType([operator(plus) | TLT], addition, TLT).
TokenListToOperationType([operator(minus) | TLT], subtraction, TLT).
TokenListToOperationType([operator(multiply) | TLT], multiplication, TLT).
TokenListToOperationType([operator(divide) | TLT], division, TLT).
TokenListToPrioritySequence(O1, TL, O, TLT) :-
TokenListToOperationType(TL, OT, TLT1),
not(IsLowPriority(OT)),
TokenListToOperand(TLT1, O2, TLT2),
TokenListToPrioritySequence(operation(operation(OT, O1, O2)), TLT2, O, TLT), !.
TokenListToPrioritySequence(O, TL, O, TL).
TokenListToPriority(TL, O, TLT) :-
TokenListToOperand(TL, O1, TLT1),
TokenListToPrioritySequence(O1, TLT1, O, TLT), !.
TokenListToPriority(TL, O, TLT) :- TokenListToOperand(TL, O, TLT).
TokenListToExpressionSequence(O1, TL, O, TLT) :-
TokenListToOperationType(TL, OT, TLT1),
IsLowPriority(OT),
TokenListToPriority(TLT1, O2, TLT2),
TokenListToExpressionSequence(operation(operation(OT, O1, O2)), TLT2, O, TLT), !.
TokenListToExpressionSequence(O, TL, O, TL).
TokenListToExpression(TL, O, TLT) :-
TokenListToPriority(TL, O1, TLT1),
TokenListToExpressionSequence(O1, TLT1, O, TLT), !.
TokenListToExpression(TL, O, TLT) :-
TokenListToPriority(TL, O, TLT).
OperandToString(variable(C), S) :- str_char(S, C), !.
OperandToString(operation(O), S) :- OperationToString(O, S).
OperationTypeToString(addition, "ADD").
OperationTypeToString(subtraction, "SUB").
OperationTypeToString(multiplication, "MUL").
OperationTypeToString(division, "DIV").
OperationToString(operation(OT, O1, O2), S) :-
OperationTypeToString(OT, SOT),
OperandToString(O1, SO1),
OperandToString(O2, SO2),
format(S, "%(%,%)", SOT, SO1, SO2).
Calculator() :-
readln(IS),
StringToCharList(IS, CL),
SkipSpaces(CL, CL_WS),
CharListToTokenList(Cl_WS, TL),
TokenListToExpression(TL, O, []),
OperandToString(O, OS),
write(OS), nl,
readchar(_).
Goal
Calculator().