私は精神文法を書くことに取り組んでおり、16進数表現の文字列を取る基本ベース16を作成するために基本ベース16を作成しようとしています。スピリット文法文字数で文字列を分割するには
49276d206b696c
(文字列が6の完全な倍数でない場合は少なくなります)を解析し、入力からベース64のエンコードされた文字列を生成します。私はおそらく働くだろう考え出し一つの文法は次のようなものです:
// 6 characters
`(qi::char_("0-9a-fA-F") >> qi::char_("0-9a-fA-F") >>
qi::char_("0-9a-fA-F") >> qi::char_("0-9a-fA-F") >>
qi::char_("0-9a-fA-F") >> qi::char_("0-9a-fA-F")[/*action*/]) |
// or 5 characters
(qi::char_("0-9a-fA-F") >> qi::char_("0-9a-fA-F") >>
qi::char_("0-9a-fA-F") >> qi::char_("0-9a-fA-F") >>
qi::char_("0-9a-fA-F")[/*action*/]) | ...`
など....すべての方法ダウン1つの文字、または文字の数ごとに定義された異なるルールを持つが、私はそこにあることが必要だと思います文法を指定する良い方法です。私は精神の繰り返しについて読んで、おそらく私は何かをすることができると思っていた +(boost::spirit::repeat(1, 6)[qi::char_("0-9a-fA-F")][/*action on characters*/])
しかし、コンパイラは、文法のセマンティックなアクション部分のため、これにエラーをスローします。一度に正確に6文字以下で動作する文法を指定する簡単な方法はありますか?
編集 ここでは、私がこれまでに行ったことある... base16convertergrammar.hpp
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
#include <string>
#include <iostream>
namespace grammar {
namespace qi = boost::spirit::qi;
void toBase64(const std::string& p_input, std::string& p_output)
{
if (p_input.length() < 6)
{
// pad length
}
// use back inserter and generator to append to end of p_output.
}
template <typename Iterator>
struct Base16Grammar : qi::grammar<Iterator, std::string()>
{
Base16Grammar() : Base16Grammar::base_type(start, "base16grammar"),
m_base64String()
{
// get six characters at a time and send them off to be encoded
// if there is less than six characters just parse what we have
start = +(boost::spirit::repeat(1, 6)[qi::char_("0-9a-fA-F")][boost::phoenix::bind(toBase64, qi::_1,
boost::phoenix::ref(m_base64String))]);
}
qi::rule<Iterator, std::string()> start;
std::string m_base64String;
};
}
そして、ここでは、使用され... base16converter.cpp
#include "base16convertergrammar.hpp"
const std::string& convertHexToBase64(const std::string& p_hexString)
{
grammar::Base16Grammar<std::string::const_iterator> g;
bool r = boost::spirit::qi::parse(p_hexString.begin(), p_hexString.end(), g);
}
int main(int argc, char** argv)
{
std::string test("49276d206b696c6c");
convertHexToBase64(test);
}
が、あなたの例でセマンティックアクションは残りのものを無視して最後の文字にのみ付けられます。あなたが提案する代替案は、 'vector'という属性を持っていなければなりません。あなたが(-nほとんど)完全な例を提供すれば、より簡単になり(あなたにとっては良いでしょう)。 –
llonesmiz
私はこれまでのものを加えました。 – joshu