私はBisonを使ってパーサを生成しようとしています。文法はうまくいきますが、私はその行動に素早く問題を抱えています。ここに簡単なサンプルがあります:Bisonのアクションオーダー
statements
: statement
| statements statement;
私の知る限り、これはかなり普通のことです。私が持っている質問は、最初に導き出されたものです。私は
statement statement statement statement
のように見えるの入力を持っている場合、私はのリンクリストを構築しようとしている
statement (statement (statement (statement))))
または
(((statement) statement) statement) statement
として例えば、Bisonは私の行動を呼ぶんルールはここで呼び出され、入力と同じ順序でリストを保持したい。 OK、私はこのような何かを行うことができます:今、私は
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;
なぜdownvoteですか? – Praetorian
@DeadMG: '$ 2'を' $ 1'に追加し、 '$$'を使って' $ 1'を "返す"ので、次の派生の後に同じノードの 'Next'ポインタをリセットする*でしょう。あなたが必然的にリンクリストを望むなら(なぜ、 'vector'や' deque'ではなく?)、その頭とその尾の両方へのポインタを保持しなければなりません。 –
@larsmans:ベクターやデュークを使用していないのは、私が依存できる場所をどこにも格納していないからです。スタック(Cスタイルの文法)にはいくつかの 'statements 'があり、Bisonは複雑なコンテナを保持することは実際にはありません。実際には、考えてみると、実際のスタックになることは決してありませんでしたので、ユーザー提供の引数に格納し、中央の引数を使用してプッシュしてポップすることができます。 – Puppy