#pragma once // [config-parser.h]: configuration file parser // // -------------------------------------------------------------------------------------------- // #include "cfg-value.h" #include "cfg-cmd.h" #include "cfg-vec.h" #include "lexeme-list.h" #include "mem-buffer.h" #include <stack> namespace scm { // call back default // -------------------------------------------------------------------------------------------- // class parserCallBack { public: virtual bool call_back(const cfgCommand& cmd) { return true; } parserCallBack() {} virtual ~parserCallBack() {} }; // -------------------------------------------------------------------------------------------- // class ConfigParser { public: // -------------------------------------------------------------------------------------------- // ConfigParser(); ~ConfigParser(); // -------------------------------------------------------------------------------------------- // // run // -------------------------------------------------------------------------------------------- // bool run(const char* filename); bool run(const char* filename, parserCallBack& pcb); // -------------------------------------------------------------------------------------------- // // get & check calls // -------------------------------------------------------------------------------------------- // bool is_varname(const char* name) const; const cfgVector get_variable(const int idx) const; const cfgVector 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, long 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; // -------------------------------------------------------------------------------------------- // // adding variable // -------------------------------------------------------------------------------------------- // bool add(const cfgVector& rvalue); bool is_valid_name(const char* name) const; // -------------------------------------------------------------------------------------------- // // print // -------------------------------------------------------------------------------------------- // void print() const; // -------------------------------------------------------------------------------------------- // private: // datatypes // -------------------------------------------------------------------------------------------- // // --- helper struct to control parsing state // -------------------------------------------------------------------------------------------- // struct parserState { parserState(); parserState(const parserState& state); ~parserState(); void truncate_name_space(); void append_name_space(const char* name); const char* get_global_name(const char* varname); int idx; // lexeme index char *name_space; // current namespace private: // allocation data int nalloc; static const int c_alloc_init = 64; char *name_buf; int name_buf_nalloc; }; // -------------------------------------------------------------------------------------------- // private: // processing (private) // -------------------------------------------------------------------------------------------- // // --- expression rpn evaluation bool get_rpn( mem_buffer<int>& rpn, mem_buffer<int>& rpn_key, const LexemeList& lexeme_list, const int lex_beg, const int lex_end) const; bool evaluate_rpn( std::stack<cfgVector>& dyn_expr, const mem_buffer< int >& rpn, const mem_buffer<int>& rpn_key, const int rpn_beg, const int rpn_end, const LexemeList& lexeme_list, const char* name_space, const bool exe_cntrl) const; bool evaluate_rpn( cfgVector& res, const mem_buffer< int >& rpn, const mem_buffer<int>& rpn_key, const LexemeList& lexeme_list, const char* name_space, const bool exe_cntrl) const; // -------------------------------------------------------------------------------------------- // // --- command setup bool set_command( cfgCommand& cmd, const mem_buffer< int >& rpn, const mem_buffer< int >& fun_narg, const LexemeList& lexeme_list, const bool exe_cntrl) const; // -------------------------------------------------------------------------------------------- // // --- syntax analysis bool parse_syntax(const LexemeList& lexeme_list, const bool exe_cntrl, parserCallBack& pcb); bool parse_block( parserState& state, const LexemeList& lexeme_list, const bool exe_cntrl, parserCallBack& pcb); bool parse_command( parserState& state, const LexemeList& lexeme_list, const bool exe_cntrl, parserCallBack& pcb); bool parse_if_statement( parserState& state, const LexemeList& lexeme_list, const bool exe_cntrl, parserCallBack& pcb); bool parse_while_statement( parserState& state, const LexemeList& lexeme_list, const bool exe_cntrl, parserCallBack& pcb); bool parse_name_space( parserState& state, const LexemeList& lexeme_list, const bool exe_cntrl, parserCallBack& pcb); bool parse_assignment( parserState& state, const LexemeList& lexeme_list, const bool exe_cntrl, parserCallBack& pcb); bool parse_address_assignment( parserState& state, const LexemeList& lexeme_list, const bool exe_cntrl, parserCallBack& pcb); // -------------------------------------------------------------------------------------------- // // --- add variable (no additional checks) bool add_unsafe(const cfgVector& rvalue); // -------------------------------------------------------------------------------------------- // private: // static (private) // -------------------------------------------------------------------------------------------- // // +,- [priority=1, assoc.=left] // *,/,% [priority=2, assoc.=left] // +,- [priority=3, assoc.=right] // ^ [priority=4, assoc.=right] static int operator_priority(const Lexeme::TYPE type); static bool operator_priority_lt( const Lexeme::TYPE typeA, const Lexeme::TYPE typeB); static int function_nargs(const Lexeme::TYPE type); static bool is_operator_binary(const Lexeme::TYPE type); static bool is_operator_unary(const Lexeme::TYPE type); static bool is_operator_assoc_left(const Lexeme::TYPE type); static bool is_operator_assoc_right(const Lexeme::TYPE type); private: // data (private) // -------------------------------------------------------------------------------------------- // int nvars; int nalloc_vars; static const int c_alloc_vars_init = 64; cfgVector *var; }; // -------------------------------------------------------------------------------------------- // }