Expression Syntax

The expressions that can be formed depend on the operators and their levels that have been defined as follows. The system can distinguish prefix, infix and postfix operators. The arguments of an operator have to be on a lower or equal level than the operator itself so that parsing is successful. The exact operator type further determines the acceptability and associativity of the operator.

expression(M) --> "(" term(1200) ")" { M=0 }
| "(" ")"
| op1(M,fx) term(M-1)
| op1(M,fy) term(M)
| term(M-1) op2(M,xfx) term(M-1)
| term(M-1) op2(M,xfy) term(M)
| term(M) op2(M,yfx) term(M-1)
| term(M-1) op2(M,xf)
| term(M) op2(M,yf).

op1(M,I) --> atom(O) { current_op(M,I,O) }.

op2(M,I) --> operator(O) { current_op(M,I,O) }.

Names, either quoted or unquoted, can be used as operators. Since the empty set {} and the empty list [] do belong to the category of atoms they can be used as an operator as well. Additionally the comma (“,”), the vertical bar (“|”) and the period (“.”) can also be used as an infix or postfix operator without quoting them. Whether a certain atom or operator can be used further depends on the built-in op/3 which might refuse certain definitions.

- 5              % is a prefix expression, corresponds to –(5)
5 + 6        % is an infix expression, corresponds to +(5, 6)
5 days       % is a postfix expression, corresponds to days(5)
assertz((p :- q) % is a compound
mode(+, -)      % is a compound

The parenthesis (“()”) serves to circumvent the level rule of the operators. Arguments from compounds and lists have the level 999. To use higher level operators as arguments, we therefore have to put them in parenthesis. The operator detection itself can be escaped when the operator directly precedes a stop character.