#ifndef PARSE_HPP #define PARSE_HPP #include "struc.hpp" #include #include #include #include #define SPACES " \t" #define SEPARATORS " \t\n" #define ARG_END " \t\n;#()&|<>" #define VARNAME_END " \t\n;#()&|=\"'\\{}/-+" #define BLOCK_TOKEN_END " \t\n;#()&|=\"'\\" #define BASH_BLOCK_END " \t\n;#()&|=\"'\\{}" #define COMMAND_SEPARATOR "\n;" #define CONTROL_END "#)" #define PIPELINE_END "\n;#()&" #define ARGLIST_END "\n;#()&|" #define SPECIAL_TOKENS "\n;#()&|" #define ALL_TOKENS "\n;#()&|{}" #define SPECIAL_VARS "!#*@$?" // bash specific #define ARRAY_ARG_END " \t\n;#()&|<>]" // macros // #define PARSE_ERROR_I(str, ctx, i) format_error(str, ctx.filename, ctx.data, i) // #define PARSE_ERROR(str, ctx) format_error(str, ctx.filename, ctx.data, ctx.i) // #define PARSE_ERROR_I(str, ctx, i) { printFormatError(format_error(str, ctx.filename, ctx.data, i)); ctx.has_errored=true; } // #define PARSE_ERROR(str, ctx) { printFormatError(format_error(str, ctx.filename, ctx.data, ctx.i)); ctx.has_errored=true; } // structs struct list_parse_options { char end_char=0; bool word_mode=false; std::vector end_words={}; const char* expecting=NULL; }; // globals extern const std::vector posix_cmdvar; extern const std::vector bash_cmdvar; std::string import_file(std::string const& path); std::pair parse_text(parse_context context); std::pair parse_text(std::string const& in, std::string const& filename=""); inline std::pair parse(std::string const& file) { return parse_text(import_file(file), file); } // tools parse_context make_context(std::string const& in, std::string const& filename="", bool bash=false); parse_context make_context(parse_context ctx, std::string const& in="", std::string const& filename="", bool bash=false); parse_context make_context(parse_context ctx, uint64_t i); parse_context operator+(parse_context ctx, int64_t a); parse_context operator-(parse_context ctx, int64_t a); // error handlers void parse_error(std::string const& message, parse_context& ctx); void parse_error(std::string const& message, parse_context& ctx, uint64_t i); // ** unit parsers ** // /* util parsers */ uint32_t word_eq(const char* word, const char* in, uint32_t size, uint32_t start, const char* end_set=NULL); inline bool word_eq(const char* word, parse_context const& ct, const char* end_set=NULL) { return word_eq(word, ct.data, ct.size, ct.i, end_set); } std::pair get_word(parse_context ct, const char* end_set); uint32_t skip_chars(const char* in, uint32_t size, uint32_t start, const char* set); inline uint32_t skip_chars(parse_context const& ct, const char* set) { return skip_chars(ct.data, ct.size, ct.i, set); } uint32_t skip_until(const char* in, uint32_t size, uint32_t start, const char* set); inline uint32_t skip_until(parse_context const& ct, const char* set) { return skip_until(ct.data, ct.size, ct.i, set); } uint32_t skip_unread(const char* in, uint32_t size, uint32_t start); inline uint32_t skip_unread(parse_context const& ct) { return skip_unread(ct.data, ct.size, ct.i); } // list // std::pair parse_list_until(parse_context ct, char end_c, const char* expecting=NULL); // std::pair parse_list_until(parse_context ct, std::string const& end_word); // std::tuple parse_list_until(parse_context ct, std::vector const& end_words, const char* expecting=NULL); std::tuple parse_list_until(parse_context ct, list_parse_options opts={}); // name std::pair parse_var(parse_context ct, bool specialvars=true, bool array=false); // subarg parsers std::pair parse_arithmetic(parse_context ct); std::pair parse_manipulation(parse_context ct); // arg parser std::pair parse_arg(parse_context ct, const char* end=ARG_END, const char* unexpected=SPECIAL_TOKENS, bool doquote=true); // redirect parser std::pair parse_redirect(parse_context ct); // arglist parser std::pair parse_arglist(parse_context ct, bool hard_error=false, std::vector* redirs=nullptr); // block parsers std::pair parse_block(parse_context ct); std::pair parse_cmd(parse_context ct); std::pair parse_function(parse_context ct, const char* after="()"); std::pair parse_subshell(parse_context ct); std::pair parse_brace(parse_context ct); std::pair parse_case(parse_context ct); std::pair parse_if(parse_context ct); std::pair parse_for(parse_context ct); std::pair parse_while(parse_context ct); // pipeline parser std::pair parse_pipeline(parse_context ct); // condlist parser std::pair parse_condlist(parse_context ct); #endif //PARSE_HPP