ohmjs/ohm

Handle trailing separators in ListOf

DavidSouther opened this issue · 4 comments

Rep {
  RepA = List<"A", ",">
  List<e, s> = NonemptyListOf<e, s> s?
  RepB = NonemptyListOf<"A", ",">
  NonemptyListOf<e, s> := ... s?
}

Line 5, col 32: expected "+=", ":=", or "="

A, with RepA succeeds, but fails NonemptyListOf<"A", ",">. This would be desirable to allow trailing commas, eg in

call(
  longArg1,
  longArg2,
);

I can of course write my own List<e, s> as above, but it loses the asIteration() built-in utilities.

You're getting a syntax error here because the super-splice operator (...) can only be used with an alternation. In other words, it needs to appear beside a |.

Say your supergrammar is as follows:

G {
  contactInfo = emailAddress
  // definition of emailAddress rule is omitted here
}

Here are some examples of using the super-splice operator:

  • contactInfo := phoneNumber | ...
  • contactInfo := ... | phoneNumber
  • contactInfo := phoneNumber | ... | faxNumber

The reason for this restriction is that using it in other ways (e.g., as part of a sequence like you're trying to do here), would change the arity of the rule, which would possibly make it incompatible with existing semantic actions written for that rule.

Overriding built-in parameterized rules does work:

G {
  Start = ListOf<"", ",">
  ListOf<thing, sep> := sep sep
}

This will succeed to match ",,".

would change the arity of the rule, which would possibly make it incompatible with existing semantic actions written for that rule.

Gotcha, that does make sense.

Your second comment doesn't capture what I'm looking for, I update the rule title and examples to make it more clear.

Ok, if I make a new base language for myself, I can do this:

Base {
  List<e, s> = NonemptyListOf<e, s> s?
}

Lang <: Base {
  Call = Name OpenParen Args CloseParen
  Args = List<Arg, ",">
}
valueSemantics.extendOperation("asIteration", {
  List(list, _) {
    return list.asIteration();
  },
});