P => Program K => Block
S => Single-command
C => Commands
E => Expression
B => Boolean-expr
I => Identifier
N > Numeral
Prolog evaluates top down, then LL grammar techniques can be adapted. DCG are more powerful than LL(1), but left recursion must still be eliminated.
B
is easier to handle: left factor the production.
B ::= E Bx | not B | (B)
Bx ::= = E | > E | < E | != E | and B | or B
E is harder, because the miss mul
token introduces still more ambiguity. Tentatively
E ::= − E | (E) | I | N | El
El ::= Ex E | epsilon
Ex ::= + El | − El | div El | mod El
epsilon (empty production) in DCG can be written this way
epsilon --> [].
If you need to handle precedence and associativity (in both B and E) you will need more work. You can refer to this older answer for a working schema.