Skip to content

Instantly share code, notes, and snippets.

@klmr
Created March 21, 2012 10:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save klmr/2146139 to your computer and use it in GitHub Desktop.
Save klmr/2146139 to your computer and use it in GitHub Desktop.
Ambiguous function call grammar
#include <iostream>
#include <iterator>
#include <string>
#include <boost/spirit/include/qi.hpp>
namespace qi = boost::spirit::qi;
template <typename Iterator>
struct mini_grammar : qi::grammar<Iterator, qi::ascii::space_type> {
typedef qi::rule<Iterator, qi::ascii::space_type> rule_t;
rule_t expression, call, addition, unary, primary, id, number;
mini_grammar() : mini_grammar::base_type(expression) {
expression = call | addition;
call = id >> *addition;
addition =
unary
>> *( ('+' > unary)
| ('-' > unary)
);
unary =
primary |
('(' > (('+' > unary) |
('-' > unary) |
expression) > ')'
);
primary = id | number;
id = qi::lexeme[+qi::char_("a-z")];
number = qi::double_;
}
};
std::string read_input(std::istream& stream) {
return std::string(
std::istreambuf_iterator<char>(stream),
std::istreambuf_iterator<char>());
}
int main() {
std::string const code = read_input(std::cin);
auto const begin = code.begin();
auto end = code.end();
try {
mini_grammar<decltype(end)> grammar;
qi::ascii::space_type space;
bool const success =
qi::phrase_parse(begin, end, *(grammar > ';'), space);
std::cout << std::boolalpha << "Success: " << success << "\n";
}
catch (qi::expectation_failure<decltype(end)> const& ex) {
std::cout << "Failure; parsing stopped after \""
<< std::string(ex.first, ex.last) << "\"\n";
}
}
1;
a;
a + b;
1 + 2;
f a;
f (-1) b;
f (+a) (-b) c;
(-1) + 2;
(f 1) + (g 2 a);
f (a + b) (-c) (g 1);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment