1

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.

Maxpm
  • 24,113
  • 33
  • 111
  • 170

2 Answers2

2

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.

Ani
  • 111,048
  • 26
  • 262
  • 307
  • 2
    The Q, Plus and Star methods on terms were deprecated around 2010 and have been removed at some point since then. What is the alternative to Q? – Asad Saeeduddin Jul 18 '14 at 14:57
1

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.

shannon
  • 8,664
  • 5
  • 44
  • 74