Search code examples
parsinggrammarantlr4pegpegjs

PEG grammar which accepts three optional elements in any order


Let's assume we have three elements a b and c.

A valid expression uses these three elements (and optional whitespace).

  1. At least one of these three elements has to be present.
  2. All three elements are optional (as long as at least one of the other two elements is present, see 1).
  3. The order in which these three elements are supplied is not important.

Is there an idiomatic way to write a PEG grammar that meets these three requirements?

I played with peg.js at http://pegjs.org/online and solved (1) (lookahead) and (2), but (3) eludes me. Any suggestions?

e = &(a / b / c) (a? b? c?) 

a = 'a' _
b = 'b' _
c = 'c' _

_ = [ \t]*

Solution

  • Really the only possibility is to list all six possible orders, because PEG does not have an "unordered permutation" operator. (And neither do traditional context free grammars, so roughly the same procedure is necessary.

    For example, you could use:

    a (b c? / c b?)? / b (a c? / c a?)? / c (a b? / b a?)?
    

    but that is obviously tedious to construct for a larger number of alternatives.

    It's usually easier to solve "a list of x, y, ... in any order but without repetitions" and the like by accepting an arbitrary list of x, y, ..., and then checking for repetitions in the semantic action. That not only makes the grammar easier to write, it allows for more meaningful error messages.