在Bison的行动命令

时间:2011-07-26 20:20:10

标签: c++ bison lalr

我正在尝试使用Bison在C ++中生成解析器。语法很好,但我对这些动作有一些快速的麻烦。这是一个简单的示例:

statements
: statement
| statements statement;

据我所知,这是很正常的事情。我的问题是首先得出的。例如,如果我有一个看起来像

的输入
statement statement statement statement

Bison是否将我的行为称为

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 个答案:

答案 0 :(得分:4)

它与左边相关,即

(((statement) statement) statement) statement

你可以说这是唯一的可能性,因为这可以减少到statements statement,这是你的作品之一。另一个选择

statement (statement (statement (statement))))

必须缩减为statement statements您的某个作品。但是,如果您想要右关联,则可以使用此方法。

您的代码不会按原样生成链接列表,因为在将一个语句与另一个语句连接后,您将返回指向第一个语句的指针,因此当下一个语句到来时您就是覆盖第一个语句的Next指针。

将顺序更改为右关联应解决此问题,但请注意,这将需要语句数量中的线性解析器堆栈空间。如果您期望许多语句,则应考虑反向构建链接列表。