I'm trying to debug a boost::spirit grammar that I want to use in a Visual Studio project: This is my code snippet:
#include <boost/spirit/include/classic.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
// This is pasted and copied from another header file
namespace StateMachine {
namespace Private {
struct LuaParameterData {
std::wstring name;
std::wstring type;
std::wstring unit;
std::wstring cardinality;
std::wstring value;
};
} // namespace Private
} // namespace StateMachine
BOOST_FUSION_ADAPT_STRUCT(
StateMachine::Private::LuaParameterData,
(std::wstring, name)
(std::wstring, type)
(std::wstring, unit)
(std::wstring, cardinality)
(std::wstring, value)
)
// From here original file continues
namespace StateMachine {
namespace Private {
namespace qi = boost::spirit::qi;
template<typename Iterator>
struct LuaParameterDataParser : qi::grammar<Iterator, LuaParameterData(), qi::ascii::space_type>
{
LuaParameterDataParser() : LuaParameterDataParser::base_type(start)
{
quotedString %= qi::lexeme['"' >> +(qi::ascii::char_ - '"') >> '"'];
start %=
qi::lit("\"parameter\"")
>> ':'
>> '{'
>> qi::lit("\"name\"" ) >> ':' >> quotedString >> ','
>> qi::lit("\"type\"" ) >> ':' >> quotedString >> ','
>> qi::lit("\"unit\"" ) >> ':' >> quotedString >> ','
>> qi::lit("\"cardinality\"") >> ':' >> quotedString >> ','
>> qi::lit("\"value\"" ) >> ':' >> quotedString
>> '}'
;
}
qi::rule<Iterator, std::string(), qi::ascii::space_type> quotedString;
qi::rule<Iterator, LuaParameterData(), qi::ascii::space_type> start;
};
} // namespace Private
} // namespace StateMachine
BOOST_SPIRIT_DEBUG_RULE(StateMachine::Private::LuaParameterDataParser<std::string::const_iterator>::quotedString);
The macro BOOST_SPIRIT_DEBUG
is defined in project properties.
When I compile it I obtain following errors in the last line where I use BOOST_SPIRIT_DEBUG_RULE
:
error C3484: syntax error: expected '->' before the return type
error C2061: syntax error : identifier 'register_node'
I don't know if I'm doing the right thing. I want to debug my grammar, but I've seen only hints for debugging rules (here and here) so I've tried to adapt my code.
What I'm doing wrong and what I must do in order to print debugging information when I use this grammar with phrase_parse
?
The field is not static.
Also you're not showing the #define BOOST_SPIRIT_DEBUG
line (perhaps you specify it at the compiler command line).
The typical approach is to use BOOST_SPIRIT_DEBUG_NODES() e.g.
Notes:
classic
includewstring
?#define BOOST_SPIRIT_DEBUG
#include <boost/fusion/include/io.hpp>
//#include <boost/spirit/include/classic.hpp>
#include <boost/spirit/include/qi.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
// This is pasted and copied from another header file
namespace StateMachine {
namespace Private {
struct LuaParameterData {
std::wstring name;
std::wstring type;
std::wstring unit;
std::wstring cardinality;
std::wstring value;
};
} // namespace Private
} // namespace StateMachine
BOOST_FUSION_ADAPT_STRUCT(
StateMachine::Private::LuaParameterData,
(std::wstring, name)
(std::wstring, type)
(std::wstring, unit)
(std::wstring, cardinality)
(std::wstring, value)
)
namespace qi = boost::spirit::qi;
// From here original file continues
namespace StateMachine {
namespace Private {
template<typename Iterator>
struct LuaParameterDataParser : qi::grammar<Iterator, LuaParameterData(), qi::ascii::space_type>
{
LuaParameterDataParser() : LuaParameterDataParser::base_type(start)
{
quotedString = qi::lexeme['"' >> +(qi::ascii::char_ - '"') >> '"'];
start =
qi::lit("\"parameter\"")
>> ':'
>> '{'
>> qi::lit("\"name\"" ) >> ':' >> quotedString >> ','
>> qi::lit("\"type\"" ) >> ':' >> quotedString >> ','
>> qi::lit("\"unit\"" ) >> ':' >> quotedString >> ','
>> qi::lit("\"cardinality\"") >> ':' >> quotedString >> ','
>> qi::lit("\"value\"" ) >> ':' >> quotedString
>> '}'
;
BOOST_SPIRIT_DEBUG_NODES((start)(quotedString));
}
qi::rule<Iterator, std::string(), qi::ascii::space_type> quotedString;
qi::rule<Iterator, LuaParameterData(), qi::ascii::space_type> start;
};
} // namespace Private
} // namespace StateMachine
int main() {
using It = std::string::const_iterator;
std::string const input = R"(
"parameter" : {
"name" : "name" ,
"type" : "type" ,
"unit" : "unit" ,
"cardinality" : "cardinality",
"value" : "value"
}
)";
It f = input.begin(),
l = input.end();
StateMachine::Private::LuaParameterDataParser<It> p;
StateMachine::Private::LuaParameterData data;
bool ok = qi::phrase_parse(f, l, p, qi::ascii::space, data);
if (ok) {
std::wcout << L"Parsed: \n";
std::wcout << L"\tname: " << data.name << L'\n';
std::wcout << L"\ttype: " << data.type << L'\n';
std::wcout << L"\tunit: " << data.unit << L'\n';
std::wcout << L"\tcardinality: " << data.cardinality << L'\n';
std::wcout << L"\tvalue: " << data.value << L'\n';
} else {
std::wcout << L"Parse failure\n";
}
if (f!=l)
std::wcout << L"Remaining unparsed: '" << std::wstring(f,l) << L"'\n";
}
Prints
<start>
<try>\n "parameter"</try>
<quotedString>
<try> "name" , \n </try>
<success> , \n </success>
<attributes>[[n, a, m, e]]</attributes>
</quotedString>
<quotedString>
<try> "type" , \n </try>
<success> , \n </success>
<attributes>[[t, y, p, e]]</attributes>
</quotedString>
<quotedString>
<try> "unit" , \n </try>
<success> , \n </success>
<attributes>[[u, n, i, t]]</attributes>
</quotedString>
<quotedString>
<try> "cardinality", \n </try>
<success>, \n "valu</success>
<attributes>[[c, a, r, d, i, n, a, l, i, t, y]]</attributes>
</quotedString>
<quotedString>
<try> "value" \n </try>
<success> \n }\n </success>
<attributes>[[v, a, l, u, e]]</attributes>
</quotedString>
<success>\n </success>
<attributes>[[[110, 97, 109, 101], [116, 121, 112, 101], [117, 110, 105, 116], [99, 97, 114, 100, 105, 110, 97, 108, 105, 116, 121], [118, 97, 108, 117, 101]]]</attributes>
</start>
Parsed:
name: name
type: type
unit: unit
cardinality: cardinality
value: value