1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-20 20:23:03 +02:00
vcmi/scripting/erm/ERMParser.h

283 lines
5.6 KiB
C
Raw Normal View History

/*
* ERMParser.h, part of VCMI engine
*
* Authors: listed in file AUTHORS in main folder
*
* License: GNU General Public License v2.0 or later
* Full text of license available in license.txt file, in main folder
*
*/
#pragma once
2014-11-15 13:10:51 +02:00
#include <boost/spirit/home/support/unused.hpp>
2014-11-15 13:10:51 +02:00
namespace spirit = boost::spirit;
class CERMPreprocessor
{
std::string fname;
std::stringstream sourceStream;
int lineNo;
void getline(std::string &ret);
public:
enum class Version : ui8
{
INVALID,
ERM,
VERM
};
Version version;
CERMPreprocessor(const std::string & source);
std::string retrieveCommandLine();
2011-05-11 22:53:55 +03:00
int getCurLineNo() const
{
return lineNo;
}
const std::string& getCurFileName() const
{
return fname;
}
};
2011-03-19 19:06:46 +02:00
//various classes that represent ERM/VERM AST
namespace ERM
{
using ValType = int; //todo: set to int64_t
using IType = int; //todo: set to int32_t
struct TStringConstant
{
std::string str;
};
struct TMacroUsage
{
std::string macro;
};
// //macro with '?', for write only
// struct TQMacroUsage
// {
// std::string qmacro;
// };
//definition of a macro
struct TMacroDef
{
std::string macro;
};
typedef std::string TCmdName;
struct TVarExpNotMacro
{
typedef boost::optional<int> Tval;
boost::optional<char> questionMark;
std::string varsym;
Tval val;
};
typedef boost::variant<TVarExpNotMacro, TMacroUsage> TVarExp;
//write-only variable expression
struct TVarpExp
{
TVarExp var;
};
//i-expression (identifier expression) - an integral constant, variable symbol or array symbol
typedef boost::variant<TVarExp, int> TIexp;
struct TArithmeticOp
{
TIexp lhs, rhs;
char opcode;
};
struct TVRLogic
{
char opcode;
TIexp var;
};
struct TVRArithmetic
{
char opcode;
TIexp rhs;
};
struct TSemiCompare
{
std::string compSign;
TIexp rhs;
};
struct TCurriedString
{
TIexp iexp;
TStringConstant string;
};
struct TVarConcatString
{
TVarExp var;
TStringConstant string;
};
typedef boost::variant<TVarConcatString, TStringConstant, TCurriedString, TSemiCompare, TMacroDef, TIexp, TVarpExp> TBodyOptionItem;
typedef std::vector<TBodyOptionItem> TNormalBodyOptionList;
struct TNormalBodyOption
{
char optionCode;
boost::optional<TNormalBodyOptionList> params;
};
typedef boost::variant<TVRLogic, TVRArithmetic, TNormalBodyOption> TBodyOption;
// typedef boost::variant<TIexp, TArithmeticOp > TIdentifierInternal;
typedef std::vector< TIexp > Tidentifier;
struct TComparison
{
std::string compSign;
TIexp lhs, rhs;
};
struct Tcondition;
typedef
boost::optional<
boost::recursive_wrapper<Tcondition>
>
TconditionNode;
struct Tcondition
{
typedef boost::variant<
TComparison,
int>
Tcond; //comparison or condition flag
char ctype;
Tcond cond;
TconditionNode rhs;
};
struct TTriggerBase
{
bool pre; //if false it's !$ post-trigger, elsewise it's !# (pre)trigger
TCmdName name;
boost::optional<Tidentifier> identifier;
boost::optional<Tcondition> condition;
};
struct Ttrigger : TTriggerBase
{
Ttrigger()
{
2011-05-22 21:46:52 +03:00
pre = true;
}
};
struct TPostTrigger : TTriggerBase
{
TPostTrigger()
{
2011-05-22 21:46:52 +03:00
pre = false;
}
};
//a dirty workaround for preprocessor magic that prevents the use types with comma in it in BOOST_FUSION_ADAPT_STRUCT
//see http://comments.gmane.org/gmane.comp.lib.boost.user/62501 for some info
//
//moreover, I encountered a quite serious bug in boost: http://boost.2283326.n4.nabble.com/container-hpp-111-error-C2039-value-type-is-not-a-member-of-td3352328.html
//not sure how serious it is...
//typedef boost::variant<char, TStringConstant, TMacroUsage, TMacroDef> bodyItem;
typedef std::vector<TBodyOption> Tbody;
struct Tinstruction
{
TCmdName name;
boost::optional<Tidentifier> identifier;
boost::optional<Tcondition> condition;
Tbody body;
};
struct Treceiver
{
TCmdName name;
boost::optional<Tidentifier> identifier;
boost::optional<Tcondition> condition;
boost::optional<Tbody> body;
};
struct Tcommand
{
typedef boost::variant<
Ttrigger,
Tinstruction,
Treceiver,
TPostTrigger
>
Tcmd;
Tcmd cmd;
//std::string comment;
};
//vector expression
typedef boost::variant<Tcommand, std::string, boost::spirit::unused_type> TERMline;
typedef std::string TVModifier; //'`', ',', ',@', '#''
struct TSymbol
{
std::vector<TVModifier> symModifier;
std::string sym;
};
//for #'symbol expression
2011-04-10 19:39:34 +03:00
enum EVOtions{VEXP, SYMBOL, CHAR, DOUBLE, INT, TCMD, STRINGC};
struct TVExp;
typedef boost::variant<boost::recursive_wrapper<TVExp>, TSymbol, char, double, int, Tcommand, TStringConstant > TVOption; //options in v-expression
//v-expression
struct TVExp
{
std::vector<TVModifier> modifier;
std::vector<TVOption> children;
};
//script line
typedef boost::variant<TVExp, TERMline> TLine;
template <typename T> struct ERM_grammar;
}
2011-05-11 22:53:55 +03:00
struct LineInfo
{
ERM::TLine tl;
int realLineNum;
};
2011-03-19 19:06:46 +02:00
class ERMParser
{
public:
std::shared_ptr<ERM::ERM_grammar<std::string::const_iterator>> ERMgrammar;
ERMParser();
virtual ~ERMParser();
std::vector<LineInfo> parseFile(CERMPreprocessor & preproc);
2011-03-19 19:06:46 +02:00
private:
void repairEncoding(char * str, int len) const; //removes nonstandard ascii characters from string
void repairEncoding(std::string & str) const; //removes nonstandard ascii characters from string
2011-05-11 22:53:55 +03:00
ERM::TLine parseLine(const std::string & line, int realLineNo);
ERM::TLine parseLine(const std::string & line);
2011-03-19 19:06:46 +02:00
};