Przeglądaj źródła

Port all parsers to PEGTL 1.3.1.

There might be issues with lolremez but at first sight it seems to work.
undefined
Sam Hocevar 10 lat temu
rodzic
commit
6a6ecc66e9
4 zmienionych plików z 251 dodań i 193 usunięć
  1. +1
    -1
      build/msbuild/lol.vars.props
  2. +1
    -1
      configure.ac
  3. +35
    -26
      src/gpu/shader.cpp
  4. +214
    -165
      tools/lolremez/expression.h

+ 1
- 1
build/msbuild/lol.vars.props Wyświetl plik

@@ -5,7 +5,7 @@
<ExternalDir>$(SolutionDir)\..\external</ExternalDir>

<!-- PEGTL -->
<PegtlDir>$(ExternalDir)\pegtl-0.32</PegtlDir>
<PegtlDir>$(ExternalDir)\pegtl-1.3.1</PegtlDir>
<PegtlIncludes>$(PegtlDir)\include</PegtlIncludes>

<!-- imgui -->


+ 1
- 1
configure.ac Wyświetl plik

@@ -296,7 +296,7 @@ fi

dnl Use pegtl? Yes, always
if true; then
LOL_CFLAGS="$LOL_CFLAGS -I\$(top_srcdir)/external/pegtl-0.32/include"
LOL_CFLAGS="$LOL_CFLAGS -I\$(top_srcdir)/external/pegtl-1.3.1/include"
fi




+ 35
- 26
src/gpu/shader.cpp Wyświetl plik

@@ -117,42 +117,22 @@ using namespace pegtl;

struct lolfx_parser
{
public:
lolfx_parser(String const &code)
: m_section("header")
{
basic_parse_string<struct lolfx>(std::string(code.C()), this);
}

public:
String m_section;
map<String, String> m_programs;

private:
struct do_title : action_base<do_title>
{
static void apply(std::string const &ctx, lolfx_parser *that)
{
that->m_section = ctx.c_str();
}
};

struct do_code : action_base<do_code>
{
static void apply(std::string const &ctx, lolfx_parser *that)
{
that->m_programs[that->m_section] = ctx.c_str();
}
};

// title <- '[' (!']')+ ']' .{eol}
struct do_title
: plus<not_one<']'>> {};

struct title
: seq<one<'['>,
ifapply<plus<not_one<']'>>, do_title>,
do_title,
one<']'>,
until<eol, any>> {};

// FIXME: I’m using this rule because the ifapply<> above also
// FIXME: I’m using this rule because the do_title above also
// gets triggered when using at<> which is non-consuming.
struct title_ignore
: seq<one<'['>,
@@ -166,7 +146,7 @@ private:

// code_section < code_line{&(title / eof)}
struct code_section
: ifapply<until<at<sor<title_ignore, pegtl::eof>>, code_line>, do_code> {};
: until<at<sor<title_ignore, pegtl::eof>>, code_line> {};

// shader < title code_section
struct shader
@@ -179,6 +159,35 @@ private:
// lolfx < header code_section*
struct lolfx
: seq<header, star<shader>> {};

// default action: nothing
template<typename RULE>
struct action : nothing<RULE> {};

public:
lolfx_parser(String const &code)
: m_section("header")
{
pegtl::parse<lolfx, action>(code.C(), "shader", this);
}
};

template<>
struct lolfx_parser::action<lolfx_parser::do_title>
{
static void apply(input const &in, lolfx_parser *that)
{
that->m_section = in.string().c_str();
}
};

template<>
struct lolfx_parser::action<lolfx_parser::code_section>
{
static void apply(input const &in, lolfx_parser *that)
{
that->m_programs[that->m_section] = in.string().c_str();
}
};

/*


+ 214
- 165
tools/lolremez/expression.h Wyświetl plik

@@ -28,7 +28,7 @@ namespace grammar

using namespace pegtl;

enum class op : uint8_t
enum class id : uint8_t
{
/* Variables and constants */
x,
@@ -46,45 +46,8 @@ enum class op : uint8_t
min, max,
};

