Каков иронический эквивалент необязательного оператора Yacc ("?")?
У меня есть фрагмент грамматики в обозначении Yacc:
stylesheet
: [ CHARSET_SYM STRING ';' ]?
[S|CDO|CDC]* [ import [ CDO S* | CDC S* ]* ]*
[ [ ruleset | media | page ] [ CDO S* | CDC S* ]* ]*
;
Как мне реализовать этот фрагмент в Иронии? Я не могу найти эквивалент ?
, что означает 0 или 1 вхождение в Yacc.
2 ответа
Вы можете использовать BnfTerm.Q
метод для представления '?' (0 или 1 вхождение). Это было разумное дизайнерское решение, так как C# не позволяет вам написать собственную реализацию ?
оператор, в отличие от +
а также *
,
Со страницы "Нетерминалы" в ироническом Wikibook:
В традиционных обозначениях BNF символы "?", "+" И "*" используются для обозначения "0 или 1 раз", "1 или более раз" и "0 или более раз" соответственно. В Иронии это сделано немного по-другому. Вы используете методы MakePlusRule и MakeStarRule из базового класса грамматики для "+" и "*" или можете использовать методы Q(), Plus() и Star() непосредственно для термина в правиле.
Автор говорит, что для этой цели теперь требуется дополнительный узел AST. Так, например, вы можете заменить следующее необязательный термин в правиле:
new NonTerminal("OptionalTermName", Empty | TermThatShouldBeOptional)
http://irony.codeplex.com/discussions/550979
Интересно, можно ли это уменьшить до:
(Empty | TermThatShouldBeOptional)
Перегрузка создает термин BNF, а не нетерминальный узел, который может потерять некоторую иерархическую информацию при непосредственном соединении с другими терминами BNF, в зависимости от реализации. Я не исследовал дальше.