Boost Spirit 2.4.2: невозможно извлечь строку - PullRequest
2 голосов
/ 01 июля 2011

После решения вопроса Boost Spirit: Ошибка C2664, Невозможно преобразовать 'const boost :: phoenix :: actor ' в 'char' , у меня есть другой вопрос:

Почему, используя приведенный ниже код для js_key и js_string, я не могу перехватить печать строк в формате "str" ​​или "str". Те всегда возвращаются пустыми!

Например:

Ввод: {"a":"aa", b:'c'} Фактический объем производства:

{
str:
str:
str: b
str:
Successfully parsed the input as JSON!

Ожидаемый результат:

{
str: a
str: aa
str: b
str: c
Successfully parsed the input as JSON!

Пожалуйста, сообщите. Спасибо!

#include <map>
#include <string>
#include <vector>
#include <iostream>

#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_stl.hpp>
#include <boost/spirit/include/phoenix_object.hpp>
#include <boost/spirit/include/phoenix_container.hpp>
#include <boost/spirit/include/phoenix_function.hpp>
#include <boost/spirit/include/phoenix_fusion.hpp>
#include <boost/spirit/include/phoenix_bind.hpp>
#include <boost/fusion/include/adapt_assoc_struct.hpp>
#include <boost/fusion/include/io.hpp>
#include <boost/bind.hpp>
#include <boost/function.hpp>

namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;

void print_char(char c)
{
    std::cout << c << std::endl;
}

void print_str(std::string str)
{
    std::cout << "str: " << str << std::endl;
}

template <typename Iterator>
struct json_grammar : qi::grammar<Iterator, ascii::space_type>
{
    json_grammar() : json_grammar::base_type(start)
    {
        using ascii::alpha;
        using ascii::alnum;
        using qi::long_long;
        using qi::long_double;
        using qi::lit;
        using qi::char_;
        using qi::lexeme;

        // 
        start =
            char_('{')              [phoenix::bind(&print_char, qi::_1)]
            >> -(js_member % ',')
            >> char_('}')
        ;
        // 
        js_member =
            js_key                  [phoenix::bind(&print_str, qi::_1)]
            >> ':' >> js_value
        ;
        // 
        js_key = (alpha >> *alnum) | js_string
        ;
        // 
        js_string = js_single_quoted_str | js_double_quoted_str
        ;
        // 
        js_array = lit('[') >> -(js_value % ',') >> lit(']')
        ;
        // 
        js_bool = lit("true") | lit("false")
        ;
        // 
        js_null = lit("null")
        ;
        // 
        js_value = js_string        [phoenix::bind(&print_str, qi::_1)]
            | js_num | js_array | start | js_bool | js_null;
        // 
        js_single_quoted_str = (lexeme["'" >> *(char_ - "'") >> "'"]);
        // 
        js_double_quoted_str = (lexeme['"' >> *(char_ - '"') >> '"']);
        // 
        js_num = long_long | long_double;
    }

    qi::rule<Iterator, std::string(), ascii::space_type> js_key;
    qi::rule<Iterator, std::string(), ascii::space_type> js_string;

    qi::rule<Iterator, ascii::space_type> start;
    qi::rule<Iterator, ascii::space_type> js_member;
    qi::rule<Iterator, ascii::space_type> js_value;
    qi::rule<Iterator, ascii::space_type> js_single_quoted_str;
    qi::rule<Iterator, ascii::space_type> js_double_quoted_str;
    qi::rule<Iterator, ascii::space_type> js_array;
    qi::rule<Iterator, ascii::space_type> js_num;
    qi::rule<Iterator, ascii::space_type> js_bool;
    qi::rule<Iterator, ascii::space_type> js_null;
};

int main()
{
    std::string inputStr;
    json_grammar<std::string::const_iterator> jsonParser;
    bool parseOK = false;

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

        std::string::const_iterator iter = inputStr.begin();
        std::string::const_iterator iterEnd = inputStr.end();

        parseOK = qi::phrase_parse(iter, iterEnd, jsonParser, ascii::space);

        if(parseOK && iter == iterEnd) {
            std::cout << "Successfully parsed the input as JSON!" << std::endl;
        } else {
            std::cout << "Cannot parse the input as JSON!" << std::endl;
        }
    }

    return 0;
}

1 Ответ

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

Ответ очень прост: 2 структуры js_single_quoted_str и js_double_quoted_str должны быть переопределены следующим образом, чтобы заставить анализатор качаться:

qi::rule<Iterator, std::string(), ascii::space_type> js_single_quoted_str;
qi::rule<Iterator, std::string(), ascii::space_type> js_double_quoted_str;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...