// Map operation enums to pegl::string<> rules
template<op OP> struct r_call_string {};

template<> struct r_call_string<op::abs> : string<'a','b','s'> {};
template<> struct r_call_string<op::sqrt> : string<'s','q','r','t'> {};
template<> struct r_call_string<op::cbrt> : string<'c','b','r','t'> {};
template<> struct r_call_string<op::exp> : string<'e','x','p'> {};
template<> struct r_call_string<op::exp2> : string<'e','x','p','2'> {};
template<> struct r_call_string<op::log> : string<'l','o','g'> {};
template<> struct r_call_string<op::log2> : string<'l','o','g','2'> {};
template<> struct r_call_string<op::log10> : string<'l','o','g','1','0'> {};
template<> struct r_call_string<op::sin> : string<'s','i','n'> {};
template<> struct r_call_string<op::cos> : string<'c','o','s'> {};
template<> struct r_call_string<op::tan> : string<'t','a','n'> {};
template<> struct r_call_string<op::asin> : string<'a','s','i','n'> {};
template<> struct r_call_string<op::acos> : string<'a','c','o','s'> {};
template<> struct r_call_string<op::atan> : string<'a','t','a','n'> {};
template<> struct r_call_string<op::sinh> : string<'s','i','n','h'> {};
template<> struct r_call_string<op::cosh> : string<'c','o','s','h'> {};
template<> struct r_call_string<op::tanh> : string<'t','a','n','h'> {};

template<> struct r_call_string<op::atan2> : string<'a','t','a','n','2'> {};
template<> struct r_call_string<op::pow> : string<'p','o','w'> {};
template<> struct r_call_string<op::min> : string<'m','i','n'> {};
template<> struct r_call_string<op::max> : string<'m','a','x'> {};

