Skip to content

Instantly share code, notes, and snippets.

@ArGxento
Created August 30, 2012 20:50
Show Gist options
  • Save ArGxento/3540633 to your computer and use it in GitHub Desktop.
Save ArGxento/3540633 to your computer and use it in GitHub Desktop.
skeleton of boost.spirit.qi with semantic action
// 最もシンプルな文法構造体のサンプル
#include <boost/spirit/include/qi.hpp>
#include <iostream>
#include <string>
namespace qi = boost::spirit::qi;
// qi::grammarクラスを継承して文法クラスを作ります。
// テンプレート引数には入力用のイテレータを書く必要があります
template <typename itrT>
struct Grammar : qi::grammar<itrT> {
// ここに文法を構成する規則群を宣言します
qi::rule<itrT> my_rule;
// コンストラクタで最初に適用する規則を指定します
Grammar() : Grammar::base_type(my_rule) {
using qi::omit; using qi::lit; using qi::unused_type;
// この下に規則を記述していきます
// 例として,空白で区切られた文章の単語の数だけ文字列を出力する
// 規則を書いてみます
my_rule =
// 括弧内の規則の1回以上の繰り返し
+(
// 空白をのぞくすべての文字の1回以上の繰り返し
// (qi::char_ - qi::space)の属性はcharですが,型情報を
// 使わないので,omit[]で属性をunused_typeに変換し,
// それを受けてセマンティックアクションに指定したラムダ式の
// 第1引数がunused_typeになっています
(+omit[qi::char_ - qi::space])[
// 受理された時点で実行されるセマンティックアクション
[&](unused_type, unused_type, unused_type){
std::cout << "Hello, World!" << std::endl;
}
]
// その後ろに0個以上の空白が続く
>> *qi::space
);
}
};
int main(){
using namespace std;
Grammar<string::iterator> g;
string s("This is a test.");
string::iterator itr = s.begin();
if( qi::parse(itr, s.end(), g) && itr == s.end() ) {
std::cout << "done" << std::endl;
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment