Skip to content
Snippets Groups Projects
config-parser.h 6.79 KiB
Newer Older
  • Learn to ignore specific revisions
  • 数学の武士's avatar
    数学の武士 committed
    #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;
    	};
    	// -------------------------------------------------------------------------------------------- //
    }