×
[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。
今回は組み込み関数に対応する引数に応じて後々のルールを変更する方法と言うことでひとつ。
symbolsさんを使います。
今回は関数名と対応するルールで作りましたが、もっとわかりやすい例としては
とかして英語と数字のマッピングなんかも出来ちゃいます。多分。
あと、この部分
にすると、うまく動きません。実行時エラー起こします。
設定の順番が大事みたいです。
さらに、この部分
を、こんな感じ
にしたい場合、
ってしないとダメみたいです。
とりあえず今日はこんなところで。
#include <iostream>
#include <string>
#pragma warning(push)
#pragma warning(disable:4100) //引数は関数の本体部で 1 度も参照されません。
#pragma warning(disable:4512) //代入演算子を生成できません。
#pragma warning(disable:4819) //ファイルは、現在のコード ページ (932) で表示できない文字を含んでいます。
#pragma warning(disable:4127) //条件式が定数です。
#include <boost/spirit/include/qi_action.hpp>
#include <boost/spirit/include/qi_grammar.hpp>
#include <boost/spirit/include/qi_lexeme.hpp>
#include <boost/spirit/include/qi_operator.hpp>
#include <boost/spirit/include/qi_parse.hpp>
#include <boost/spirit/include/qi_rule.hpp>
#include <boost/spirit/include/qi_char_.hpp>
#include <boost/spirit/include/qi_string.hpp>
#include <boost/spirit/include/qi_numeric.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_statement.hpp>
#pragma warning(pop)
#pragma warning(disable:4503) //装飾された名前の長さが限界を越えました。
template<typename String, typename Skipper>
struct Parser : boost::spirit::qi::grammar<typename String::const_iterator, Skipper>{
typedef typename String::const_iterator Iterator;
boost::spirit::qi::rule<Iterator, Skipper> func1;
boost::spirit::qi::rule<Iterator, Skipper> func2;
boost::spirit::qi::symbols<char, boost::spirit::qi::rule<Iterator, Skipper>> funcs;
boost::spirit::qi::rule<Iterator, Skipper> statement;
boost::spirit::qi::rule<Iterator, boost::spirit::qi::locals<boost::spirit::qi::rule<Iterator, Skipper>>, Skipper> statement2;
Parser() : Parser::base_type(statement){
//文法定義
{
using namespace boost::spirit;
using namespace boost::spirit::ascii;
using namespace boost::spirit::labels;
namespace phoenix = boost::phoenix;
//テストコード
func1 = '(' >> int_ >> ')';
func2 = '(' >> char_ >> "," >> char_ >> ')';
funcs.add
("func1", func1)
("func2", func2)
;
statement2 = (funcs[_a = _1] >> lazy(_a));
statement = statement2;
}
}
};
template<typename String>
struct SkipParser : boost::spirit::qi::grammar<typename String::const_iterator>{
typedef typename String::const_iterator Iterator;
SkipParser() : SkipParser::base_type(comment){
using namespace boost::spirit;
comment = boost::spirit::ascii::space
| ("//" >> *(qi::char_ - '\n') >> '\n')
| ("/*" >> *(qi::char_ - "*/") >> "*/");
}
boost::spirit::qi::rule<Iterator> comment;
};
int main(void)
{
namespace phoenix = boost::phoenix;
typedef SkipParser<std::string> SkipperType;
typedef Parser<std::string, SkipperType> ParserType;
SkipperType skipper;
ParserType parser;
std::string str;
while (getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
std::string::const_iterator it = str.begin();
std::string::const_iterator end = str.end();
bool result = phrase_parse(it, end, parser, skipper);
if (result && it == end)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << str << " Parses OK: " << std::endl;
}
else if(result)
{
std::cout << "-------------------------\n";
std::cout << "Parsing succeeded\n";
std::cout << std::string(str.begin(), it) << " Parses OK: " << std::endl;
std::cout << std::string(it, end) << " amari" << std::endl;
}
else
{
std::cout << "-------------------------\n";
std::cout << "Parsing failed\n";
std::cout << "-------------------------\n";
}
}
return 0;
}
symbolsさんを使います。
コレは、前者の値に対応して後者を返すルールを簡単に作れるもの……です。多分。boost::spirit::qi::symbols<char, boost::spirit::qi::rule<Iterator, Skipper>> funcs;
今回は関数名と対応するルールで作りましたが、もっとわかりやすい例としては
boost::spirit::qi::symbols<char, int> nums;
nums.add
("one", 1)
("two", 2)
("three", 3)
;
とかして英語と数字のマッピングなんかも出来ちゃいます。多分。
あと、この部分
を、こんな感じfunc1 = '(' >> int_ >> ')';
func2 = '(' >> char_ >> "," >> char_ >> ')';
funcs.add
("func1", func1)
("func2", func2)
;
statement2 = (funcs[_a = _1] >> lazy(_a));
statement = statement2;
statement = statement2;
statement2 = (funcs[_a = _1] >> lazy(_a));
funcs.add
("func1", func1)
("func2", func2)
;
func1 = '(' >> int_ >> ')';
func2 = '(' >> char_ >> "," >> char_ >> ')';
にすると、うまく動きません。実行時エラー起こします。
設定の順番が大事みたいです。
さらに、この部分
statement2 = (funcs[_a = _1] >> lazy(_a));
statement = statement2;
を、こんな感じ
statement = (funcs[_a = _1] >> lazy(_a));
にしたい場合、
struct Parser : boost::spirit::qi::grammar<typename String::const_iterator, boost::spirit::qi::locals<boost::spirit::qi::rule<typename String::const_iterator, Skipper>>, Skipper>{
<中略>
boost::spirit::qi::rule<Iterator, boost::spirit::qi::locals<boost::spirit::qi::rule<Iterator, Skipper>>, Skipper> statement;
ってしないとダメみたいです。
とりあえず今日はこんなところで。
PR
この記事にコメントする