Я пытаюсь использовать 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;