вопрос об улучшении духа правил ци - PullRequest
1 голос
/ 08 июля 2011

У меня следующий код не может скомпилироваться, однако я не знаю, в чем проблема:

#include <boost/config/warning_disable.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_stl.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/variant/recursive_variant.hpp>
#include <boost/foreach.hpp>

#include <iostream>
#include <fstream>
#include <string>
#include <vector>

void print (std::string& s)
{
    std::cout << "Get string [" << s << ']' << std::endl;
}

namespace client
{
    namespace fusion = boost::fusion;
    namespace phoenix = boost::phoenix;
    namespace qi = boost::spirit::qi;
    namespace ascii = boost::spirit::ascii;

    template <typename Iterator>
    struct my_grammar
      : qi::grammar<Iterator, std::string(), ascii::space_type>
    {
        my_grammar()
          : my_grammar::base_type(start)
        {
        using qi::lit;
        using qi::int_;
        using qi::lexeme;
        using ascii::char_;
        using ascii::string;
        using ascii::space_type;
        using namespace qi::labels;


        // Here you can see the rule oct_char with attribute type as char
        // +(char) would be vector<char> which is compactable with string type
        // Why the compiler still told me the type of the attribute is not right?
        start %= lexeme[+(oct_char)] [&print]
            ;

        oct_char =
                   lexeme["//"        
                           >>  char_('0','3') [ _a = ( _1 - '0' ) ]
                     ||     char_('0','7') [ _a = _a << 3 + ( _1 - '0' ) ]
                ||     char_('0','7') [ _a = _a << 3 + ( _1 - '0' ) ]]
                 [ _val = _a ]
                ;
        }
    qi::rule<Iterator, std::string(), ascii::space_type> start;
        qi::rule<Iterator, char(), qi::locals<char>, ascii::space_type> oct_char;

    };
}

int main(int argc, char **argv)
{

    typedef client::my_grammar<std::string::const_iterator> Grammer;
    Grammer grm;

    std::string str;


using boost::spirit::ascii::space;

while (getline(std::cin, str))
{
    if (str.empty() || str[0] == 'q' || str[0] == 'Q')
        break;

    if (phrase_parse(str.begin(), str.end(), grm, space))
    {
        std::cout << "-------------------------\n";
        std::cout << "Parsing succeeded\n";
        std::cout << "got: " << str << std::endl;
        std::cout << "\n-------------------------\n";
    }
    else
    {
        std::cout << "-------------------------\n";
        std::cout << "Parsing failed\n";
        std::cout << "-------------------------\n";
    }
}

std::cout << "Bye... :-) \n\n";
return 0;


}

Вот сообщения об ошибках:

Error   2   error C2664: 'void (std::basic_string<_Elem,_Traits,_Ax> )' : cannot convert parameter 1 from 'std::vector<_Ty>' to 'std::basic_string<_Elem,_Traits,_Ax> ' d:\code\boost_1_46_1\boost\spirit\home\support\action_dispatch.hpp  70

Кто-нибудь может дать некоторые предложения? Спасибо

1 Ответ

2 голосов
/ 09 июля 2011

Это подробно обсуждалось в другом месте (например, здесь ). Если вы измените свою функцию печати на vector<char>, она будет работать:

void print (std::vector<char> const& s)
{
    std::cout << "Get string [" 
              << std::string(s.begin(), s.end()) << ']' 
              << std::endl;
}

В вашем коде есть еще одна ошибка. Правило oct_char не должно иметь шкипера, поскольку оно используется внутри lexeme[]:

qi::rule<Iterator, char(), qi::locals<char> > oct_char;
...