問題タブ [boost-spirit-qi]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c++ - boost-spirit数値パーサーと目的の合成属性の取得
--編集-質問を解決しました:最後のサイドノートへのコメントが役に立ちます。また、phoenix :: bindオーバーロード処理に関するコメントも役立ちます(私の答えでは)。
私は厳密な型指定要件のあるシステムで作業しています。int32_tとint64_tの制約を満たす整数を解析していることを確認したいのですが、解析された文字列を合成して上記の型に制約するパーサーは必要ありません。
これについてはどうすればよいですか?ドキュメントにはlong_long
、64ビットをサポートするプラットフォームでのみ使用可能であると記載されていますが、32ビットプラットフォームでもint64_tを解析する必要があります。
私のパーサーからの抜粋は次のとおりです。
AddEntryにはint32_t
オーバーロードとint64_t
オーバーロードがありますが、phoenix :: static_cast_は順番にオン_1
になっていますか?この場合、最新の32ビットプラットフォームで64ビット整数を解析するにはどうすればよいですか?8008BOOST_HAS_LONG_LONG
のような古風なハードウェアでは定義されていないだけだと思います;)。
<Rant>
彼らがc99で設定された標準に固執していればよかった<boost/cstdint.hpp>
のですが、私たちのほとんどはクリーンな抽象化に対してプログラミングしたいと思っています。数値パーサーがそのように定義されているのには、おそらく正当な理由があります。ただし、グランドスキームの使用は、ドキュメントでより適切に定義できます。
</Rant>
補足:上記の条件付きイプシロンスタイルは、パフォーマンスのケースステートメントに匹敵しますか?
c++ - boost.Spirit で括弧がネストされた式を解析するにはどうすればよいですか?
次のように、キーと値のペアとキーと部分式のペアを含む 1 行の式を解析する必要があります。
パーサーを簡単にするために、最初のレベルのタグ (ここでは 123、456、789、111、および 666) を分離し、別のステップでそれらのコンテンツを解析することで、いくつかのステップで解析を行うつもりです。ここで 789 の値は次のようになります。"a b c"
、111 の値は になります(1=a 2=b 3=c) (1=x 2=y 3=z) (123=(x y z))
。
しかし、文法はこの時点で私を打ち負かしたので、一致する括弧の間の式を取得する方法を理解することができます. 111 で得られるのは(1=a 2=b 3=c
、最初の閉じ括弧で終わる だけです。
この便利な例を見つけて使用しようとしましたが、成功しませんでした:
どうすればそれができますか?
編集: http://boost-spirit.com/home/articles/qi-example/parsing-a-list-of-key-value-pairs-using-spirit-qi/で例を見つけました
c++ - パーサーに関係のない関数の Spirit Qi セマンティック アクションとパラメーター
ルール/パーサーが返した属性を使用しないフリー関数を呼び出すセマンティック アクションを宣言するにはどうすればよいですか?
たとえば、文字列を返すパーサーがあるとしますが、頻度と期間に 2 つの整数値を取り、文字列を気にしない Beep のような無関係な関数を呼び出したいとします。
実際に直接呼び出すことは可能ですか、それとも、文字列を消費して呼び出すプロキシ関数を常に作成する必要がありますか?この場合は、その本体で Beep を呼び出しますか?
編集:申し訳ありません。最初に、Hartmut が提案した構文で boost::phoenix::bind を使用したことを言及する必要がありました。これにより、次のエラーが発生しました。
ここで物事を台無しにするのは呼び出し規約ですか?
Edit2: それが問題のようです。Hartmuts コードは、Beep と同じ量と型の引数を取る単純な関数でコンパイルされます。
Google 検索の結果、(ほとんどの) WINAPI 関数は __stdcall 規則を使用していることがわかった。
したがって、これまでの回答はすべて正しかったため、フェニックスのソリューションはそのままでは機能しませんでした。(そもそもこの質問を投稿する動機になりました。威厳がなく混乱を招く性質で申し訳ありませんが、これですべてが解決するかもしれません。)
今私にとって不明な唯一のことは...フェニックスを__stdcallとうまくやっていく方法ですが、それはおそらく別の質問になるはずです。
c++ - 実行時にBoost.Spirit.Qiルールを動的に組み合わせる(任意の数の選択肢)
Boost.Spirit.Qiに、実行時に任意の数のルールを動的に組み合わせる方法があるかどうか疑問に思いました。Boost.Spiritの内部動作はまだ私には少し謎ですが、ルールはオブジェクトとして実装されているため、実行可能のようです。私の動機は、文法の特定の部分を簡単に拡張できるようにすることです。
次の不自然な例を考えてみましょう。
VisualStudio2010で発生するエラーは次のとおりです。
私の疑いは、これは継承された属性をに渡さなかったことが原因であると考えられgrammar.copy()
ます。残念ながら、これを行う簡単な方法が見つからなかったため、回避策を選択しました。その結果、最後のバージョンが1つあります(これまで立ち往生していた人にはもう感謝したいと思います!)。これは実際に機能しているようです:
ただし、単純なセマンティックアクション( "[no_op]"など)をアタッチすると、動作が非常に奇妙になります。以前のように0,1,2を印刷するのではなく、0,0,2を印刷します。だから私は疑問に思っています、私が達成しようとしていることは未定義の動作をもたらしますか?これはバグですか?または、おそらく、私は何か(セマンティックアクションなど)を間違った方法で使用しているだけですか?
c++ - 些細なSpiritParser文法によるセグメンテーション違反
私はSpiritQiパーサーで頻繁にsegfaultに遭遇しています。
問題をデバッグするために何日も費やした後(スタックトレースを理解するのは不可能であることがわかりました)、最小限の例に切り詰めることにしました。誰かが私が間違っていることを教えてもらえますか?
コードをbug.cppとして保存し、でコンパイルg++ -Wall -o bug bug.cpp
すれば、準備は完了です。
私はこれをテストしました
- g ++ 4.4、4.5、4.6および
- ブーストバージョン1.42(ubuntu meerkat)および1.46.1.1(natty)
出力は
または、ブースト1.46.1では、レポートされますSpirit version: 2042
c++ - Boost.Spirit.Qi: パーサーの警告を報告するには?
パーサーの警告を報告するには? エラーの報告に似ていますが、パーサーは停止してはなりません。警告メッセージのみをログに記録し、副次式が警告を引き起こしました。
入力例:
期待される出力:
c++ - ブースト::スピリット::気。インライン パーサー式をスタンドアロンの文法に変換する方法と、それらによって生成されたタプルをアンパックする方法は?
私は QI と Phoenix を使用しており、セマンティック アクション内の関数呼び出しの引数として使用される 4 つの bool を返す小さな文法を書きたいと考えています。
それらを必要とするいくつかの関数があり、これまでのところ、このアプローチを使用しています。
それ自体は問題ありませんが、名前空間の部分を「使用」していても、あちこちで使用するのは見苦しく、混乱を招きます。
そのため、この表現をスタンドアロンの文法に抽出したいと考えました。
だから私はこれを試しました(クレジットはテストベッドのildjarnに行きます):
fourBools[phx::bind(&noDice, spirit::_1)]
に置き換えない限り、コンパイルされませんfourBools[phx::bind(&worksFine, spirit::_1)]
。
つまり、私の問題は、引数の数が署名レベルで異なるため、呼び出される関数の署名に一致するように引数をアンパックすることです (4 つのブール値の 1 つのタプルと 4 つのブール値自体)。
タプルを個別の必要がある既存の関数の個々の引数に変換するラッパーを記述する代わりに、フェニックスプレースホルダーを直接使用してアンパックすることは可能ですか? もしそうなら、その構文は何ですか?結局のところ、プレースホルダー( qi::_bool >> qi::_bool >> qi::_bool >> qi::_bool)
によって「アンパック」されると、インライン バージョンは正常に動作します。spirit::_1 - spirit::_4,
そのため、このバージョンもタプルを返すかのように見え、タプルを返す文法とは異なり、上記のアプローチでは何らかの形でアンパック可能です。
どうすればこれに対処できますか?
c++ - Boost Spiritの解析済みエンティティを入力ストリーム内の場所に関連付ける方法は?
Boost Spiritライブラリは、解析中に入力位置を追跡することを許可します。このメカニズムにより、解析中にパーサーエラーの場所を通知できます。
将来の使用のために、解析されたすべてのエンティティの元の場所をそれらと一緒に保持したいと思います。(たとえば、ASTセマンティック検証。)これを行うための推奨される方法は何ですか?
ありがとうございました!
c++ - qi を使用して整数の順序付きリストを解析および検証する方法
次のような行で構成される、サイズがおそらく数 GB のテキスト ファイルを解析しています。
基本的に、1 行に 1 つの int と 1 つの float があります。int は順序付けられ、負でない必要があります。データが説明どおりであることを確認したいのですが、範囲内の最小および最大の int が返されました。これは私が思いついたものです:
私が知りたいのは次のことです。
- これについてもっと良い方法はありますか?継承および合成された属性、ローカル変数、およびフェニックス ブードゥー教を少し使用しました。これは素晴らしい; ツールを学ぶのは良いことですが、同じことを達成するもっと簡単な方法があるかもしれないと考えずにはいられません:/ (PEGパーサー内で...)
- たとえば、ローカル変数なしでどのように行うことができますか?
詳細情報:同時に解析される他のデータ形式があるため、戻り値をパーサー属性として保持したいと考えています。現時点では、これは std::pair であり、解析時に他のデータ形式は、たとえば独自の std::pair を公開します。これらを std::vector に詰め込みたいと思います。