|
|
@@ -1,11 +1,13 @@ |
|
|
|
// |
|
|
|
// Lol Engine - Sandbox program |
|
|
|
// Lol Engine - Sandbox program |
|
|
|
// |
|
|
|
// Copyright: (c) 2005-2011 Sam Hocevar <sam@hocevar.net> |
|
|
|
// This program is free software; you can redistribute it and/or |
|
|
|
// modify it under the terms of the Do What The Fuck You Want To |
|
|
|
// Public License, Version 2, as published by Sam Hocevar. See |
|
|
|
// http://www.wtfpl.net/ for more details. |
|
|
|
// Copyright © 2005-2015 Sam Hocevar <sam@hocevar.net> |
|
|
|
// |
|
|
|
// This program is free software. It comes without any warranty, to |
|
|
|
// the extent permitted by applicable law. You can redistribute it |
|
|
|
// and/or modify it under the terms of the Do What the Fuck You Want |
|
|
|
// to Public License, Version 2, as published by the WTFPL Task Force. |
|
|
|
// See http://www.wtfpl.net/ for more details. |
|
|
|
// |
|
|
|
|
|
|
|
#if HAVE_CONFIG_H |
|
|
@@ -14,22 +16,151 @@ |
|
|
|
|
|
|
|
#include <lol/engine.h> |
|
|
|
|
|
|
|
#include "pegtl.hh" |
|
|
|
namespace lol { namespace parser = pegtl; } |
|
|
|
|
|
|
|
#include "axe.h" |
|
|
|
namespace lol { using namespace axe; } |
|
|
|
|
|
|
|
using namespace lol; |
|
|
|
|
|
|
|
int main(int argc, char **argv) |
|
|
|
// |
|
|
|
// Parser tools for a simple calculator grammar with + - * / |
|
|
|
// |
|
|
|
|
|
|
|
struct calculator |
|
|
|
{ |
|
|
|
ivec2 size(128, 128); |
|
|
|
void push(double d) { stack.Push(d); } |
|
|
|
void pop() { printf("%f\n", stack.Pop()); } |
|
|
|
|
|
|
|
if (argc > 1) |
|
|
|
size.x = size.y = atoi(argv[1]); |
|
|
|
if (argc > 2) |
|
|
|
size.y = atoi(argv[2]); |
|
|
|
void mul() { auto x = stack.Pop(); stack.Push(stack.Pop() * x); } |
|
|
|
void div() { auto x = stack.Pop(); stack.Push(stack.Pop() / x); } |
|
|
|
void add() { auto x = stack.Pop(); stack.Push(stack.Pop() + x); } |
|
|
|
void sub() { auto x = stack.Pop(); stack.Push(stack.Pop() - x); } |
|
|
|
|
|
|
|
array2d<float> vac = Image::BlueNoiseKernel(size); |
|
|
|
for (int y = 0; y < size.y; ++y) |
|
|
|
for (int x = 0; x < size.x; ++x) |
|
|
|
printf("%d %d %f\n", x, y, vac[x][y]); |
|
|
|
array<double> stack; |
|
|
|
}; |
|
|
|
|
|
|
|
static void parse_pegtl(std::string const &str); |
|
|
|
static void parse_axe(std::string const &str); |
|
|
|
|
|
|
|
int main() |
|
|
|
{ |
|
|
|
std::string const str("42+2*(1-1+2+3-4*5)"); |
|
|
|
|
|
|
|
parse_axe(str); |
|
|
|
parse_pegtl(str); |
|
|
|
|
|
|
|
return EXIT_SUCCESS; |
|
|
|
} |
|
|
|
|
|
|
|
// |
|
|
|
// PegTL -- a PEG parser |
|
|
|
// |
|
|
|
|
|
|
|
namespace pegtl_parser |
|
|
|
{ |
|
|
|
using namespace lol::parser; |
|
|
|
|
|
|
|
#define ACTION(name, code) \ |
|
|
|
struct name : action_base<name> { \ |
|
|
|
static void apply(std::string const &ctx, calculator &c) { \ |
|
|
|
code \ |
|
|
|
} \ |
|
|
|
}; |
|
|
|
|
|
|
|
ACTION( do_number, c.push(atof(ctx.c_str())); ) |
|
|
|
ACTION( do_op, |
|
|
|
switch (ctx[0]) |
|
|
|
{ |
|
|
|
case '*': c.mul(); break; |
|
|
|
case '/': c.div(); break; |
|
|
|
case '+': c.add(); break; |
|
|
|
case '-': c.sub(); break; |
|
|
|
} ) |
|
|
|
ACTION( do_success, c.pop(); ) |
|
|
|
|
|
|
|
#undef ACTION |
|
|
|
|
|
|
|
// number <- <digit> + |
|
|
|
struct number : ifapply<plus<digit>, do_number> {}; |
|
|
|
|
|
|
|
// term <- number | "(" expr ")" |
|
|
|
struct term : sor<number, |
|
|
|
seq<one<'('>, struct expr, one<')'>>> {}; |
|
|
|
|
|
|
|
// factor <- term ( "*" term | "/" term ) * |
|
|
|
struct factor : seq<term, |
|
|
|
star<ifapply<sor<seq<one<'*'>, term>, |
|
|
|
seq<one<'/'>, term>>, do_op>>> {}; |
|
|
|
|
|
|
|
// expr <- factor ( "+" factor | "-" factor ) * |
|
|
|
struct expr : seq<factor, |
|
|
|
star<ifapply<sor<seq<one<'+'>, factor>, |
|
|
|
seq<one<'-'>, factor>>, do_op>>> {}; |
|
|
|
|
|
|
|
// stmt <- expr <end> |
|
|
|
struct stmt : ifapply<seq<expr, eof>, do_success> {}; |
|
|
|
}; |
|
|
|
|
|
|
|
static void parse_pegtl(std::string const & str) |
|
|
|
{ |
|
|
|
calculator c; |
|
|
|
pegtl::basic_parse_string<pegtl_parser::stmt>(str, c); |
|
|
|
} |
|
|
|
|
|
|
|
// |
|
|
|
// AXE -- a recursive descent parser (needs right-recursion) |
|
|
|
// |
|
|
|
|
|
|
|
template<typename IT> |
|
|
|
static void parse_axe_helper(IT i1, IT i2) |
|
|
|
{ |
|
|
|
calculator c; |
|
|
|
double d; |
|
|
|
|
|
|
|
#define ACTION(code) e_ref([&](...) { code }) |
|
|
|
|
|
|
|
r_rule<IT> number, term, factor, factor_tail, expr, expr_tail, stmt; |
|
|
|
|
|
|
|
// number ::= <double> |
|
|
|
number = r_double(d) >> ACTION( c.push(d); ); |
|
|
|
|
|
|
|
// term ::= number | ( expr ) |
|
|
|
term = number |
|
|
|
| '(' & expr & ')'; |
|
|
|
|
|
|
|
// factor ::= term factor_tail |
|
|
|
// factor_tail ::= * term factor_tail |
|
|
|
// | / term factor_tail |
|
|
|
// | ɛ |
|
|
|
factor_tail = '*' & term >> ACTION( c.mul(); ) & factor_tail |
|
|
|
| '/' & term >> ACTION( c.div(); ) & factor_tail |
|
|
|
| r_empty(); |
|
|
|
factor = term & factor_tail; |
|
|
|
|
|
|
|
// expr ::= factor expr_tail |
|
|
|
// expr_tail ::= + factor expr_tail |
|
|
|
// | - factor expr_tail |
|
|
|
// | ɛ |
|
|
|
expr_tail = '+' & factor >> ACTION( c.add(); ) & expr_tail |
|
|
|
| '-' & factor >> ACTION( c.sub(); ) & expr_tail |
|
|
|
| r_empty(); |
|
|
|
expr = factor & expr_tail; |
|
|
|
|
|
|
|
// stmt ::= expr <end> |
|
|
|
// | <fail> |
|
|
|
stmt = expr & r_end() >> ACTION( c.pop(); ) |
|
|
|
| r_fail([](...) { printf("malformed expression\n"); }); |
|
|
|
|
|
|
|
#undef ACTION |
|
|
|
|
|
|
|
// Evaluate expression |
|
|
|
stmt(i1, i2); |
|
|
|
} |
|
|
|
|
|
|
|
static void parse_axe(std::string const &str) |
|
|
|
{ |
|
|
|
return parse_axe_helper(str.begin(), str.end()); |
|
|
|
} |
|
|
|
|