Created
October 21, 2012 01:53
-
-
Save ArGxento/3925437 to your computer and use it in GitHub Desktop.
cheatsheet of boost.xpressive w/ semantic actions
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
#include <iostream> | |
#include <string> | |
#include <stack> | |
#include <functional> | |
//xpressiveのうち、staticのためのヘッダ | |
#include <boost/xpressive/xpressive_static.hpp> | |
// セマンティックアクションのためのヘッダ | |
#include <boost/xpressive/regex_actions.hpp> | |
namespace xpr = boost::xpressive; | |
std::stack<int> operandStack; //計算用スタック | |
struct Operand { // オペランド(終端子)を扱う関数の実体。意図的にはdouble→void。多態は無理っぽい | |
typedef void result_type; | |
void operator()(const int i) const{ | |
operandStack.push(i); | |
}; | |
}; | |
struct Operator { // オペレータを扱う関数の実体 | |
typedef void result_type; | |
void operator()(std::function<int(int, int)> f) const{ | |
double i, j; | |
i = operandStack.top(); | |
operandStack.pop(); | |
j = operandStack.top(); | |
operandStack.pop(); | |
operandStack.push(f(i, j)); | |
}; | |
}; | |
int main() { | |
const xpr::function<Operand>::type rcvOperand = {{}}; | |
const xpr::function<Operator>::type rcvOperator = {{}}; | |
xpr::sregex digit, expr, term, op1, op2; | |
using namespace boost::xpressive; | |
digit = (+_d)[rcvOperand(as<int>(_))] ; | |
term = (digit | (as_xpr('(') >> *_s >> by_ref(expr) >> ')')) >> *_s ; | |
op1 = term >> *(((s1 = as_xpr('*') | '/') >> *_s >> term)[rcvOperator(((as<char>(s1) == '*')? std::multiplies<int>: std::divides<int>))]); | |
op2 = op1 >> *(((s1 = as_xpr('+') | '-' ) >> *_s >> op1)[rcvOperator(((as<char>(s1) == '+')? std::plus<int>: std::minus<int>))]); | |
expr = bos >> *_s >> op2 >> eos; | |
smatch match; | |
std::string str("1 * (2 + 3) + 4 * 6"); //->29 | |
if(regex_match(str, match, expr)){ | |
std::cout << | |
"Ans: " << operandStack.top() << std::endl; | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment