From 62f2259fb9a5531bf425efc2f19a82b108ec5901 Mon Sep 17 00:00:00 2001 From: Celtic Minstrel Date: Wed, 3 Dec 2014 02:53:34 -0500 Subject: [PATCH] Hacked at it until the parser stopped crashing. It now seems even uglier than before. And it still doesn't actually work. --- osx/BoE.xcodeproj/project.pbxproj | 2 + osx/tools/special_parse.hpp | 51 ++++++++++++ osx/tools/specials_parse.cpp | 126 ++++++++++++++++-------------- 3 files changed, 120 insertions(+), 59 deletions(-) create mode 100644 osx/tools/special_parse.hpp diff --git a/osx/BoE.xcodeproj/project.pbxproj b/osx/BoE.xcodeproj/project.pbxproj index a2bfb57b..fac99f08 100644 --- a/osx/BoE.xcodeproj/project.pbxproj +++ b/osx/BoE.xcodeproj/project.pbxproj @@ -1347,6 +1347,7 @@ 91EC481018FBABB100BB1E86 /* prefs.mac.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = prefs.mac.mm; sourceTree = ""; }; 91EF05291904D082001BEF85 /* bold.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = bold.ttf; sourceTree = ""; }; 91EF052A1904D082001BEF85 /* plain.ttf */ = {isa = PBXFileReference; lastKnownFileType = file; path = plain.ttf; sourceTree = ""; }; + 91F06E8F1A2EBEE70038E902 /* special_parse.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = special_parse.hpp; sourceTree = ""; }; 91F6F8DD18F87F3700E3EA15 /* sfml-audio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "sfml-audio.framework"; path = "/Library/Frameworks/sfml-audio.framework"; sourceTree = ""; }; 91F6F8DE18F87F3700E3EA15 /* sfml-graphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "sfml-graphics.framework"; path = "/Library/Frameworks/sfml-graphics.framework"; sourceTree = ""; }; 91F6F8E018F87F3700E3EA15 /* sfml-system.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = "sfml-system.framework"; path = "/Library/Frameworks/sfml-system.framework"; sourceTree = ""; }; @@ -1714,6 +1715,7 @@ 91EC480E18FBAA8700BB1E86 /* prefs.hpp */, 91B3F10E0F9779D000BF5B67 /* soundtool.h */, 91BFA3D91902ADD5001686E4 /* tarball.hpp */, + 91F06E8F1A2EBEE70038E902 /* special_parse.hpp */, 917B573F100B956C0096C978 /* undo.h */, 919145FE18E63B41005CF3A4 /* winutil.h */, ); diff --git a/osx/tools/special_parse.hpp b/osx/tools/special_parse.hpp new file mode 100644 index 00000000..088ee34c --- /dev/null +++ b/osx/tools/special_parse.hpp @@ -0,0 +1,51 @@ +// +// special_parse.hpp +// BoE +// +// Created by Celtic Minstrel on 14-12-02. +// +// + +#ifndef BoE_special_parse_hpp +#define BoE_special_parse_hpp + +#include + +#include "special.h" + +namespace qi = boost::spirit::qi; +typedef boost::spirit::context, boost::fusion::vector0>& ph_t; +typedef qi::rule Rule; + +class SpecialParser { + static void init_file(); + static void init_block(); + static void prep_add_symbol(char c); + static void add_symbol(int i); + static void add_command(); + static void set_type(eSpecNodeType type); + static void skip_to(int i); + static void for_sdf(); + static void for_pic(); + static void for_msg(); + static void for_ex1(); + static void for_ex2(); + static void for_goto(); + static void set_first(int i, ph_t, bool& pass); + static void set_second(int i, ph_t, bool& pass); + static void set_third(int i, ph_t, bool& pass); + static std::string temp_symbol; + static int cur_node, cur_fld; + static cSpecial curSpec; + static std::map specials; + static qi::symbols defn; + static Rule ws, comment, symbol, val; + static Rule datcode, command, def_line, cmd_line, op_line, cmd_block, nodes_file; + static bool grammar_built; +public: + SpecialParser(); + std::map parse(std::string code); + void debug(); +}; + +#endif diff --git a/osx/tools/specials_parse.cpp b/osx/tools/specials_parse.cpp index f614c726..3063b00b 100644 --- a/osx/tools/specials_parse.cpp +++ b/osx/tools/specials_parse.cpp @@ -6,52 +6,55 @@ // // +#include "special_parse.hpp" + #include #include #include -#include +#include #include "special.h" -using namespace boost::spirit::qi; -typedef boost::spirit::context, boost::fusion::vector0>& ph_t; +namespace ph = boost::phoenix; +qi::symbols opcode; -std::string temp_symbol; -int cur_node, cur_fld; -cSpecial curSpec; -std::map specials; +#define _(fcn) SpecialParser::fcn -symbols opcode; -symbols defn; +bool SpecialParser::grammar_built = false; +std::string SpecialParser::temp_symbol; +int SpecialParser::cur_node, SpecialParser::cur_fld; +cSpecial SpecialParser::curSpec; +std::map SpecialParser::specials; +qi::symbols SpecialParser::defn; +Rule SpecialParser::ws, SpecialParser::comment, SpecialParser::symbol, SpecialParser::val; +Rule SpecialParser::datcode, SpecialParser::command, SpecialParser::def_line, SpecialParser::cmd_line; +Rule SpecialParser::op_line, SpecialParser::cmd_block, SpecialParser::nodes_file; -void init_file(), init_block(); -void prep_add_symbol(char c); -void add_symbol(int i); -void add_command(); -void set_type(eSpecNodeType type); -void skip_to(int i); -void for_sdf(), for_pic(), for_msg(), for_ex1(), for_ex2(), for_goto(); -void set_first(int i, ph_t, bool& pass), set_second(int i, ph_t, bool& pass), set_third(int i, ph_t, bool& pass); +SpecialParser::SpecialParser() { + if(grammar_built) return; + using namespace qi; + ws = char_(" \t"); + comment = char_('#') >> *(print | ws); + symbol = lexeme[char_("A-Za-z$_-")[_(prep_add_symbol)] >> *char_("A-Za-z0-9$_-")[_(prep_add_symbol)]]; + val = int_ | defn; -typedef rule Rule; + datcode = lit("sdf")[_(for_sdf)] | lit("pic")[_(for_pic)] | lit("msg")[_(for_msg)] | + lit("ex1")[_(for_ex1)] | lit("ex2")[_(for_ex2)] | lit("goto")[_(for_goto)]; -auto ws = char_(" \t"); -auto comment = char_('#') >> *(print | ws); -auto symbol = lexeme[char_("A-Za-z$_-")[prep_add_symbol] >> *char_("A-Za-z0-9$_-")[prep_add_symbol]]; -auto val = int_ | defn; + command = datcode >> ws >> val[_(set_first)] >> -(char_(',') >> val[_(set_second)] >> -(char_(',') >> val[_(set_third)])); -Rule datcode = lit("sdf")[for_sdf] | lit("pic")[for_pic] | lit("msg")[for_msg] | - lit("ex1")[for_ex1] | lit("ex2")[for_ex2] | lit("goto")[for_goto]; + def_line = lit("def") >> ws >> symbol >> char_('=') >> uint_[_(add_symbol)] >> -comment >> eol; + cmd_line = (command | eps) >> (comment | eps) >> eol; + op_line = lexeme[char_('@') >> opcode[_(set_type)]] >> -(char_('=') >> int_[_(skip_to)]) >> -comment >> eol; -Rule command = datcode >> ws >> val[set_first] >> -(char_(',') >> val[set_second] >> -(char_(',') >> val[set_third])); + cmd_block = eps[_(init_block)] >> op_line >> *(cmd_line | def_line); -Rule def_line = lit("def") >> ws >> symbol >> char_('=') >> uint_[add_symbol] >> -comment >> eol; -Rule cmd_line = (command | eps) >> (comment | eps) >> eol; -Rule op_line = lexeme[char_('@') >> opcode[set_type]] >> -(char_('=') >> int_[skip_to]) >> -comment >> eol; - -Rule command_block = eps[init_block] >> op_line >> *(cmd_line | def_line); - -Rule nodes_file = eps[init_file] >> *def_line >> *command_block[add_command]; + nodes_file = eps[_(init_file)] >> *(-comment >> eol | def_line) >> *cmd_block[_(add_command)]; + + grammar_built = true; +} + +#undef A struct initer { initer() { @@ -169,12 +172,12 @@ struct initer { static struct initer initer; -void init_file() { +void SpecialParser::init_file() { specials.clear(); init_block(); } -void init_block() { +void SpecialParser::init_block() { cur_node = 0; temp_symbol.clear(); curSpec.type = SPEC_NULL; @@ -194,52 +197,52 @@ void init_block() { curSpec.jumpto = -1; } -void prep_add_symbol(char c) { +void SpecialParser::prep_add_symbol(char c) { temp_symbol += c; } -void add_symbol(int i) { +void SpecialParser::add_symbol(int i) { defn.add(temp_symbol, i); temp_symbol.clear(); } -void add_command() { +void SpecialParser::add_command() { specials[cur_node] = curSpec; } -void set_type(eSpecNodeType type) { +void SpecialParser::set_type(eSpecNodeType type) { curSpec.type = type; } -void skip_to(int i) { +void SpecialParser::skip_to(int i) { cur_node = i; } -void for_sdf() { +void SpecialParser::for_sdf() { cur_fld = 0; } -void for_pic() { +void SpecialParser::for_pic() { cur_fld = 1; } -void for_msg() { +void SpecialParser::for_msg() { cur_fld = 2; } -void for_ex1() { +void SpecialParser::for_ex1() { cur_fld = 3; } -void for_ex2() { +void SpecialParser::for_ex2() { cur_fld = 4; } -void for_goto() { +void SpecialParser::for_goto() { cur_fld = 5; } -void set_first(int i, ph_t, bool& pass) { +void SpecialParser::set_first(int i, ph_t, bool& pass) { switch(cur_fld) { case 0: curSpec.sd1 = i; break; case 1: curSpec.pic = i; break; @@ -251,7 +254,7 @@ void set_first(int i, ph_t, bool& pass) { } } -void set_second(int i, ph_t, bool& pass) { +void SpecialParser::set_second(int i, ph_t, bool& pass) { switch(cur_fld) { case 0: curSpec.sd2 = i; break; case 1: curSpec.pictype = i; break; @@ -262,7 +265,7 @@ void set_second(int i, ph_t, bool& pass) { } } -void set_third(int i, ph_t, bool& pass) { +void SpecialParser::set_third(int i, ph_t, bool& pass) { switch(cur_fld) { case 2: curSpec.m3 = i; break; case 3: curSpec.ex1c = i; break; @@ -271,25 +274,30 @@ void set_third(int i, ph_t, bool& pass) { } } -std::map parse(std::string code) { - parse(code.begin(), code.end(), nodes_file, ws); +std::map SpecialParser::parse(std::string code) { + bool success = qi::phrase_parse(code.begin(), code.end(), nodes_file, ws); return specials; } +void SpecialParser::debug() { +// BOOST_SPIRIT_DEBUG_NODE(defn); +// BOOST_SPIRIT_DEBUG_NODE(datcode); +// BOOST_SPIRIT_DEBUG_NODE(command); +// BOOST_SPIRIT_DEBUG_NODE(def_line); +// BOOST_SPIRIT_DEBUG_NODE(cmd_line); +// BOOST_SPIRIT_DEBUG_NODE(op_line); +// BOOST_SPIRIT_DEBUG_NODE(cmd_block); +// BOOST_SPIRIT_DEBUG_NODE(nodes_file); +} + void test_special_parse(std::string file) { std::ostringstream code; std::ifstream fin(file); code << fin.rdbuf(); fin.close(); -// BOOST_SPIRIT_DEBUG_NODE(defn); -// BOOST_SPIRIT_DEBUG_NODE(datcode); -// BOOST_SPIRIT_DEBUG_NODE(command); -// BOOST_SPIRIT_DEBUG_NODE(def_line); -// BOOST_SPIRIT_DEBUG_NODE(cmd_line); -// BOOST_SPIRIT_DEBUG_NODE(op_line); -// BOOST_SPIRIT_DEBUG_NODE(command_block); -// BOOST_SPIRIT_DEBUG_NODE(nodes_file); - parse(code.str()); + SpecialParser parser; + parser.debug(); + auto specials = parser.parse(code.str()); std::ofstream fout(file + ".out"); for(auto p : specials) { fout << "Special node ID " << p.first << ":\b";