What's Irony's equivalent of Yacc's optional operator ("?")?

1k Views Asked by At

I have a fragment of grammar in Yacc notation:

stylesheet
: [ CHARSET_SYM STRING ';' ]?
  [S|CDO|CDC]* [ import [ CDO S* | CDC S* ]* ]*
  [ [ ruleset | media | page ] [ CDO S* | CDC S* ]* ]*
;

How do I implement this fragment in Irony? I can't find any equivalent of ?, which means 0 or 1 occurrence in Yacc.

2

There are 2 best solutions below

1
On BEST ANSWER

You can use the BnfTerm.Q method to represent '?' (0 or 1 occurrences). This was a reasonable design decision since C# does not let you write a custom implementation of the ? operator, unlike + and *.

From the Non Terminals page on the Irony Wikibook:

In traditional BNF notation, the "?", "+", and "*" characters are used to indicate "0 or 1 time", "1 or more times" and "0 or more times", respectively. In Irony, it's done slightly differently. You use the MakePlusRule and MakeStarRule methods from the base Grammar class for "+" and "*" or you can use the Q(), Plus(), and Star() methods directly on the term within the rule.

0
On

The author says an additional AST node is now required for this purpose. So for example you could substitute the following for an optional term in a rule:

new NonTerminal("OptionalTermName", Empty | TermThatShouldBeOptional)

http://irony.codeplex.com/discussions/550979

I wonder if it could be reduced to:

(Empty | TermThatShouldBeOptional)

The overload creates a BNF Term, rather than a NonTerminal node, which could lose some hierarchical information when joined directly with other BNF terms, depending on the implementation. I haven't investigated further.