#pragma once // [config-parser.h]: configuration file parser // // -------------------------------------------------------------------------------------------- // #include "mpi-com.h" #include "str-com.h" #include "cfg-var.h" namespace nse { class ConfigParser { public: ConfigParser(); ~ConfigParser(); bool run(const char* filename); bool mpi_run(const char* filename, const MPI_Comm comm); bool mpi_run(const char* filename); bool is_varname(const char* name) const; const cfgVariable get_variable(const int idx) const; const cfgVariable get_variable(const char* name) const; bool get_value(const char* name, int* value) const; bool get_value(const char* name, float* value) const; bool get_value(const char* name, double* value) const; bool get_value(const char* name, char** value) const; bool get_value(const char* name, std::string& value) const; bool get_value(const char* name, bool* value) const; bool mpi_is_varname(const char* name, const MPI_Comm comm) const; template< typename T > bool mpi_get_value(const char* name, T* value, const MPI_Comm comm) const; bool mpi_get_value(const char* name, char** value, const MPI_Comm comm) const; bool mpi_get_value(const char* name, std::string& value, const MPI_Comm comm) const; void print() const; private: // datatypes // enum LEXEME_TYPE { // lexeme types // IS_INVALID, IS_NAME, IS_ASSIGNMENT, IS_BRACE_OPEN, IS_BRACE_CLOSE, // {} IS_BRACKET_OPEN, IS_BRACKET_CLOSE, // () IS_SEMICOLON, IS_VALUE, IS_OP_ADD, IS_OP_SUB, // +,- [priority=1, assoc.=left] IS_OP_MUL, IS_OP_DIV, IS_OP_MOD, // *,/,% [priority=2, assoc.=left] IS_OP_PLUS, IS_OP_MINUS, // +,- [priority=3, assoc.=left] IS_OP_EXP // ^ [priority=4, assoc.=right] }; enum OP_ASSOCIATIVITY { IS_OP_LEFT, IS_OP_RIGHT }; // operation specifiers // struct parserState { // helper struct to control parsing state // parserState(); parserState(const parserState& state); ~parserState(); void truncate_name_space(); void append_name_space(const char* name); int idx, level; // lexeme index and namespace level char *name_space; // current namespace private: // allocation data int nalloc; static const int c_alloc_init = 64; }; struct rpnList { // helper struct for RPN expressions evaluation // rpnList(); ~rpnList(); bool convert( parserState& state, // advancing state after delimiter [';'] const LEXEME_TYPE *lexeme_type, const FileParser& parser); private: // interface // void init(); void add(const int idx); bool empty(); public: int *expr; // lexeme index corresponding to element int nexpr; // number of elements in expression private: // allocation data int nalloc; static const int c_alloc_init = 64; }; private: // static // static bool is_valid_name(const char* lexeme); // valid variable name check // // op - priority interface // static bool is_op(const LEXEME_TYPE op); static bool is_op_binary(const LEXEME_TYPE op); static bool is_op_unary(const LEXEME_TYPE op); static int op_priority(const LEXEME_TYPE op); static OP_ASSOCIATIVITY op_associativity(const LEXEME_TYPE op); static bool op_lt(const LEXEME_TYPE opA, const LEXEME_TYPE opB); private: // processing // bool add(const cfgVariable& rvalue); // adding variable to list // const cfgVariable evaluate_rpn( const rpnList& rpn, parserState state, // using copy due to namespace operations const LEXEME_TYPE *lexeme_type, const FileParser& parser) const; bool run_lexical_analysis(LEXEME_TYPE *lexeme_type, const FileParser& parser); bool run_syntax_analysis(const LEXEME_TYPE *lexeme_type, const FileParser& parser); private: // data // int nalloc_vars; static const int c_alloc_init = 64; int nvars; cfgVariable *var; }; }