ソースを参照

misc: experiment with two parser libraries (AXE and PEGTL).

undefined
Sam Hocevar 10年前
コミット
55897d7cae
4個のファイルの変更163行の追加24行の削除
  1. +1
    -1
      build/msbuild/lol.rules.props
  2. +6
    -0
      build/msbuild/lol.vars.props
  3. +9
    -7
      configure.ac
  4. +147
    -16
      demos/test/sandbox/sample.cpp

+ 1
- 1
build/msbuild/lol.rules.props ファイルの表示

@@ -15,7 +15,7 @@
<!-- We should use %(RelativeDir) here but for some reason it's an _absolute_ dir. WTF. -->
<ObjectFileName>$(IntDir)/%(Directory)/</ObjectFileName>

<AdditionalIncludeDirectories>$(SolutionDir)\..\src;$(SolutionDir)\..\src\bullet;$(SolutionDir)\..\tools\lolunit;$(FlexIncludes);$(BtPhysIncludes);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(SolutionDir)\..\src;$(SolutionDir)\..\src\bullet;$(SolutionDir)\..\tools\lolunit;$(PegtlIncludes);$(FlexIncludes);$(BtPhysIncludes);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Platform)'=='Win32'">$(GlIncludes);$(SdlIncludes);$(FfmpegIncludes);$(D3d9Includes);$(XinputIncludes);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories Condition="'$(Platform)'=='x64'">$(GlIncludes);$(SdlIncludes);$(FfmpegIncludes);$(D3d9Includes);$(XinputIncludes);%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions>NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>


+ 6
- 0
build/msbuild/lol.vars.props ファイルの表示

@@ -8,6 +8,10 @@
<FlexDir>$(ExternalDir)\flex-2.5.35</FlexDir>
<FlexIncludes>$(FlexDir)\include</FlexIncludes>

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

<!-- libgcc (from mingw-w64) -->
<LibGccDir>$(ExternalDir)\libgcc-4.9</LibGccDir>
<LibGccLibs Condition="'$(Platform)'=='Win32'">$(LibGccDir)\lib\i686-w64-mingw32</LibGccLibs>
@@ -109,6 +113,8 @@
<BuildMacro Include="ExternalDir"><Value>$(ExternalDir)</Value></BuildMacro>
<BuildMacro Include="FlexDir"><Value>$(FlexDir)</Value></BuildMacro>
<BuildMacro Include="FlexIncludes"><Value>$(FlexIncludes)</Value></BuildMacro>
<BuildMacro Include="PegtlDir"><Value>$(PegtlDir)</Value></BuildMacro>
<BuildMacro Include="PegtlIncludes"><Value>$(PegtlIncludes)</Value></BuildMacro>
<BuildMacro Include="LibGccDir"><Value>$(LibGccDir)</Value></BuildMacro>
<BuildMacro Include="LibGccLibs"><Value>$(LibGccLibs)</Value></BuildMacro>
<BuildMacro Include="LibGccDeps"><Value>$(LibGccDeps)</Value></BuildMacro>


+ 9
- 7
configure.ac ファイルの表示

@@ -143,9 +143,8 @@ else
AC_DEFINE(LOL_BUILD_RELEASE, 1, Define to 1 to activate final release)
LOL_TRY_CXXFLAGS(-Os, [AM_CXXFLAGS="${AM_CXXFLAGS} -Os"])
LOL_TRY_CXXFLAGS(-ffast-math, [AM_CXXFLAGS="${AM_CXXFLAGS} -ffast-math"])
dnl Removed this so .nexe build ok.
dnl LOL_TRY_CXXFLAGS(-fomit-frame-pointer, [AM_CXXFLAGS="${AM_CXXFLAGS} -fomit-frame-pointer"])
dnl LOL_TRY_CXXFLAGS(-fno-strength-reduce, [AM_CXXFLAGS="${AM_CXXFLAGS} -fno-strength-reduce"])
LOL_TRY_CXXFLAGS(-fomit-frame-pointer, [AM_CXXFLAGS="${AM_CXXFLAGS} -fomit-frame-pointer"])
LOL_TRY_CXXFLAGS(-fno-strength-reduce, [AM_CXXFLAGS="${AM_CXXFLAGS} -fno-strength-reduce"])
fi


@@ -191,10 +190,6 @@ AM_CONDITIONAL(USE_LATEX, test "${LATEX}" != "no")
AM_CONDITIONAL(USE_DOT, test "${DOT}" != "no")


dnl No exceptions…
LOL_TRY_CXXFLAGS(-fno-exceptions, [AM_CXXFLAGS="${AM_CXXFLAGS} -fno-exceptions"])
LOL_TRY_CXXFLAGS(-fno-rtti, [AM_CXXFLAGS="${AM_CXXFLAGS} -fno-rtti"])

dnl Debug symbols
LOL_TRY_LDFLAGS(-rdynamic, [AM_LDFLAGS="${AM_LDFLAGS} -rdynamic"])

@@ -353,6 +348,13 @@ if test "x${ac_cv_my_have_flexlexer_h}" = "xno"; then
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/axe-1.5.4.164/include"
fi


dnl Use NativeClient?
ac_cv_my_have_nacl="no"
AC_LANG_PUSH(C++)


+ 147
- 16
demos/test/sandbox/sample.cpp ファイルの表示

@@ -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());
}


読み込み中…
キャンセル
保存