Skip to content

Instantly share code, notes, and snippets.

@hecomi
Created January 22, 2012 17:33
Show Gist options
  • Save hecomi/1657775 to your computer and use it in GitHub Desktop.
Save hecomi/1657775 to your computer and use it in GitHub Desktop.
/* ------------------------------------------------------------------------- */
// 家電を操作するための文章コマンドのパーサ
/* ------------------------------------------------------------------------- */
#include <iostream>
#include <string>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
namespace qi = boost::spirit::qi;
namespace phx = boost::phoenix;
namespace ascii = boost::spirit::ascii;
// 結果を格納する型(2次元 string テーブル)
typedef std::vector<std::vector<std::string>> str_2d_array;
/* ------------------------------------------------------------------------- */
// Parser
// string: "(a|b|c)d(e|f)g" --> str_2d_array: { {a,b,c}, d, {e,f}, g}
/* ------------------------------------------------------------------------- */
template <typename Iterator>
bool command_parse(Iterator first, Iterator last, str_2d_array& result)
{
using qi::char_;
using qi::_1;
using qi::lit;
qi::rule<Iterator, std::string(), ascii::space_type> word, words, sentence;
std::vector<std::string> buf;
word = +( char_ - '(' - '|' - ')' );
words = -lit('(')
>> ( word [phx::push_back(phx::ref(buf), _1)] % '|' )
>> -lit(')');
sentence = *(
words
[phx::push_back(phx::ref(result), phx::ref(buf))]
[phx::clear(phx::ref(buf))]
)
>> qi::eol;
bool r = qi::phrase_parse(first, last, sentence, ascii::space);
if (!r || first != last) {
return false;
}
return true;
}
/* ------------------------------------------------------------------------- */
// main 関数(テスト用)
/* ------------------------------------------------------------------------- */
int main(int argc, char const* argv[])
{
std::string str = "(abc|def|ghi)jkl(mno|pqr)stu(vwx|yz|)";
std::string::const_iterator iter = str.begin(), end = str.end();
str_2d_array sentences;
if (command_parse(iter, end, sentences)) {
std::cout << "failed" << std::endl;
}
for (const auto& sentence : sentences) {
std::cout << sentence.size() << ": ";
for (const auto& x : sentence) {
std::cout << x << " ";
}
std::cout << std::endl;
}
return 0;
}
@hecomi
Copy link
Author

hecomi commented Jan 22, 2012

3: abc def ghi
1: jkl
2: mno pqr
1: stu
2: vwx yz

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment