1

C++ で Bison を使用してパーサーを生成しようとしています。文法は問題ありませんが、アクションですぐに問題が発生します。簡単なサンプルを次に示します。

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;
4

1 に答える 1

4

左側に関連付けられます。

(((statement) statement) statement) statement

これがあなたの作品の1つであるに減らすことができるので、これが唯一の可能性であると言うことができstatements statementます。他のオプション

statement (statement (statement (statement))))

に減らす必要がありますstatement statementsが、これはあなたの作品の1つではありません。ただし、代わりに右結合性が必要な場合は、これを使用できます。

あるステートメントを別のステートメントと結合した後、最初のステートメントへのポインターを返すため、コードはリンクリストをそのまま生成しません。したがって、次のステートメントが発生すると、最初のステートメントのポインターが上書きされますNext

順序を右連想に変更するとこれを解決できますが、これにはステートメント数に線形パーサースタックスペースが必要になることに注意してください。したがって、多くのステートメントが予想される場合は、リンクリストを逆に作成することを検討する必要があります。

于 2011-07-26T20:44:10.333 に答える