Каков иронический эквивалент необязательного оператора 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, в зависимости от реализации. Я не исследовал дальше.

Другие вопросы по тегам