Created
June 5, 2012 14:17
-
-
Save madebyjeffrey/2875279 to your computer and use it in GitHub Desktop.
Question7
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* 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