Skip to content

Instantly share code, notes, and snippets.

@madebyjeffrey
Created June 5, 2012 14:17
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save madebyjeffrey/2875279 to your computer and use it in GitHub Desktop.
Save madebyjeffrey/2875279 to your computer and use it in GitHub Desktop.
Question7
/* example question implementation in spirit:
7. Construct an attribute grammar for the language L so that:
@ has value 2
*@* has value 4 - surrounding an expression with two stars squares its value
(@) has value 3 - putting brackets around an expressions adds 1 to the value
((@)) has value 4
(*(@)*) has value 10
((*((@))*)) has value 18
(((*(*(@)*)*))) has value 103
*/
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_core.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <iostream>
#include <string>
namespace client
{
namespace qi = boost::spirit::qi;
namespace ascii = boost::spirit::ascii;
namespace phoenix = boost::phoenix;
using qi::_1;
using ascii::space;
template <typename Iterator>
struct parse_grammar : qi::grammar<Iterator, unsigned()>
{
parse_grammar() : parse_grammar::base_type(start)
{
using qi::eps;
using qi::lit;
using qi::_val;
using qi::_1;
using ascii::char_;
start = lit('@') >> qi::attr(2)
| lit('*') >> start >> lit('*') [_val *= _val]
| lit('(') >> start >> lit(')') [_val += 1];
}
qi::rule<Iterator, unsigned()> start;
};
}
int main()
{
using namespace client;
parse_grammar<std::string::const_iterator> parser;
std::string str;
unsigned result;
while (std::getline(std::cin, str))
{
if (str.empty() || str[0] == 'q' || str[0] == 'Q')
break;
auto iter = str.cbegin();
auto end = str.cend();
bool r = parse(iter, end, parser, result);
if (r && iter == end)
{
std::cout << "---- success" << std::endl;
std::cout << "result = " << result << std::endl;
std::cout << "---- " << std::endl;
}
else
{
std::string rest(iter, end);
std::cout << "---- failure" << std::endl;
std::cout << " stopped at: \": " << rest << "\"" << std::endl;
std::cout << "----" << std::endl;
}
}
std::cout << "end." << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment