Skip to content

Instantly share code, notes, and snippets.

@jefftrull
Created May 8, 2013 22:56
Show Gist options
  • Save jefftrull/5544308 to your computer and use it in GitHub Desktop.
Save jefftrull/5544308 to your computer and use it in GitHub Desktop.
Using semantic actions with synthesized attributes. Do the attributes only get matched with the part of the rule that lacks actions? Or the whole thing?
// a test case for combining semantic actions with synthesized attributes in the same rule
#include <iostream>
#include <vector>
#include <string>
#include <iterator>
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix.hpp>
void action_func(std::string const& a, std::string const& b)
{
std::cout << "a=" << a << ", b=" << b << std::endl;
}
int main()
{
typedef std::string::iterator Iterator;
namespace qi = boost::spirit::qi;
using boost::spirit::_1;
using boost::spirit::_2;
using boost::phoenix::bind;
typedef std::vector<std::string> result_t;
boost::spirit::qi::rule<Iterator, result_t()> testrule;
// things that compile successfully:
// testrule %= qi::string("A") >> qi::string("B") >> qi::string("C") ; // does not call action
// testrule %= qi::string("A") >> (qi::string("B") >> qi::string("C")) ; // does not call action
// these do not store the synthesized attribute:
// testrule = (qi::string("A") >> qi::string("B") >> qi::string("C"))[bind(action_func, _1, _2)] ;
// testrule = qi::string("A") >> (qi::string("B") >> qi::string("C"))[bind(action_func, _1, _2)] ;
// things that fail to compile entirely
// testrule %= (qi::string("A") >> qi::string("B") >> qi::string("C"))[bind(action_func, _1, _2)] ;
// testrule %= qi::string("A") >> (qi::string("B") >> qi::string("C"))[bind(action_func, _1, _2)];
std::string testdata("ABC");
result_t result;
Iterator beg = testdata.begin();
if (!qi::parse(beg, testdata.end(), testrule, result))
{
std::cerr << "parse failed" << std::endl;
return 1;
}
if (beg != testdata.end())
{
std::cerr << "not all input consumed! Remaining: ";
std::copy(beg, testdata.end(), std::ostream_iterator<char>(std::cerr, ""));
std::cerr << std::endl;
return 2;
}
std::cout << "parsed vector result:" << std::endl;
std::copy(result.begin(), result.end(), std::ostream_iterator<std::string>(std::cout, "\n"));
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment