/* Customizeable Text Parser by Gee Gee@pyro.nu --Overview-- CParserValue Data! (an int, real, string etc), basically an argument CParserTaskType Syntax description for a line (ex. "variable=value") CParserLine Parse _one_ line CParser Include all syntax (CParserTaskTypes) The whole CParser* class group is used to read in config files and give instruction on how that should be made. The CParserTaskType declares what in a line is arguments, of course different CParserTaskTypes will exist, and it's up to the system to figure out which one acquired. --More Info-- http://forums.wildfiregames.com/0ad/index.php?showtopic=134 */ #ifndef __PARSER_H #define __PARSER_H #include "Prometheus.h" #pragma warning(disable:4786) //-------------------------------------------------------- // Includes / Compiler directives //-------------------------------------------------------- #include #include #include #include #include //------------------------------------------------- // Types //------------------------------------------------- enum _ParserValueType { typeIdent, typeValue, typeRest, typeAddArg }; //------------------------------------------------- // Declarations //------------------------------------------------- class CParserValue; class CParserTaskType; class CParserLine; class CParser; // CParserValue // --------------------------------------------------------------------- // A parser value represents an argument // color=r, g, b // r, g and b will be CParserValues, or the arguments as they are called. // This class can store only a string, but can try parsing it to different // types class CParserValue { public: CParserValue(); ~CParserValue(); // return is error status bool GetString(std::string &ret); bool GetBool(bool &ret); bool GetChar(char &ret); // As number! otherwise use GetString make sure size=1 bool GetShort(short &ret); bool GetInt(int &ret); bool GetLong(long &ret); bool GetUnsignedShort(unsigned short &ret); bool GetUnsignedInt(unsigned int &ret); bool GetUnsignedLong(unsigned long &ret); bool GetFloat(float &ret); bool GetDouble(double &ret); // Memory regardless if it's an int, real, string or whatever std::string m_String; }; // CParserTaskTypeNode // ---------------------------------------------------------------------| Class // A task type is basically a tree, this is because dynamic arguments // requires alternative routes, so basically it's a binary tree with an // obligatory next node (if it's not the end of the tree) and an alternative // dynamic arguments node // // If we are at the beginning of this string, this will be the layout of the node // "<$value_>:_" // // m_Element ":" // m_AltNode => "$value" // m_NextNode => "_" // class CParserTaskTypeNode { public: CParserTaskTypeNode(); ~CParserTaskTypeNode(); // Free node pointers that are below this void DeleteChildren(); // Either the node is a letter or a type, if m_Leter is '\0' // then check m_Type what it is char m_Letter; _ParserValueType m_Type; std::string m_String; // Used for diverse storage // mainly for the typeAddArg // Parent node CParserTaskTypeNode *m_ParentNode; // Next node CParserTaskTypeNode *m_NextNode; // true means AltNode can be looped <...> // false means AltNode is just an optional part [...] bool m_AltNodeRepeatable; // Whenever a dynamic argument is used, it's first node is stored in this // as an alternative node. The parser first checks if there is an // alternative route, and if it applies to the next node. If not, proceed // as usual with m_String and the next node CParserTaskTypeNode *m_AltNode; // There are different kinds of alternative routes //int m_AltRouteType; }; // CParserTaskType // ---------------------------------------------------------------------| Class // A task type is basically different kinds of lines for the parser // variable=value is one type... class CParserTaskType { public: CParserTaskType(); ~CParserTaskType(); // Delete the whole tree void DeleteTree(); CParserTaskTypeNode *m_BaseNode; // Something to identify it with std::string m_Name; }; // CParserLine // ---------------------------------------------------------------------| Class // Representing one line, i.e. one task, in a config file class CParserLine { public: CParserLine(); ~CParserLine(); std::deque m_Arguments; bool m_ParseOK; // same as ParseString will return std::string m_TaskTypeName; // Name of the task type found protected: bool ClearArguments(); public: // Interface bool ParseString(const CParser& parser, std::string line); // Methods for getting arguments // it returns success bool GetArgString (const int& arg, std::string &ret); bool GetArgBool (const int& arg, bool &ret); bool GetArgChar (const int& arg, char &ret); bool GetArgShort (const int& arg, short &ret); bool GetArgInt (const int& arg, int &ret); bool GetArgLong (const int& arg, long &ret); bool GetArgUnsignedShort (const int& arg, unsigned short &ret); bool GetArgUnsignedInt (const int& arg, unsigned int &ret); bool GetArgUnsignedLong (const int& arg, unsigned long &ret); bool GetArgFloat (const int& arg, float &ret); bool GetArgDouble (const int& arg, double &ret); // Get Argument count size_t GetArgCount() const { return m_Arguments.size(); } }; // CParser // ---------------------------------------------------------------------| Class // Includes parsing instruction, i.e. task-types class CParser { public: CParser::CParser(); CParser::~CParser(); std::vector m_TaskTypes; // Interface bool InputTaskType(const std::string& strName, const std::string& strSyntax); }; #endif