|
|
|
@ -12,24 +12,12 @@ |
|
|
|
|
using namespace peglib; |
|
|
|
|
using namespace std; |
|
|
|
|
|
|
|
|
|
//
|
|
|
|
|
// PEG syntax:
|
|
|
|
|
//
|
|
|
|
|
// EXPRESSION <- _ TERM (TERM_OPERATOR TERM)*
|
|
|
|
|
// TERM <- FACTOR (FACTOR_OPERATOR FACTOR)*
|
|
|
|
|
// FACTOR <- NUMBER / '(' _ EXPRESSION ')' _
|
|
|
|
|
// TERM_OPERATOR <- < [-+] > _
|
|
|
|
|
// FACTOR_OPERATOR <- < [/*] > _
|
|
|
|
|
// NUMBER <- < [0-9]+ > _
|
|
|
|
|
// ~_ <- [ \t\r\n]*
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
template <typename T, typename U, typename F> |
|
|
|
|
static U reduce(T i, T end, U val, F f) { |
|
|
|
|
if (i == end) { |
|
|
|
|
return val; |
|
|
|
|
} |
|
|
|
|
std::tie(val, i) = f(val, i); |
|
|
|
|
tie(val, i) = f(val, i); |
|
|
|
|
return reduce(i, end, val, f); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
@ -96,9 +84,7 @@ int main(int argc, const char** argv) |
|
|
|
|
return 1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
const char* s = argv[1]; |
|
|
|
|
|
|
|
|
|
const char* syntax = |
|
|
|
|
peg parser( |
|
|
|
|
" EXPRESSION <- _ TERM (TERM_OPERATOR TERM)* " |
|
|
|
|
" TERM <- FACTOR (FACTOR_OPERATOR FACTOR)* " |
|
|
|
|
" FACTOR <- NUMBER / '(' _ EXPRESSION ')' _ " |
|
|
|
@ -106,9 +92,7 @@ int main(int argc, const char** argv) |
|
|
|
|
" FACTOR_OPERATOR <- < [/*] > _ " |
|
|
|
|
" NUMBER <- < [0-9]+ > _ " |
|
|
|
|
" ~_ <- [ \t\r\n]* " |
|
|
|
|
; |
|
|
|
|
|
|
|
|
|
peg parser(syntax); |
|
|
|
|
); |
|
|
|
|
|
|
|
|
|
parser["EXPRESSION"] = ast_ope::create; |
|
|
|
|
parser["TERM"] = ast_ope::create; |
|
|
|
@ -116,9 +100,10 @@ int main(int argc, const char** argv) |
|
|
|
|
parser["FACTOR_OPERATOR"] = [](const char* s, size_t n) { return *s; }; |
|
|
|
|
parser["NUMBER"] = ast_num::create; |
|
|
|
|
|
|
|
|
|
auto expr = argv[1]; |
|
|
|
|
shared_ptr<ast_node> ast; |
|
|
|
|
if (parser.parse(s, ast)) { |
|
|
|
|
cout << s << " = " << ast->eval() << endl; |
|
|
|
|
if (parser.parse(expr, ast)) { |
|
|
|
|
cout << expr << " = " << ast->eval() << endl; |
|
|
|
|
return 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|