Search code examples
c++parsingboostboost-spirit

function parser using boost-spirit


I'm trying to parse functions using boost spirit. I get a compilation error when I try to save the matching function into string.

Parser.cpp:50:58: error: call of overloaded ‘ref(std::string&)’ is ambiguous int_[ ref(a) = _1 ] >> p.definedFunctions [ref(myFunction) = _1]

The code works fine when replace [ref(myFunction) = _1] with [std::cout<<_1]

Parser.h

#include <spirit/include/qi.hpp>
#include <iostream>
#ifndef PARSER_H
#define PARSER_H

namespace qi = boost::spirit::qi;
class Parser {
public:
    Parser();
    Parser(const Parser& orig);
    virtual ~Parser();
    static std::string parseFuncion(const std::string& s);

private:
    qi::symbols<char, std::string> definedFunctions;
};

#endif /* PARSER_H */

Parser.cpp

#include <iostream>
#include <iomanip>
#include <stdexcept>
#include <cstdlib>
#include <sstream>

#include <spirit/include/qi.hpp>
#include <spirit/include/phoenix.hpp>

#include "Parser.h"
namespace qi = boost::spirit::qi;

Parser::Parser() {
    definedFunctions.add
            ("^"    ,      "pow")
            (">"   ,   "greater")
            ;
}

Parser::Parser(const Parser& orig) {
}

Parser::~Parser() {
}

std::string Parser::parseFuncion(const std::string& s){
    using boost::spirit::qi::_1;
    using boost::spirit::qi::int_;
    using boost::phoenix::ref;
    int a=0, b=0;
    std::string myFunction;
    Parser p;

    const char* first = s.data();
    const char* const end = first + s.size();
    const bool success = boost::spirit::qi::parse(first, end,
                                                  // Implementation of 'full-date' rule from EBNF grammar.
                                                  int_[ ref(a) = _1 ] >> p.definedFunctions [ref(myFunction) = _1]
            >> int_[ ref(b) = _1 ] 
            );
    if (!success || first != end) {
        throw std::logic_error("Parsing failed");
    }
    std::stringstream ss;
    ss<<myFunction<<"("<<a<<","<<b<<")";
    return ss.str();
}

Solution

  • As the error message says the call to ref is ambiguous because there is std::ref and boost::phoenix::ref. Add a

    namespace phx = boost::phoenix;
    

    to the top and use phx::ref in your parse function.