1

私は現在、このトピックに関する個人教育用のコンパイラ フロント エンドを作成していますが、演算子のオーバーロードによって C++ で BNF 定義を処理する方法に関する問題に遭遇しました。

現在、私のセットアップは次のとおりです。

Rule.h:

class Rule
{
public:
    ChainRule operator>>(Rule& right);
    OrRule operator|(Rule& right);
    KleeneRule operator*();
    OptionalRule Rule::operator+();

    virtual bool parse(TokenList::iterator& begin, TokenList::iterator end) = 0;
};

ルール.cpp:

ChainRule Rule::operator>>(Rule& right) {
    return ChainRule(this, &right);
}

OrRule Rule::operator|(Rule& right) {
    return OrRule(this, &right);
}

KleeneRule Rule::operator*() {
    return KleeneRule(this);
}

OptionalRule Rule::operator+() {
    return OptionalRule(this);
}

ChainRule、OrRule、KleeneRule、OptionalRule、および EmptyRule は、次のように自明に定義されます。

class ChainRule : public Rule
{
private:
    Rule* next;
    Rule* _this;

public:
    ChainRule();
    ChainRule(Rule* _this, Rule* right);

    bool parse(TokenList::iterator& begin, TokenList::iterator end) override;
};

Rule の各サブクラスは明らかに parse() の適切な実装を定義します。これらのクラスを使用して、次のように文法を定義できます。

OrRule assignment_exp   = logical_or_exp
                        | unary_exp >> StringRule("=") >> assignment_exp
                        ;   

問題は次のとおりです。オーバーロードされた各演算子は、新しいオブジェクトを値で返します。つまり、 operator>> または operator| を使用するたびに Rule クラスから、operator>> または operator| への呼び出しから戻ると、これらのポインターはガベージになります。スタックがクリーンアップされ、オブジェクトがなくなったためです。

Rule サブクラスのコンストラクターで値渡しを使用することもできません。再帰的な文法を定義できないからです。

したがって、オブジェクトを値で渡すオプションも、オブジェクトをポインターで渡すオプションもありません。私の文法をそのように定義することを強制しない解決策を誰かに教えてもらえますか?

StringRule s = StringRule("=");
OrRule assignment_exp;
ChainRule temp1 = s >> assignment_exp;
ChainRule temp2 = unary_exp >> temp1;
assignment_exp = logical_or_exp | temp2;

PS さまざまなパーサー ジェネレーターと Boost.Spirit を認識していますが、私の目標は独自のパーサーを作成することです。

4

2 に答える 2

1

戻りオブジェクトを (ファクトリ経由で) ヒープに割り当て、それらを参照として返すことができます。工場はそれらを追跡できるので、漏れることはありません。構文に関する限り、値で返す場合と同じように機能します。

于 2012-11-21T23:13:58.067 に答える
1

Rule*(演算子をオーバーロードできないという問題がある) をラッパー オブジェクトに置き換えることで、この問題を回避できます。つまり、 などの代わりにChainRule含まれ、すべての演算子が に対して定義されます。は単純に を含み、から構築可能です。メモリ処理を簡単にするために、スマート ポインター クラスから継承できます。RuleRef nextRule * nextRuleRefRuleRefRule*Rule*

于 2012-11-21T23:26:41.583 に答える