Каков иронический эквивалент необязательного оператора Yacc («?»)?

1

У меня есть фрагмент грамматики в нотации Yacc:

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

Как реализовать этот фрагмент в Иронии? Я не могу найти эквивалент ? , что означает 0 или 1 появление в Yacc.

Теги:
parsing
yacc
irony

2 ответа

2
Лучший ответ

Вы можете использовать метод BnfTerm.Q для представления '?' (0 или 1 вхождения). Это было разумное дизайнерское решение, поскольку С# не позволяет вам писать пользовательскую реализацию ? оператор, в отличие от + и *.

На странице Non Terminals на Irony Wikibook:

В традиционной нотации BNF символы "?", "+" И "*" используются для обозначения "0 или 1 раз", "1 или более раз" и "0 или более раз" соответственно. В Иронии это делалось несколько иначе. Вы используете методы MakePlusRule и MakeStarRule из базового класса грамматики для "+" и "*", или вы можете использовать методы Q(), Plus() и Star() непосредственно на члене в правиле.

  • 2
    Методы Q, Plus и Star на условиях были объявлены устаревшими в 2010 году и с тех пор были удалены. Какая альтернатива Q?
1

Автор говорит, что для этой цели теперь требуется дополнительный узел АСТ. Так, например, вы можете подставить следующее правило для необязательного термина в правиле:

new NonTerminal("OptionalTermName", Empty | TermThatShouldBeOptional)

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

Интересно, можно ли это уменьшить:

(Empty | TermThatShouldBeOptional)

Перегрузка создает термин BNF, а не узел NonTerminal, который может потерять некоторую иерархическую информацию при соединении напрямую с другими терминами BNF в зависимости от реализации. Я еще не исследовал.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню