1

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?

Community
  • 1
  • 1
Jepessen
  • 11,744
  • 14
  • 82
  • 149

1 Answers1

1

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:

  • drop the classic include
  • any particular reason to use wstring?

Compiling On Coliru

#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
sehe
  • 374,641
  • 47
  • 450
  • 633
  • I set `BOOST_SPIRIT_DEBUG` in project options so it's used by the compiler. I'll try your approach. Thanks for your help. – Jepessen Feb 09 '15 at 13:36
  • It compiles (thanks) but I obtain no output from the failed parsing, I've set the `BOOST_SPIRIT_DEBUG` define, so what I can do? maybe my parser is wrong? – Jepessen Feb 09 '15 at 22:26
  • I see nothing that explains that in your code as shown. Can you post a SSCCE? As it is you don't parse anything really:) – sehe Feb 09 '15 at 22:32
  • @Jepessen I just realized you should drop the `classic` header. Apparently it block the debug feature (I didn't know this). Updated – sehe Feb 10 '15 at 08:07
  • I'll check it asap. Sorry if I reply always late, but I'm working in two different places.. – Jepessen Feb 10 '15 at 08:44
  • I removed the header. Now the parsers fails (obviously), but at least I've the log. Thanks for your help. – Jepessen Feb 10 '15 at 20:04