boost-spirit

C++/Boost: Writing a more powerful sscanf replacement

女生的网名这么多〃 提交于 2019-12-05 23:31:04
问题 I want to write a function in C++ to replace C's sscanf that assigns the matches to iterator. Basically, I want something like: string s = "0.5 6 hello"; std::vector<boost::any> any_vector; sscanv(s, "%f %i %s", any_vector); cout << "float: " << any_cast<float>(any_vector[0]); cout << "integer: " << any_cast<integer(any_vector[1]); cout << "string: " << any_cast<string>(any_vector[2]); The exact details may vary, but you get the idea. Any ideas for implementation? Options so far along with

parse typed csv file with boost::spirit::qi

妖精的绣舞 提交于 2019-12-05 22:51:54
I want to parse a CSV-File with typed values. The type of every column is defined in the header, e.x.: int double double int unsigned 12 1.3 23445 1 42 45 46 47 48 49 The result data structure may be something like this 2-dimensional vector: using ColumnType = boost::variant< std::vector<int>, std::vector<unsigned>, std::vector<double> >; using ResultType = std::vector<ColumnType>; My working code: namespace phoenix = boost::phoenix; namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; using ColumnType = boost::variant< std::vector<int>, std::vector<unsigned>, std::vector

boost spirit parsing CSV with columns in variable order

只愿长相守 提交于 2019-12-05 22:40:51
I'm trying to parse a CSV file (with header line) using boost spirit. The csv is not in a constant format. Sometimes there is some extra column or the order of the column is mixed. I'm interested in few columns, whose header name is well known. For instance my CSV may look like: Name,Surname,Age John,Doe,32 Or: Age,Name 32,John I want to parse only the content of Name and Age (N.B. Age is integer type). At the moment i come out with a very ugly solution where Spirit parses the first line and creates a vector that contains an enum in the positions i'm interested into. And then i have to do the

Using Boost Spirit to parse a text file while skipping large parts of it

廉价感情. 提交于 2019-12-05 21:40:32
I have the following std::string : <lots of text not including "label A" or "label B"> label A: 34 <lots of text not including "label A" or "label B"> label B: 45 <lots of text not including "label A" or "label B"> ... I want extract single integral numbers following all occurrences of label A or label B and place them in corresponding vector<int> a, b . A simple, but not elegant way of doing it is using find("label A") and find("label B") and parsing whichever is first. Is there a succinct way of expressing it using Spirit? How do you skip everything but label A or label B ? You can just omit

Is there a way to match the content of a spirit::lex string token as a literal in a spirit::qi grammar

对着背影说爱祢 提交于 2019-12-05 20:49:34
I'm writing a DSL and using a Boost Spirit lexer to tokenize my input. In my grammar, I want a rule similar to this (where tok is the lexer): header_block = tok.name >> ':' >> tok.stringval > ';' >> tok.description >> ':' >> tok.stringval > ';' ; Rather than specifying reserved words for the language (e.g. "name", "description") and deal with synchronizing these between the lexer and grammar, I want to just tokenize everything that matches [a-zA-Z_]\w* as a single token type (e.g. tok.symbol ), and let the grammar sort it out. If I weren't using a lexer, I might do something like this:

How might I assume a “default value” when parsing using boost::spirit?

拜拜、爱过 提交于 2019-12-05 20:43:07
Let's say I have a grammar defined to something like: some_rule := a b [c [d]] where c , and d are optional and default to a certain value (let's say 14) if not given. Can I get it to default to the 14 if the value isn't given? I want the produced std::vector to always be of size 4. The closest I've come is like the following: qi::rule<Iterator, std::vector<int>(), ascii::space_type> some_rule; some_rule %= int_ >> int_ >> -int_ >> -int_; // ... some_other_rule = some_rule[&some_callback_for_int_vectors]; which will then get 0 for the optional values that didn't show up (I believe). I then

Boost spirit lex write token value back to input stream

橙三吉。 提交于 2019-12-05 20:01:21
I'm wondering if there's a way in boost::spirit::lex to write a token value back to the input stream (possibly after editing) and rescanning again. What I'm basically looking for is a functionality like that offered by unput() in Flex. Thanks! Sounds like you just want to accept tokens in different orders but with the same meaning. Without further ado, here is a complete sample that shows how this would be done, exposing the identifier regardless of input order. Output: Input 'abc(' Parsed as: '(abc' Input '(abc' Parsed as: '(abc' Code #include <boost/spirit/include/qi.hpp> #include <boost

Generate string if boolean attribute is true (karma counterpart to qi::matches)

好久不见. 提交于 2019-12-05 19:32:36
Imagine we want to parse and generate simple C++ member function declarations with Boost.Spirit. The Qi grammar might look like this: function_ %= type_ > id_ > "()" > matches["const"]; That means, whether the function is const is stored in a bool . How to write the corresponding generator with Karma? function_ %= type_ << ' ' << id_ << "()" << XXX[" const"]; Here, we want a directive that consumes a boolean attribute, executes the embedded generator if the attribute is true and does nothing otherwise. We want something that makes the following tests succeed. test_generator_attr("abc", XXX[

Segmentation fault with trivial Spirit Parser grammar

霸气de小男生 提交于 2019-12-05 19:07:41
I'm running into frequent segfaults with my Spirit Qi parser. After spending days to debug the issue (I found the stacktraces impossible to grok) I decided to trim it down to a minimal example. Can anyone tell what I'm doing wrong, if anything? Save code as bug.cpp, compile with g++ -Wall -o bug bug.cpp and you should be good to go. //#define BOOST_SPIRIT_DEBUG_PRINT_SOME 80 //#define BOOST_SPIRIT_DEBUG #include <boost/spirit/version.hpp> #include <boost/spirit/include/qi.hpp> #include <iostream> #include <fstream> #include <iterator> #include <string> namespace /*anon*/ { using namespace

How do I parse end-of-line with boost::spirit::qi?

匆匆过客 提交于 2019-12-05 18:21:30
问题 Shouldn't a simple eol do the trick? #include <algorithm> #include <boost/spirit/include/qi.hpp> #include <iostream> #include <string> using boost::spirit::ascii::space; using boost::spirit::lit; using boost::spirit::qi::eol; using boost::spirit::qi::phrase_parse; struct fix : std::unary_function<char, void> { fix(std::string &result) : result(result) {} void operator() (char c) { if (c == '\n') result += "\\n"; else if (c == '\r') result += "\\r"; else result += c; } std::string &result; };