2013-02-21 11 views
5

próbuję zdefiniować własną gramatykę używając ramy ducha doładowania i mam taką zasadę definiowania pasujący:doładowania duch dostać cały mecz jako ciąg

value = (
     char_('"') >> 
     (*qi::lexeme[ 
       char_('\\') >> char_('\\') | 
       char_('\\') >> char_('"') | 
       graph - char_('"') | 
       char_(' ') 
     ])[some_func] >> 
     char_('"') 
); 

chciałbym assing akcję - some_func - do części i przekazuje cały pasujący ciąg jako parametr. Ale niestety otrzymam coś w rodzaju vector<boost::variant<boost::fusion::vector2 ..a lot of stuff...)...>. Czy mogę w jakiś sposób uzyskać wszystkie dane jako char *, std :: string lub nawet void * o rozmiarze?

+0

co jest nie tak z wektorem ? –

+0

Opisuję go jako wektor >>>, ale został on zredagowany przez sehe. – Dejwi

Odpowiedz

8

Spójrz na qi::as_string:

Wyjście z programu demonstracyjnego:

DEBUG: 'some\\"quoted\\"string.' 
parse success 

Szczerze mówiąc, wygląda na to są naprawdę starają się analizować "Verbatim sznurki z możliwych znaków ewakuacyjnych. Pod tym względem użycie lexeme wydaje się błędne (miejsca zostają zjedzone). Jeśli chcesz zobaczyć próbki z interpretowanym łańcuchem znaków, zobacz np.

Prosty przegrupowanie, które myślę, że może być dokonane, co najmniej może wyglądać następująco:

value = qi::lexeme [ 
      char_('"') >> 
      qi::as_string [ 
      *(
       string("\\\\") 
       | string("\\\"") 
       | (graph | ' ') - '"' 
      ) 
      ] [some_func(_1)] >> 
      char_('"') 
     ]; 

Uwaga jednak, że można po prostu zadeklarować regułę bez skipera i upuść lexeme alltogether: http://liveworkspace.org/code/1oEhei$0

Code (żyć na liveworkspace)

#include <boost/fusion/adapted.hpp> 
#include <boost/spirit/include/qi.hpp> 
#include <boost/spirit/include/phoenix.hpp> 

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

struct some_func_t 
{ 
    template <typename> struct result { typedef void type; }; 
    template <typename T> 
     void operator()(T const& s) const 
     { 
      std::cout << "DEBUG: '" << s << "'\n"; 
     } 
}; 

template <typename It, typename Skipper = qi::space_type> 
    struct parser : qi::grammar<It, Skipper> 
{ 
    parser() : parser::base_type(value) 
    { 
     using namespace qi; 
     // using phx::bind; using phx::ref; using phx::val; 

     value = (
       char_('"') >> 
        qi::as_string 
        [ 
         (*qi::lexeme[ 
          char_('\\') >> char_('\\') | 
          char_('\\') >> char_('"') | 
          graph - char_('"') | 
          char_(' ') 
          ]) 
        ] [some_func(_1)] >> 
       char_('"') 
      ); 
     BOOST_SPIRIT_DEBUG_NODE(value); 
    } 

    private: 
    qi::rule<It, Skipper> value; 
    phx::function<some_func_t> some_func; 
}; 

bool doParse(const std::string& input) 
{ 
    typedef std::string::const_iterator It; 
    auto f(begin(input)), l(end(input)); 

    parser<It, qi::space_type> p; 

    try 
    { 
     bool ok = qi::phrase_parse(f,l,p,qi::space); 
     if (ok) 
     { 
      std::cout << "parse success\n"; 
     } 
     else  std::cerr << "parse failed: '" << std::string(f,l) << "'\n"; 

     if (f!=l) std::cerr << "trailing unparsed: '" << std::string(f,l) << "'\n"; 
     return ok; 
    } catch(const qi::expectation_failure<It>& e) 
    { 
     std::string frag(e.first, e.last); 
     std::cerr << e.what() << "'" << frag << "'\n"; 
    } 

    return false; 
} 

int main() 
{ 
    bool ok = doParse("\"some \\\"quoted\\\" string.\""); 
    return ok? 0 : 255; 
} 
+1

+1 Chciałem wcześniej odpowiedzieć 'as_string', ale nie mógłbym na całe życie znaleźć tego w dokumentach -" dyrektywy parsera ", duh! – ildjarn

+0

Dodałem konkretną ilustrację tego, co uważam za "poprawione" przy użyciu "leksemów". – sehe