Порядок действий в бизоне - PullRequest
1 голос
/ 27 июля 2011

Я пытаюсь использовать Bison для генерации парсера в C ++. Грамматика в порядке, но у меня возникли проблемы с действиями. Вот простой пример:

statements
: statement
| statements statement;

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

statement statement statement statement

Бизон называет мои действия

statement (statement (statement (statement))))

или

(((statement) statement) statement) statement

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

statements
: statement
{ 
  $$ = $1; 
}
| statements statement
{ 
  dynamic_cast<ParsedFile::Statement*>($1)->Next = dynamic_cast<ParsedFile::Statement*>($2);
  $$ = $1;
};

Редактировать: ОК, так что я мог бы сделать что-то вроде этого:

switch_statement
: SWITCH '(' expression ')'
{ 
  auto Switch = p.Make<ParsedFile::SwitchStatement>();
  Switch->Test = dynamic_cast<ParsedFile::Expression*>($3);
  p.NewScope();
  $$ = Switch;
}
'{' case_statements '}'
{
  auto Switch = dynamic_cast<ParsedFile::SwitchStatement*>($5);
  Switch->Cases = p.statements.top();
  p.PopScope();
  p.AddToCurrentScope(Switch);
};

default_statement
: DEFAULT ':' 
{
  auto Default = p.Make<ParsedFile::DefaultStatement>();
  p.NewScope();
  $$ = Default;
}
statements
{
  auto Default = dynamic_cast<ParsedFile::DefaultStatement*>($3);
  Default->Statements = p.statements.top();
  p.PopScope();
  p.AddToCurrentScope(Default);
};

case_statement
: CASE expression 
{
  auto case = p.Make<ParsedFile::CaseStatement>();
  p->Value = dynamic_cast<ParsedFile::Expression*>($2);
  p.NewScope();
  $$ = case;
}
DOUBLE_COLON statements
{
  auto Case = dynamic_cast<ParsedFile::CaseStatement*>($3);
  Case->Statements = p.statements.top();
  p.PopScope();
  p.AddToCurrentScope(Case); 
};

case_statements
: case_statement
| case_statements case_statement
| case_statements default_statement;

1 Ответ

4 голосов
/ 27 июля 2011

Он ассоциируется слева, т.е.

(((statement) statement) statement) statement

Вы можете сказать, что это единственная возможность, потому что это может быть уменьшено до statements statement, что является одним из ваших произведений.Другой вариант

statement (statement (statement (statement))))

должен быть уменьшен до statement statements, что является , а не одним из ваших произведений.Однако вы можете использовать это, если хотите вместо этого использовать правую ассоциативность.

Ваш код не будет создавать связанный список как есть, потому что после объединения одного оператора с другим вы возвращаете указатель на первый оператор , поэтому, когда приходит следующий оператор, вы перезаписываете указатель Next первого оператора.

Изменение порядка на ассоциативное право должно решить эту проблему, но обратите внимание, что для этого потребуется линейныйпространство стека синтаксического анализатора в количестве операторов.Если вы ожидаете много утверждений, вам следует рассмотреть возможность создания связанного списка в обратном порядке.

...