Currently if you want to require that a comma-separated list (or any list using a separator) has at least one separator, you do something like:

ID "," {ID ","}+

The resulting term, obviously, will have the first element as a separate component. If however, one could specify that we want at least 2 elements in the list, like:

{ID ","}++

Then we could differentiate a list from a non-list correctly.

Another use case is:

{Expr BinaryOp}++ -> Expr{cons("BinaryOp")}

Where one wants to only match this rule if there’s at least one operator used, but we want all the operators and separators to go in the list.

A separate but related use case would be supporting a trailing separator, like in Python lists/tuples. Perhaps:

{Expr ","}++? -> Expr{cons("Tuple")} 

Would match “1,”, “1,1”, and “1,1,” but not something with no comma at all.

Submitted by Dobes Vandermeer on 13 October 2012 at 19:47

On 13 October 2012 at 22:57 Guido Wachsmuth commented:

The first example you can achieve with

{ID ","}+ -> IDs 
ID        -> IDs {reject}

The second example seems not to be attractive, since it will be highly ambiguous. For example, 1 + 2 + 3 + 4 can be parsed as (1+2)+(3+4) or as ((1+2)+3)+4. Furthermore, you will need to analyse operator precedence afterwards. Typically, we prefer the following pattern

context-free syntax

  Exp BinOp1 Exp -> Exp {cons("BinOp1")}
  Exp BinOp2 Exp -> Exp {cons("BinOp2")}

context-free priorities

  Exp BinOp1 Exp -> Exp >
  Exp BinOp2 Exp -> Exp 

The third example would suffer from the same ambiguity issue as the previous one.


On 14 October 2012 at 06:50 Dobes Vandermeer commented:

Excellent points! Thanks!


On 13 November 2012 at 13:18 Maartje closed this issue.

Log in to post comments