[spirit] Grammar/Action problems

Hi, my first parser and problems :-) Well, obviously I didn't understood the translation of BNF in spirit (probably BNF also); attached the code. The result is: $ g++ spirit.cpp -o spirit && ./spirit [Date] = "[Data Ver] 3.4 " ^-- error ("D") [Data Ver] = 0 "[File Name] foo.csv" ^-- error ("F") [File Name] = [Notes] = y Can anybody help? Further more I need to replace the comment symbol rule dynamically ("[Comment Char]") for the data self (not displayed here). Thanks, Olaf ---8<--- #include <boost/spirit/core.hpp> #include <boost/spirit/symbols/symbols.hpp> #include <boost/spirit/utility/chset.hpp> #include <boost/spirit/utility/escape_char.hpp> #include <boost/spirit/utility/confix.hpp> #include <boost/spirit/actor.hpp> #include <iostream> #include <iomanip> namespace sp = ::boost::spirit; struct data { std::pair<int, int> data_ver; // major,minor std::string comment_char; std::string file_name; std::string file_rev; std::string date; std::string notes; }; struct grammar : public sp::grammar<grammar> { explicit grammar( data& data ) : m_data( data ) { } template <typename ScannerT> struct definition { definition( const grammar& self ) { typedef sp::chset<char> chset_t; using sp::comment_p; using sp::int_p; using sp::anychar_p; using sp::blank_p; using sp::lexeme_d; using sp::as_lower_d; using sp::assign_a; using sp::strlit; data& data = self.m_data; chset_t COMMENT_SYMBOL_CHSET( "!\"#$%&'()*,:;<>?@\\^`{|}~" ); chset_t FILE_NAME_CHSET( "abcdefghijklmnopqrstuvwxyz0123456789_^$~!#%&-{})(@'`" ); std::pair<int, int> v( 0, 0 ); document = comment | data_ver | comment_char | file_name | file_rev | date | notes ; comment = comment_p('|') ; data_ver = ( lexeme_d[strlit<>("[Data Ver]")] >> int_p[assign_a(v.first)] >> '.' >> int_p[assign_a(v.second)] )[assign_a( data.data_ver, v )] ; comment_char = lexeme_d[strlit<>("[Comment Char]")] // FixMe: dynamic rule for comment !!! >> COMMENT_SYMBOL_CHSET[assign_a( data.comment_char )] >> "_char" ; file_name = ( lexeme_d[strlit<>("[File Name]")] >> ( +FILE_NAME_CHSET >> "." >> ( as_lower_d[".csv"] | as_lower_d[".txt"] ) ) )[assign_a( data.file_name )] ; file_rev = lexeme_d[strlit<>("[File Rev]")] >> ( // treated as string +anychar_p )[assign_a( data.file_rev )] ; date = "[Date]" >> ( // treated as string +anychar_p[assign_a( data.date )] ) ; notes = "[Notes]" >> ( // treated as string +anychar_p[assign_a( data.notes )] ) ; } sp::rule<ScannerT> const& start() const { return document; } sp::rule<ScannerT> document, comment, data_ver, comment_char, file_name, file_rev, date, notes ; }; private: data& m_data; }; template <typename GrammarT> static void parse(GrammarT const& grammar, std::string expr) { std::string::iterator first = expr.begin(); sp::parse_info<std::string::iterator> result = sp::parse(first, expr.end(), grammar); if ( !result.hit ) { std::cerr << "\"" << expr << "\"" << std::endl; std::cerr << std::setw(result.stop - expr.begin() + 1) << "^-- error (" << "\"" << *result.stop << "\")" << std::endl; } else if ( !result.full ) { first = result.stop; } } int main() { data d; grammar g( d ); parse( g, "[Date] 19.03.2008 | yeah " ); std::cout << "[Date] = " << d.date << std::endl; parse( g, "[Data Ver] 3.4 " ); std::cout << "[Data Ver] = " << d.data_ver.first << std::endl; parse( g, "[File Name] foo.csv" ); std::cout << "[File Name] = " << d.file_name << std::endl; parse( g, "[Notes] Use this section for any special notes related to the file." " This information is for modeling purposes only, and is not" " guaranteed. | May vary"); std::cout << "[Notes] = " << d.notes << std::endl; } --->8---

sorry, I forgot the white space parser to add here: template <typename GrammarT> static void parse(GrammarT const& grammar, std::string expr) { std::string::iterator first = expr.begin(); sp::parse_info<std::string::iterator> result = sp::parse(first, expr.end(), grammar, sp::space_p); if ( !result.hit ) { std::cerr << "\"" << expr << "\"" << std::endl; std::cerr << std::setw(result.stop - expr.begin() + 1) << "^-- error (" << "\"" << *result.stop << "\")" << std::endl; } else if ( !result.full ) { first = result.stop; } } Thanks, Olaf

template <typename GrammarT> static void parse(GrammarT const& grammar, std::string expr) { std::string::iterator first = expr.begin();
sp::parse_info<std::string::iterator> result = sp::parse(first, expr.end(), grammar, sp::space_p);
if ( !result.hit ) { std::cerr << "\"" << expr << "\"" << std::endl; std::cerr << std::setw(result.stop - expr.begin() + 1) << "^-- error (" << "\"" << *result.stop << "\")" << std::endl; } else if ( !result.full ) { first = result.stop; } }
than I get: $ g++ spirit.cpp -o spirit && ./spirit [Date] = h [Data Ver] = -1078612884 "[File Name] foo.csv" ^-- error ("F") [File Name] = [Notes] = y
participants (1)
-
ope