How can I write a grammar that expresses a set of items that can appear zero or one times each, in any order?
e.g. A B C
is valid, A C
is valid, C B A
is valid, A A B
is invalid, A B A
is invalid.
This rule enforces zero or one of each element, but also enforces a set order:
rule_1: A? B? C?
This permits any order, but also permits more than one of each:
rule_2: (A | B | C)*
This is using the Lark parser for Python - I'm unsure if this question should be tagged [lark-parser]
?
(E)BNF handles context-free languages and a context-free language can't directly express that constraint. You have to do it explicitly like this left-factored form (others are possible but not meangingfully better)
opts = (A nonA | B nonB | C nonC)?
nonA = (B nonAB | C nonAC)?
nonB = (A nonAB | C nonBC)?
nonC = (A nonAC | B nonBC)?
nonAB = C?
nonAC = B?
nonBC = A?
which quickly becomes unmanageable as the number of things grows.