struct expression
{
/*
* Parse arithmetic expression in x, e.g. 2*x+3
*/
void parse(std::string const &str)
{
m_ops.empty();
m_constants.empty();

basic_parse_string<r_stmt>(str, this);
}

/*
* Evaluate expression at x
*/
@@ -96,12 +59,12 @@ struct expression
for (int i = 0; i < m_ops.count(); ++i)
{
/* Rules that do not consume stack elements */
if (m_ops[i].m1 == op::x)
if (m_ops[i].m1 == id::x)
{
stack.push(x);
continue;
}
else if (m_ops[i].m1 == op::constant)
else if (m_ops[i].m1 == id::constant)
{
stack.push(m_constants[m_ops[i].m2]);
continue;
@@ -112,39 +75,39 @@ struct expression

switch (m_ops[i].m1)
{
case op::plus: stack.push(head); break;
case op::minus: stack.push(-head); break;
case op::abs: stack.push(fabs(head)); break;
case op::sqrt: stack.push(sqrt(head)); break;
case op::cbrt: stack.push(cbrt(head)); break;
case op::exp: stack.push(exp(head)); break;
case op::exp2: stack.push(exp2(head)); break;
case op::log: stack.push(log(head)); break;
case op::log2: stack.push(log2(head)); break;
case op::log10: stack.push(log10(head)); break;
case op::sin: stack.push(sin(head)); break;
case op::cos: stack.push(cos(head)); break;
case op::tan: stack.push(tan(head)); break;
case op::asin: stack.push(asin(head)); break;
case op::acos: stack.push(acos(head)); break;
case op::atan: stack.push(atan(head)); break;
case op::sinh: stack.push(sinh(head)); break;
case op::cosh: stack.push(cosh(head)); break;
case op::tanh: stack.push(tanh(head)); break;
case op::add: stack.push(stack.pop() + head); break;
case op::sub: stack.push(stack.pop() - head); break;
case op::mul: stack.push(stack.pop() * head); break;
case op::div: stack.push(stack.pop() / head); break;
case op::atan2: stack.push(atan2(stack.pop(), head)); break;
case op::pow: stack.push(pow(stack.pop(), head)); break;
case op::min: stack.push(min(stack.pop(), head)); break;
case op::max: stack.push(max(stack.pop(), head)); break;
case op::x:
case op::constant:
case id::plus: stack.push(head); break;
case id::minus: stack.push(-head); break;
case id::abs: stack.push(fabs(head)); break;
case id::sqrt: stack.push(sqrt(head)); break;
case id::cbrt: stack.push(cbrt(head)); break;
case id::exp: stack.push(exp(head)); break;
case id::exp2: stack.push(exp2(head)); break;
case id::log: stack.push(log(head)); break;
case id::log2: stack.push(log2(head)); break;
case id::log10: stack.push(log10(head)); break;
case id::sin: stack.push(sin(head)); break;
case id::cos: stack.push(cos(head)); break;
case id::tan: stack.push(tan(head)); break;
case id::asin: stack.push(asin(head)); break;
case id::acos: stack.push(acos(head)); break;
case id::atan: stack.push(atan(head)); break;
case id::sinh: stack.push(sinh(head)); break;
case id::cosh: stack.push(cosh(head)); break;
case id::tanh: stack.push(tanh(head)); break;
case id::add: stack.push(stack.pop() + head); break;
case id::sub: stack.push(stack.pop() - head); break;
case id::mul: stack.push(stack.pop() * head); break;
case id::div: stack.push(stack.pop() / head); break;
case id::atan2: stack.push(atan2(stack.pop(), head)); break;
case id::pow: stack.push(pow(stack.pop(), head)); break;
case id::min: stack.push(min(stack.pop(), head)); break;
case id::max: stack.push(max(stack.pop(), head)); break;
case id::x:
case id::constant:
/* Already handled above */
break;
}
@@ -155,101 +118,70 @@ struct expression
}

private:
lol::array<op, int> m_ops;
lol::array<id, int> m_ops;
lol::array<lol::real> m_constants;

private:
struct do_constant : action_base<do_constant>
{
static void apply(std::string const &ctx, expression *that)
{
/* FIXME: check if the constant is already in the list */
that->m_ops.push(op::constant, that->m_constants.count());
that->m_constants.push(lol::real(ctx.c_str()));
}
};

template<op OP>
struct do_op : action_base<do_op<OP>>
{
static void apply(std::string const &ctx, expression *that)
{
UNUSED(ctx);
that->m_ops.push(OP, -1);
}
};

struct r_expr;

// r_ <- <blank> *
struct _ : star<space> {};

// r_call_unary <- <unary_op> "(" r_expr ")"
template<op OP>
struct r_call_unary : ifapply<seq<r_call_string<OP>,
_,
one<'('>,
_,
r_expr,
_,
one<')'>>,
do_op<OP>> {};

// r_call_binary <- <binary_op> "(" r_expr "," r_expr ")"
template<op OP>
struct r_call_binary : ifapply<seq<r_call_string<OP>,
_,
one<'('>,
_,
r_expr,
_,
one<','>,
_,
r_expr,
_,
one<')'>>,
do_op<OP>> {};

// r_constant <- <digit> + ( "." <digit> * ) ? ( [eE] [+-] ? <digit> + ) ?
struct r_constant : ifapply<seq<plus<digit>,
opt<seq<one<'.'>,
star<digit>>>,
opt<seq<one<'e', 'E'>,
opt<one<'+', '-'>>,
plus<digit>>>>,
do_constant> {};
struct r_constant : seq<plus<digit>,
opt<seq<one<'.'>,
star<digit>>>,
opt<seq<one<'e', 'E'>,
opt<one<'+', '-'>>,
plus<digit>>>> {};

// r_var <- "x"
struct r_var : ifapply<one<'x'>, do_op<op::x>> {};

// r_call <- r_call_unary / r_call_binary
struct r_call : sor<r_call_unary<op::abs>,
r_call_unary<op::sqrt>,
r_call_unary<op::cbrt>,
r_call_unary<op::exp>,
r_call_unary<op::exp2>,
r_call_unary<op::log>,
r_call_unary<op::log2>,
r_call_unary<op::log10>,
r_call_unary<op::sin>,
r_call_unary<op::cos>,
r_call_unary<op::tan>,
r_call_unary<op::asin>,
r_call_unary<op::acos>,
r_call_unary<op::atan>,
r_call_unary<op::sinh>,
r_call_unary<op::cosh>,
r_call_unary<op::tanh>,
r_call_binary<op::atan2>,
r_call_binary<op::pow>,
r_call_binary<op::min>,
r_call_binary<op::max>> {};
struct r_var : pegtl_string_t("x") {};

// r_binary_call <- <r_binary_fun> "(" r_expr "," r_expr ")"
struct r_binary_fun : sor<pegtl_string_t("atan2"),
pegtl_string_t("pow"),
pegtl_string_t("min"),
pegtl_string_t("max")> {};

struct r_binary_call : seq<r_binary_fun,
_, one<'('>,
_, r_expr,
_, one<','>,
_, r_expr,
_, one<')'>> {};

// r_unary_call <- <r_unary_fun> "(" r_expr ")"
struct r_unary_fun : sor<pegtl_string_t("abs"),
pegtl_string_t("sqrt"),
pegtl_string_t("cbrt"),
pegtl_string_t("exp"),
pegtl_string_t("exp2"),
pegtl_string_t("log"),
pegtl_string_t("log2"),
pegtl_string_t("log10"),
pegtl_string_t("sin"),
pegtl_string_t("cos"),
pegtl_string_t("tan"),
pegtl_string_t("asin"),
pegtl_string_t("acos"),
pegtl_string_t("atan"),
pegtl_string_t("sinh"),
pegtl_string_t("cosh"),
pegtl_string_t("tanh")> {};

struct r_unary_call : seq<r_unary_fun,
_, one<'('>,
_, r_expr,
_, one<')'>> {};

// r_call <- r_binary_call / r_unary_call
struct r_call : sor<r_binary_call,
r_unary_call> {};

// r_parentheses <- "(" r_expr ")"
struct r_parentheses : seq<one<'('>,
_,
r_expr,
_,
pad<r_expr, space>,
one<')'>> {};

// r_terminal <- r_call / r_var / r_constant / r_parentheses
@@ -259,16 +191,16 @@ private:
r_parentheses> {};

// r_signed <- "-" r_signed / "+" r_signed / r_terminal
struct r_signed : sor<ifapply<seq<one<'-'>, _, r_signed>,
do_op<op::minus>>,
struct r_signed;
struct r_minus : seq<one<'-'>, _, r_signed> {};
struct r_signed : sor<r_minus,
seq<one<'+'>, _, r_signed>,
r_terminal> {};

// r_exponent <- ( "^" / "**" ) r_signed
struct r_exponent : ifapply<seq<_,
sor<one<'^'>, string<'*', '*'>>,
_,
r_signed>, do_op<op::pow>> {};
struct r_exponent : seq<pad<sor<one<'^'>,
string<'*', '*'>>, space>,
r_signed> {};

// r_factor <- r_signed ( r_exponent ) *
struct r_factor : seq<r_signed,
@@ -277,21 +209,138 @@ private:
// r_mul <- "*" r_factor
// r_div <- "/" r_factor
// r_term <- r_factor ( r_mul / r_div ) *
struct r_mul : ifapply<seq<_, one<'*'>, _, r_factor>, do_op<op::mul>> {};
struct r_div : ifapply<seq<_, one<'/'>, _, r_factor>, do_op<op::div>> {};
struct r_mul : seq<_, one<'*'>, _, r_factor> {};
struct r_div : seq<_, one<'/'>, _, r_factor> {};
struct r_term : seq<r_factor,
star<sor<r_mul, r_div>>> {};

// r_add <- "+" r_term
// r_sub <- "-" r_term
// r_expr <- r_term ( r_add / r_sub ) *
struct r_add : ifapply<seq<_, one<'+'>, _, r_term>, do_op<op::add>> {};
struct r_sub : ifapply<seq<_, one<'-'>, _, r_term>, do_op<op::sub>> {};
struct r_add : seq<_, one<'+'>, _, r_term> {};
struct r_sub : seq<_, one<'-'>, _, r_term> {};
struct r_expr : seq<r_term,
star<sor<r_add, r_sub>>> {};

// r_stmt <- r_expr <end>
struct r_stmt : seq<_, r_expr, _, pegtl::eof> {};
struct r_stmt : must<pad<r_expr, space>, pegtl::eof> {};

//
// Default actions
//

template<typename R>
struct action : nothing<R> {};

template<id OP>
struct generic_action
{
static void apply(input const &in, expression *that)
{
UNUSED(in);
that->m_ops.push(OP, -1);
}
};

public:
/*
* Parse arithmetic expression in x, e.g. 2*x+3
*/
void parse(std::string const &str)
{
m_ops.empty();
m_constants.empty();

pegtl::parse<r_stmt, action>(str, "expression", this);
}
};

//
// Rule specialisations for simple operators
//

template<> struct expression::action<expression::r_var> : generic_action<id::x> {};
template<> struct expression::action<expression::r_exponent> : generic_action<id::pow> {};
template<> struct expression::action<expression::r_mul> : generic_action<id::mul> {};
template<> struct expression::action<expression::r_div> : generic_action<id::div> {};
template<> struct expression::action<expression::r_add> : generic_action<id::add> {};
template<> struct expression::action<expression::r_sub> : generic_action<id::sub> {};
template<> struct expression::action<expression::r_minus> : generic_action<id::minus> {};

//
// Rule specialisations for unary and binary function calls
//

template<>
struct expression::action<expression::r_binary_call>
{
static void apply(input const &in, expression *that)
{
struct { id id; char const *name; } lut[] =
{
{ id::atan2, "atan2" },
{ id::pow, "pow" },
{ id::min, "min" },
{ id::max, "max" },
};

for (auto pair : lut)
{
if (strncmp(in.string().c_str(), pair.name, strlen(pair.name)) != 0)
continue;

that->m_ops.push(pair.id, -1);
return;
}
}
};

template<>
struct expression::action<expression::r_unary_call>
{
static void apply(input const &in, expression *that)
{
struct { id id; char const *name; } lut[] =
{
{ id::abs, "abs" },
{ id::sqrt, "sqrt" },
{ id::cbrt, "cbrt" },
{ id::exp2, "exp2" },
{ id::exp, "exp" },
{ id::log10, "log10" },
{ id::log2, "log2" },
{ id::log, "log" },
{ id::sinh, "sinh" },
{ id::cosh, "cosh" },
{ id::tanh, "tanh" },
{ id::sin, "sin" },
{ id::cos, "cos" },
{ id::tan, "tan" },
{ id::asin, "asin" },
{ id::acos, "acos" },
{ id::atan, "atan" },
};

for (auto pair : lut)
{
if (strncmp(in.string().c_str(), pair.name, strlen(pair.name)) != 0)
continue;

that->m_ops.push(pair.id, -1);
return;
}
}
};

template<>
struct expression::action<expression::r_constant>
{
static void apply(input const &in, expression *that)
{
/* FIXME: check if the constant is already in the list */
that->m_ops.push(id::constant, that->m_constants.count());
that->m_constants.push(lol::real(in.string().c_str()));
}
};

} /* namespace grammar */


Ładowanie…
Anuluj
Zapisz