Бизон: Дополнительные маркеры в единственном правиле

я использую Бизона GNU 2.4.2 для записи грамматики для нового языка, я продолжаю работать, и у меня есть вопрос. Когда я указываю правило, скажем:

statement : T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}' {
           // create a node for the statement ...
}

Если у меня есть вариация на правило, например

statement : T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}' {
           // create a node for the statement ...
}

Где (от правил сканера гибкого провода):

"class"                     return T_CLASS;
"extends"                   return T_EXTENDS;
[a-zA-Z\_][a-zA-Z0-9\_]*    return T_IDENT;

(и T_IDENT_LIST является правилом для разделенных идентификаторов запятой).

Там какой-либо путь состоит в том, чтобы указать все это только в одном правиле, установив так или иначе "T_EXTENDS T_IDENT_LIST" как дополнительный? Я уже попробовал

 T_CLASS T_IDENT (T_EXTENDS T_IDENT_LIST)? '{' T_CLASS_MEMBERS '}' {
     // create a node for the statement ...
 } 

Но Бизон дал мне ошибку.

Спасибо

12
задан lesmana 6 May 2013 в 14:16
поделиться

3 ответа

Короче говоря, нет. Bison работает только с грамматиками LALR (1), что означает, что он использует только один символ просмотра вперед. Что вам нужно, это что-то вроде этого:

statement: T_CLASS T_IDENT extension_list '{' ...

extension_list: 
              | T_EXTENDS T_IDENT_LIST
              ;

Есть и другие генераторы парсеров, которые работают с более общими грамматиками. Если память не изменяет, некоторые из них поддерживают необязательные элементы относительно напрямую, как вы просите.

12
ответ дан 2 December 2019 в 21:23
поделиться

Я думаю, самое большее, что вы можете сделать, это

statement : T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}'
    | T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}' {
}
0
ответ дан 2 December 2019 в 21:23
поделиться

Почему бы вам просто не разделить их с помощью оператора выбора ( | )?

statement:
  T_CLASS T_IDENT T_EXTENDS T_IDENT_LIST  '{' T_CLASS_MEMBERS '}'
  | T_CLASS T_IDENT  '{' T_CLASS_MEMBERS '}'

Я не делаю ' Не думаю, что вы можете это сделать только потому, что это восходящий синтаксический анализатор LALR (1), вам понадобится что-то другое, например LL (k) (ANTLR?), чтобы делать то, что вы хотите сделать ..

{{1 }}
1
ответ дан 2 December 2019 в 21:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: