7

boost::spirit::ascii::spaceこれまで、標準/boost::spirit::ascii::space_typeスキッパーを使用してきた文法があります。

スキッパーを使用するルールと使用しないルールがあります。

qi::rule<Iterator, PTR<Expression>(), ascii::space_type> expression;
qi::rule<Iterator, PTR<Term>()> term;

termスキップする非終端記号(like )の内部で非スキップの非終端記号(like)を使用するとexpression、すべてが期待どおりに機能します。空白はterm非終端記号の内部でのみ重要です。

さらに、これまでは、スキッパーを再確立するために使用しない非終端記号の内部にスキッパーを使用する非終端記号を含めても問題ありませんでしqi::skipた。

index = (qi::lit('[') >> qi::skip(ascii::space)[explist >> qi::lit(']')]);

このように、空白は[]中括弧の内側では重要ではありませんが、外側では重要です。

ただし、ここで、独自のカスタムスキッパーを追加します(改行を重要にし、後でコメントスキップを追加します)。私のスキッパー文法は次のようになります。

struct skip_grammar : qi::grammar<Iterator> {
  qi::rule<Iterator> start;
  skip_grammar() : skip_grammar::base_type(start) {
    start = qi::char_("\t\r ");
  }
};

私はそれを私のルール定義にうまく追加することができました

qi::rule<Iterator, PTR<Expression>(), skip_grammar> expression;

qi::skipしかし、スキップ文法を引数として使用する方法(および置換する方法)を理解できないようですascii::space。タイプ、ローカルインスタンス変数、およびグローバルインスタンス変数を使用してみました。私が得た最も遠いのは、私のskip_grammarにコピーコンストラクターが必要であるとclangに文句を言わせることです。そこで、スキップ文法にコピーコンストラクターを追加しようとしましたがboost::noncopyable、バイナリsegfaultがほぼすぐに発生したため、基本クラスが存在するようです。

これをどのように使用すればよいですか?

ありがとう

4

1 に答える 1

7

Aqi::grammarは単なるコンテナですqi::rules。コピー コンストラクターはありません。これは、これらのルールの右側にあるパーサー式で不注意にダングリング参照を作成する可能性があるためです。

スキッパーとして文法を使用するのは少しトリッキーで、文法の開始規則をスキップ パーサーに渡すことになります。そのためのルール インスタンスを作成する方が簡単な場合があります (特に、単一のルール スキッパーがある場合)。

いずれの場合も、ルールを参照としてスキッパーに渡す必要があります (ルールのメンバー関数を呼び出すことによりalias())。

skip_grammar skippper;
index = '[' >> qi::skip(skipper.start.alias())[explist >> ']'];

または単に:

rule<iterator> skipper = qi::char_("\t\r ");
index = '[' >> qi::skip(skipper.alias())[explist >> ']'];

規則をコピーすることが何を意味するかという詳細のために、エイリアシングが必要です。これについては、ここの Spirit の FAQ で詳しく説明されています。

于 2011-02-18T12:32:19.237 に答える