9 Feb 19:31
Parsing escaped strings
Steffen Rauh <steffen.rauh <at> gmx.de>
2010-02-09 18:31:44 GMT
2010-02-09 18:31:44 GMT
Hi all,
I am trying to parse escaped strings (backslash as escape char) with spirit 2.2. I do not want spirit to
unescape the strings itself but to simply provide the complete string to the attached action (I have my own
code to unescape those strings afterwards).
The code at the end shows how I try to do it. With line #2 active, the code compiles and fails with parsing the
provided string as expected. With line #1 active, compilation fails with a message that value_type
cannot be converted to std::basic_string (\spirit\home\support\attributes.hpp(409)). Is there
something I got wrong with the attributes?
A search on google showed one solution by using a symbol table. But this won't be practical in my case,
because escaped strings can be multiple bytes encoded as hex (i.e. \x11223344). I did not show this in the
example for simplification.
Any suggestions?
Regards,
Steffen
--------------------------------------------
#include <iostream>
#include <string>
#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_fusion.hpp"
#include "boost/spirit/include/phoenix_stl.hpp"
namespace fusion = boost::fusion;
namespace phoenix = boost::phoenix;
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
void PrintString(const std::string& Text)
{
std::cout << "String: " << Text << "\n";
}
template <typename Iterator>
struct CGrammar
: boost::spirit::qi::grammar<Iterator, boost::spirit::ascii::space_type>
{
CGrammar()
: CGrammar::base_type(Rule)
{
using qi::eps;
using namespace ascii;
StringChar %= qi::lexeme[char_ - char_('"') - char_('\\')];
EscapedChar %= qi::lexeme[char_('\\') >> char_];
// EscapedString %= char_('"') >> *(StringChar | EscapedChar) >> char_('"'); // #1
EscapedString %= char_('"') >> *(StringChar) >> char_('"'); // #2
Rule = (EscapedString[&PrintString]) % eps;
}
qi::rule<Iterator, char(), ascii::space_type> StringChar;
qi::rule<Iterator, std::string(), ascii::space_type> EscapedChar;
qi::rule<Iterator, std::string(), ascii::space_type> EscapedString;
qi::rule<Iterator, ascii::space_type> Rule;
};
int main(int argc, char **argv)
{
std::string storage("\"test1\\\"test2\"");
typedef CGrammar<std::string::const_iterator> CTestGrammar;
CTestGrammar TestGrammar;
using boost::spirit::ascii::space;
std::string::const_iterator iter = storage.begin();
std::string::const_iterator end = storage.end();
bool r = phrase_parse(iter, end, TestGrammar, space);
if (r && iter == end)
{
std::cout << "Parsing succeeded\n";
}
else
{
std::string context(iter, end);
std::cout << "Parsing failed\n";
std::cout << "stopped at: " << context << "\n";
}
return 0;
}
--
--
NEU: Mit GMX DSL über 1000,- ¿ sparen!
http://portal.gmx.net/de/go/dsl02
------------------------------------------------------------------------------
The Planet: dedicated and managed hosting, cloud storage, colocation
Stay online with enterprise data centers and the best network in the business
Choose flexible plans and management services without long-term contracts
Personal 24x7 support from experience hosting pros just a phone call away.
http://p.sf.net/sfu/theplanet-com
RSS Feed