Search code examples
visual-studiodebuggingboostboost-spiritboost-spirit-qi

Error when compiling a grammar with debug activated


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?


Solution

  • 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