Hello, How to use the string parser? I tried this way: std::string s1; bool r = qi::phrase_parse(first, last, ( string[ref(s1) = _1] ) , space); But it doesn't compile. Thanks.
How to use the string parser? I tried this way:
std::string s1; bool r = qi::phrase_parse(first, last, ( string[ref(s1) = _1] ) , space);
But it doesn't compile.
Please provide us with a minimal, self-contained piece of code we can compile. We have no crystal ball to see what you're doing... Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com
Please provide us with a minimal, self-contained piece of code we can compile. We have no crystal ball to see what you're doing...
Sorry, I was sure it's so basic, that there's even no need for real source-code.
Here it is:
#include <string>
#include
Please provide us with a minimal, self-contained piece of code we can compile. We have no crystal ball to see what you're doing...
Sorry, I was sure it's so basic, that there's even no need for real source-code.
Sure it is, but I wanted to see which placeholder do you use, and what includes you have.
Here it is:
#include <string> #include
#include #include namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii; namespace phoenix = boost::phoenix; int main() { using qi::int_; using qi::string; using qi::_1; using ascii::space; using phoenix::ref;
int i1; std::string s1; std::string source; std::string::iterator first = source.begin(), last = source.end(); // compiles well: qi::phrase_parse(first, last, ( int_[ref(i1) = _1] ) , space);
// doesn't compile: qi::phrase_parse(first, last, ( string[ref(s1) = _1] ) , space);
}
qi::string is not a valid parser primitive. What would you expect it to match anyway? You'll have to be a bit more specific about what kind of string you need to parse, for instance: '"' >> ~+char_('"') >> '"' (i.e. a quote followed by at least one character which is not a quote followed by a quote). Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com
qi::string is not a valid parser primitive. What would you expect it to match anyway? You'll have to be a bit more specific about what kind of string you need to parse, for instance:
'"' >> ~+char_('"') >> '"'
Ok, I see... Actually, I have to parse a list of strings, where every line consists of numbers and "strings" delimited by ":" -- where "strings" may be empty or may contain virtually any character (except for the delimeter), like this: 1:23:string#1:optional&string@2 2:34:string#2:optional.string%3 besides, the last "string" in the line may be absent with the preceeding delimeter, i.e. both "1:23:string#1:" and "1:23:string#1" are valid (of course, "1:23::" is valid too) Is it possible with Spirit? Would it be the right tool? Thanks.
Igor R wrote:
qi::string is not a valid parser primitive. What would you expect it to match anyway? You'll have to be a bit more specific about what kind of string you need to parse, for instance:
'"' >> ~+char_('"') >> '"'
Ok, I see... Actually, I have to parse a list of strings, where every line consists of numbers and "strings" delimited by ":" -- where "strings" may be empty or may contain virtually any character (except for the delimeter), like this: 1:23:string#1:optional&string@2 2:34:string#2:optional.string%3
besides, the last "string" in the line may be absent with the preceeding delimeter, i.e. both "1:23:string#1:" and "1:23:string#1" are valid (of course, "1:23::" is valid too)
Is it possible with Spirit? Would it be the right tool?
Thanks.
Hi Igor - Spirit has a built-in construct for lists: ~*char( ':' ) % ':' If you use attribute parsing you can simply perform the following: std::vector< std::string > list_of_strings; parse( begin, end, ~*char( ':' ) % ':', list_of_strings ); Nice huh? HTH - michael -- ---------------------------------- Michael Caisse Object Modeling Designs www.objectmodelingdesigns.com
Spirit has a built-in construct for lists:
~*char( ':' ) % ':'
If you use attribute parsing you can simply perform the following:
std::vector< std::string > list_of_strings;
parse( begin, end, ~*char( ':' ) % ':', list_of_strings );
Nice huh?
Nice, but IUUC, it won't take into account the type of the elements, right?
I tried to do the following (but it doesn't match the input string):
//
#include
Spirit has a built-in construct for lists:
~*char( ':' ) % ':'
If you use attribute parsing you can simply perform the following:
std::vector< std::string > list_of_strings;
parse( begin, end, ~*char( ':' ) % ':', list_of_strings );
Nice huh?
Nice, but IUUC, it won't take into account the type of the elements, right? I tried to do the following (but it doesn't match the input string):
template <typename Iterator> struct sensor_parser : qi::grammar
{ sensor_parser() : sensor_parser::base_type(start) { using qi::int_; using qi::lit; using qi::double_; using qi::lexeme; using qi::eol; using ascii::char_; text %= lexeme[+(char_ - ':')];
start %= int_ >> ':' >> text >> ':' >> int_ >> ':' >> int_ >> ':' >> text >> -(':' >> int_) >> -(':' >> text) >> eol ; }
Your last 'text' parser eats your '\r\n' characters. As a result the eol parser fails. Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com
Your last 'text' parser eats your '\r\n' characters. As a result the eol parser fails.
Ah, right, and the last struct field has "\r\n" at the end. If I change to: text %= lexeme[+(char_ - ':' - '\r' - '\n')]; the last field is set correctly, but phrase_parse() still returns false. If I change eol to the explicit "\r\n", it still returns false.
Your last 'text' parser eats your '\r\n' characters. As a result the eol parser fails.
Ah, right, and the last struct field has "\r\n" at the end.
If I change to: text %= lexeme[+(char_ - ':' - '\r' - '\n')];
I'd rather write: text %= lexeme[+~char_("\r\n:")]; which is more efficient.
the last field is set correctly, but phrase_parse() still returns false. If I change eol to the explicit "\r\n", it still returns false.
Yeah, now your skip parser (space) is eating the eol characters. Use qi::blank instead (which matches space and tab only). Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com
Yeah, now your skip parser (space) is eating the eol characters. Use qi::blank instead (which matches space and tab only).
Then it doesn't compile (msvc9.0).
#include
Yeah, now your skip parser (space) is eating the eol characters. Use qi::blank instead (which matches space and tab only).
Then it doesn't compile (msvc9.0).
#include
#include #include #include #include #include #include <string> namespace qi = boost::spirit::qi; namespace ascii = boost::spirit::ascii;
namespace details { struct sensor { int id; std::string type; int cam; int group; std::string name; int state; std::string regs; }; }
BOOST_FUSION_ADAPT_STRUCT ( details::sensor, (int, id) (std::string, type) (int, cam) (int, group) (std::string, name) (int, state) (std::string, regs) )
namespace details { template <typename Iterator> struct sensor_parser : qi::grammar
{ sensor_parser() : sensor_parser::base_type(start) { using qi::int_; using qi::lit; using qi::double_; using qi::lexeme; using qi::eol; using ascii::char_; text %= lexeme[+~char_("\r\n:")];
start %= int_ >> ':' >> text >> ':' >> int_ >> ':' >> int_ >> ':' >> text >> -(':' >> int_) >> -(':' >> text) >> eol ; }
qi::rule
text; qi::rule start; }; } int main() { typedef std::string::const_iterator iterator_type; typedef details::sensor_parser
sensor_parser; std::string str = "3:abcd:4:5:My name:6:33333333333\r\n"; details::sensor sens; std::string::const_iterator iter = str.begin(); std::string::const_iterator end = str.end();
sensor_parser g; using qi::blank; bool r = phrase_parse(iter, end, g, blank, sens); }
Why do you ask me to spoon feed answers to you? Everything should be in the error messages. Even more, the error you're getting points you to rule.hpp, line 245. And if you read the comment above that line you have the answer you need: // If you are seeing a compilation error here stating that the // forth parameter can't be converted to a qi::reference // then you are probably trying to use a rule or a grammar with // an incompatible skipper type. Anyway, the reason for your problem is that you're trying to use qi::blank for a grammar which was defined to use ascii::space_type. That can't work. HTH Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com
On 2/19/2010 7:33 AM, Igor R wrote:
Anyway, the reason for your problem is that you're trying to use qi::blank for a grammar which was defined to use ascii::space_type. That can't work.
Thanks, now it works.
Gentlemen, please post Spirit related questions to the proper list: http://boost-spirit.com/home/feedback-and-support/ Cheers, -- Joel de Guzman http://www.boostpro.com http://spirit.sf.net http://www.facebook.com/djowel Meet me at BoostCon http://www.boostcon.com/home http://www.facebook.com/boostcon
qi::string is not a valid parser primitive. What would you expect it to match anyway? You'll have to be a bit more specific about what kind of string you need to parse, for instance:
'"' >> ~+char_('"') >> '"'
Ok, I see... Actually, I have to parse a list of strings, where every line consists of numbers and "strings" delimited by ":" -- where "strings" may be empty or may contain virtually any character (except for the delimeter), like this: 1:23:string#1:optional&string@2 2:34:string#2:optional.string%3
besides, the last "string" in the line may be absent with the preceeding delimeter, i.e. both "1:23:string#1:" and "1:23:string#1" are valid (of course, "1:23::" is valid too)
Is it possible with Spirit? Would it be the right tool?
Definitely. I'd start looking at the list parser (operator %), Kleene and plus operators (operator*, operator+), the primitive character parsers, and at attribute handling allowing to fill your data structure directly during the parsing. Did you see Spirit's web site (http://boost-spirit.com/)? The examples and tests provided with Spirit are a good source of information as well (in addition to the docs). HTH Regards Hartmut --------------- Meet me at BoostCon www.boostcon.com
Definitely. I'd start looking at the list parser (operator %), Kleene and plus operators (operator*, operator+), the primitive character parsers, and at attribute handling allowing to fill your data structure directly during the parsing. Did you see Spirit's web site (http://boost-spirit.com/)? The examples and tests provided with Spirit are a good source of information as well (in addition to the docs).
Thanks for the pointer! I used the spirit docs included in boost 1.42 so far.
participants (4)
-
Hartmut Kaiser
-
Igor R
-
Joel de Guzman
-
Michael Caisse