diff --git a/lib/ERMParser.cpp b/lib/ERMParser.cpp new file mode 100644 index 000000000..96c1d1ba8 --- /dev/null +++ b/lib/ERMParser.cpp @@ -0,0 +1,109 @@ +#include "ERMParser.h" +#include +#include +#include +#include +#include +#include +#include +#include + +namespace spirit = boost::spirit; +namespace qi = boost::spirit::qi; + +ERMParser::ERMParser(std::string file) + :srcFile(file) +{} + +void ERMParser::parseFile() +{ + std::ifstream file(srcFile); + if(!file.is_open()) + { + tlog1 << "File " << srcFile << " not found or unable to open\n"; + return; + } + //check header + char header[5]; + file.getline(header, ARRAY_COUNT(header)); + if(std::string(header) != "ZVSE") + { + tlog1 << "File " << srcFile << " has wrong header\n"; + return; + } + //parse file + char lineBuf[1024]; + int lineNum = 1; + while(file.good()) + { + //reading line + file.getline(lineBuf, ARRAY_COUNT(lineBuf)); + if(file.gcount() == ARRAY_COUNT(lineBuf)) + { + tlog1 << "Encountered a problem during parsing " << srcFile << " too long line " << lineNum << "\n"; + } + //parsing + parseLine(lineBuf); + + + //loop end + ++lineNum; + } +} + +void callme(char const& i) +{ + std::cout << "fd"; +} + +void ERMParser::parseLine( std::string line ) +{ + namespace ascii = spirit::ascii; + namespace phoenix = boost::phoenix; + typedef std::string::iterator sit; + qi::rule comment = *(qi::char_); + qi::rule commentLine = ~qi::char_('!') >> comment; + qi::rule cmdName = qi::repeat(2)[ascii::alpha]; + qi::rule identifier = qi::int_ % '/'; + qi::rule condition = qi::char_('&') >> +(qi::int_ | qi::char_("a-zA-Z&/|")) >> qi::char_(":;"); + qi::rule trigger = cmdName >> -identifier >> -condition; + qi::rule string = qi::char_('^') >> ascii::print >> qi::char_('^'); + qi::rule body = *(qi::char_("a-zA-Z0-9/ ") | string); + qi::rule instruction = cmdName >> -identifier >> -condition >> body; + qi::rule receiver = cmdName >> -identifier >> -condition >> body; + qi::rule postOBtrigger = "$OB" >> -identifier >> -condition; + + qi::rule rline = + ( + (qi::char_('!') >> + ( + (qi::char_('?') >> trigger) | + (qi::char_('!') >> instruction) | + (qi::char_('#') >> receiver) | + postOBtrigger + ) >> comment + ) + | commentLine | spirit::eoi + ); + + qi::on_error + ( + rline + , std::cout //or phoenix::ref(std::count), is there any difference? + << phoenix::val("Error! Expecting ") + << qi::_4 // what failed? + << phoenix::val(" here: \"") + << phoenix::construct(qi::_3, qi::_2) // iterators to error-pos, end + << phoenix::val("\"") + << std::endl + ); + + sit beg = line.begin(), + end = line.end(); + bool r = qi::parse(beg, end, rline); + if(!r || beg != end) + { + tlog1 << "Parse error for line " << line << std::endl; + tlog1 << "\tCannot parse: " << std::string(beg, end) << std::endl; + } +} diff --git a/lib/ERMParser.h b/lib/ERMParser.h new file mode 100644 index 000000000..5b9cdd774 --- /dev/null +++ b/lib/ERMParser.h @@ -0,0 +1,15 @@ +#pragma once +#include "../global.h" + +class ERMParser +{ +private: + std::string srcFile; + + + void parseLine(std::string line); + +public: + ERMParser(std::string file); + void parseFile(); +}; diff --git a/lib/VCMI_Lib.cpp b/lib/VCMI_Lib.cpp index 28291bc9c..2b66ec2d1 100644 --- a/lib/VCMI_Lib.cpp +++ b/lib/VCMI_Lib.cpp @@ -11,6 +11,10 @@ #include "CBuildingHandler.h" #include "CSpellHandler.h" #include "CGeneralTextHandler.h" +#include "ERMParser.h" + +#include //for erm parser testing +#include //for erm parser testing /* * VCMI_Lib.cpp, part of VCMI engine @@ -48,7 +52,25 @@ DLL_EXPORT void initDLL(CConsoleHandler *Console, std::ostream *Logfile) try { VLC->init(); - } HANDLE_EXCEPTION + } HANDLE_EXCEPTION; + + + using namespace boost::filesystem; + //parser checking + directory_iterator enddir; + for (directory_iterator dir("Data/s"); dir!=enddir; dir++) + { + if(is_regular(dir->status())) + { + std::string name = dir->path().leaf(); + if( boost::algorithm::ends_with(name, ".erm")) + { + + ERMParser ep(dir->path().string()); + ep.parseFile(); + } + } + } } DLL_EXPORT void loadToIt(std::string &dest, const std::string &src, int &iter, int mode) diff --git a/server/CVCMIServer.cpp b/server/CVCMIServer.cpp index 617d6dadf..de601362b 100644 --- a/server/CVCMIServer.cpp +++ b/server/CVCMIServer.cpp @@ -18,7 +18,6 @@ #include "CVCMIServer.h" #include "../StartInfo.h" #include "../lib/map.h" -#include "../lib/CLodHandler.h" #include "../lib/Interprocess.h" #include "../lib/VCMI_Lib.h" #include "../lib/VCMIDirs.h"