Skip to content

Instantly share code, notes, and snippets.

@ArGxento
Created October 21, 2012 01:53
Show Gist options
  • Save ArGxento/3925437 to your computer and use it in GitHub Desktop.
Save ArGxento/3925437 to your computer and use it in GitHub Desktop.
cheatsheet of boost.xpressive w/ semantic actions
#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