| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265 | 
							- #pragma once
 
- /*
 
-  * 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
 
-  *
 
-  */
 
-  
 
- #include <boost/spirit/home/support/unused.hpp>
 
- namespace spirit = boost::spirit;
 
- class CERMPreprocessor
 
- {
 
- 	std::string fname;
 
- 	std::ifstream file;
 
- 	int lineNo;
 
- 	enum {INVALID, ERM, VERM} version;
 
- 	void getline(std::string &ret);
 
- public:
 
- 	CERMPreprocessor(const std::string &Fname);
 
- 	std::string retreiveCommandLine();
 
- 	int getCurLineNo() const
 
- 	{
 
- 		return lineNo;
 
- 	}
 
- };
 
- //various classes that represent ERM/VERM AST
 
- namespace ERM
 
- {
 
- 	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, boost::spirit::unused_type> TBodyOptionItem;
 
- 	typedef std::vector<TBodyOptionItem> TNormalBodyOptionList;
 
- 	struct TNormalBodyOption
 
- 	{
 
- 		char optionCode;
 
- 		TNormalBodyOptionList params;
 
- 	};
 
- 	typedef boost::variant<TVRLogic, TVRArithmetic, TNormalBodyOption> TBodyOption;
 
- 	typedef boost::variant<TIexp, TArithmeticOp > TIdentifierInternal;
 
- 	typedef std::vector< TIdentifierInternal > 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() 
 
- 		{
 
- 			pre = true;
 
- 		}
 
- 	};
 
- 	struct TPostTrigger : TTriggerBase
 
- 	{
 
- 		TPostTrigger()
 
- 		{
 
- 			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
 
- 	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;
 
- }
 
- struct LineInfo
 
- {
 
- 	ERM::TLine tl;
 
- 	int realLineNum;
 
- };
 
- class ERMParser
 
- {
 
- private:
 
- 	std::string srcFile;
 
- 	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
 
- 	enum ELineType{COMMAND_FULL, COMMENT, UNFINISHED, END_OF};
 
- 	int countHatsBeforeSemicolon(const std::string & line) const;
 
- 	ERM::TLine parseLine(const std::string & line, int realLineNo);
 
- public:
 
- 	ERMParser(std::string file);
 
- 	std::vector<LineInfo> parseFile();
 
- 	static ERM::TLine parseLine(const std::string & line);
 
- };
 
 
  |