diff options
author | ridiculousfish <corydoras@ridiculousfish.com> | 2013-07-28 15:19:38 -0700 |
---|---|---|
committer | ridiculousfish <corydoras@ridiculousfish.com> | 2013-07-28 15:19:38 -0700 |
commit | b133137a1f0341f9e21b622448bf5d5056c53046 (patch) | |
tree | e7903ede24052ebe81852bfd3436ebc8463af639 /parse_productions.h | |
parent | 9dc91925e7bf4dc43936f7657a1a85cbd1ec4909 (diff) |
Removed templates (yay)
Diffstat (limited to 'parse_productions.h')
-rw-r--r-- | parse_productions.h | 631 |
1 files changed, 25 insertions, 606 deletions
diff --git a/parse_productions.h b/parse_productions.h index d3743014..d7b7c19d 100644 --- a/parse_productions.h +++ b/parse_productions.h @@ -8,45 +8,6 @@ #include "parse_tree.h" -/* Terrifying template black magic. */ - -/* - -- Get info for symbol -- Resolve production from info -- Get productions for children -- Get symbols for productions - -Production may be: - -1. Single value -2. Sequence of values (possibly empty) -3. Options of Single / Sequence - -Info to specify: - -1. Number of different productions -2. Resolver function -3. Symbols for associated productions - -Choice: should info be a class or a data? - -data: - -struct Symbol_t -{ - enum parse_token_type_t token_type; - int (*resolver)(parse_token_type_t tok, parse_keyword_t key); //may be trivial - production productions[5]; -} - -struct Production_t -{ - enum parse_token_type_t symbols[5]; -} - -*/ - namespace parse_productions { @@ -54,596 +15,54 @@ namespace parse_productions #define MAX_SYMBOLS_PER_PRODUCTION 5 +typedef uint32_t production_tag_t; /* A production is an array of unsigned char. Symbols are encoded directly as their symbol value. Keywords are encoded with an offset of LAST_TOKEN_OR_SYMBOL + 1. So essentially we glom together keywords and symbols. */ -typedef unsigned char Production_t[MAX_SYMBOLS_PER_PRODUCTION]; - -typedef Production_t ProductionList_t[MAX_PRODUCTIONS]; - -#define PRODUCE_KEYWORD(x) ((x) + LAST_TOKEN_OR_SYMBOL + 1) - -struct Symbol_t -{ - enum parse_token_type_t token_type; - int (*resolver)(parse_token_type_t tok, parse_keyword_t key); - Production_t productions[MAX_PRODUCTIONS]; -}; - - - -} - -namespace parse_symbols -{ - -#define SYMBOL(x) static inline parse_token_type_t get_token() { return x; } - -#define PRODUCE(X) static int production(parse_token_type_t tok, parse_keyword_t key) { return X; } - -#define NO_PRODUCTION (-1) - -struct Symbol -{ - typedef int magic_symbol_type_t; -}; - -template<parse_token_type_t WHICH> -struct Token : public Symbol -{ - SYMBOL(WHICH); -}; - -/* Placeholder */ -typedef Token<token_type_invalid> none; - -typedef Token<token_type_invalid> EMPTY; - -template<typename T0, typename T1, typename T2 = none, typename T3 = none, typename T4 = none, typename T5 = none> -struct Seq -{ - typedef T0 t0; - typedef T1 t1; - typedef T2 t2; - typedef T3 t3; - typedef T4 t4; - typedef T5 t5; - - typedef int magic_seq_type_t; -}; - -template<typename P0, typename P1, typename P2 = none, typename P3 = none, typename P4 = none, typename P5 = none> -struct OR -{ - typedef P0 p0; - typedef P1 p1; - typedef P2 p2; - typedef P3 p3; - typedef P4 p4; - typedef P5 p5; +typedef uint8_t production_element_t; - typedef int magic_or_type_t; -}; +/* An index into a production option list */ +typedef uint8_t production_option_idx_t; -template<parse_keyword_t WHICH> -struct Keyword : public Symbol +inline parse_token_type_t production_element_type(production_element_t elem) { - static inline parse_keyword_t get_token() + if (elem > LAST_TOKEN_OR_SYMBOL) { - return WHICH; + return parse_token_type_string; } -}; - -struct job; -struct statement; -struct job_continuation; -struct boolean_statement; -struct block_statement; -struct if_statement; -struct if_clause; -struct else_clause; -struct else_continuation; -struct switch_statement; -struct decorated_statement; -struct switch_statement; -struct case_item_list; -struct case_item; -struct argument_list_nonempty; -struct argument_list; -struct block_statement; -struct block_header; -struct for_header; -struct while_header; -struct begin_header; -struct function_header; -struct boolean_statement; -struct decorated_statement; -struct plain_statement; -struct arguments_or_redirections_list; -struct argument_or_redirection; -struct redirection; -struct statement_terminator; -struct optional_background; - -/* A job_list is a list of jobs, separated by semicolons or newlines */ -struct job_list : public Symbol -{ - typedef OR< - EMPTY, - Seq<job, job_list>, - Seq<Token<parse_token_type_end>, job_list> - > productions; - - SYMBOL(symbol_job_list) - - static int production(parse_token_type_t token_type, parse_keyword_t token_keyword) + else { - switch (token_type) - { - case parse_token_type_string: - // 'end' is special - switch (token_keyword) - { - case parse_keyword_end: - case parse_keyword_else: - // End this job list - return 0; - - default: - // Normal string - return 1; - } - - case parse_token_type_pipe: - case parse_token_type_redirection: - case parse_token_type_background: - return 1; - - case parse_token_type_end: - // Empty line - return 2; - - case parse_token_type_terminate: - // no more commands, just transition to empty - return 0; - break; - - default: - return NO_PRODUCTION; - } + return static_cast<parse_token_type_t>(elem); } +} -}; - -/* A job is a non-empty list of statements, separated by pipes. (Non-empty is useful for cases like if statements, where we require a command). To represent "non-empty", we require a statement, followed by a possibly empty job_continuation */ -struct job : public Symbol -{ - typedef Seq<statement, job_continuation> sole_production; - SYMBOL(symbol_job); -}; - -struct job_continuation : public Symbol -{ - typedef OR< - EMPTY, - Seq<Token<parse_token_type_pipe>, statement, job_continuation> - > productions; - - SYMBOL(symbol_job_continuation); - - static int production(parse_token_type_t token_type, parse_keyword_t token_keyword) - { - switch (token_type) - { - case parse_token_type_pipe: - // Pipe, continuation - return 1; - - default: - // Not a pipe, no job continuation - return 0; - } - - } -}; - -/* A statement is a normal command, or an if / while / and etc */ -struct statement : public Symbol -{ - typedef OR< - boolean_statement, - block_statement, - if_statement, - switch_statement, - decorated_statement - > productions; - - SYMBOL(symbol_statement); - - static int production(parse_token_type_t token_type, parse_keyword_t token_keyword) - { - switch (token_type) - { - case parse_token_type_string: - switch (token_keyword) - { - case parse_keyword_and: - case parse_keyword_or: - case parse_keyword_not: - return 0; - - case parse_keyword_for: - case parse_keyword_while: - case parse_keyword_function: - case parse_keyword_begin: - return 1; - - case parse_keyword_if: - return 2; - - case parse_keyword_else: - //symbol_stack_pop(); - return NO_PRODUCTION; - - case parse_keyword_switch: - return 3; - - case parse_keyword_end: - PARSER_DIE(); //todo - return NO_PRODUCTION; - - // 'in' is only special within a for_header - case parse_keyword_in: - case parse_keyword_none: - case parse_keyword_command: - case parse_keyword_builtin: - case parse_keyword_case: - return 4; - } - break; - - case parse_token_type_pipe: - case parse_token_type_redirection: - case parse_token_type_background: - case parse_token_type_terminate: - return NO_PRODUCTION; - //parse_error(L"statement", token); - - default: - return NO_PRODUCTION; - } - } - -}; - -struct if_statement : public Symbol -{ - typedef Seq<if_clause, else_clause, Keyword<parse_keyword_end>, arguments_or_redirections_list> sole_production; - SYMBOL(symbol_if_statement); -}; - -struct if_clause : public Symbol -{ - typedef Seq<Keyword<parse_keyword_if>, job, statement_terminator, job_list> sole_production; - SYMBOL(symbol_if_clause); -}; - -struct else_clause : public Symbol -{ - typedef OR< - EMPTY, - Seq<Keyword<parse_keyword_else>, else_continuation> - > productions; - - SYMBOL(symbol_else_clause); - - static int production(parse_token_type_t tok, parse_keyword_t key) - { - switch (key) - { - case parse_keyword_else: - return 1; - default: - return 0; - } - } -}; - -struct else_continuation : public Symbol -{ - typedef OR< - Seq<if_clause, else_clause>, - Seq<statement_terminator, job_list> - > productions; - - SYMBOL(symbol_else_continuation); - - static int production(parse_token_type_t tok, parse_keyword_t key) - { - switch (key) - { - case parse_keyword_if: - return 0; - default: - return 1; - } - } -}; - -struct switch_statement : public Symbol -{ - typedef Seq<Keyword<parse_keyword_switch>, - Token<parse_token_type_string>, - statement_terminator, - case_item_list, - Keyword<parse_keyword_end> - > sole_production; - - SYMBOL(symbol_switch_statement); -}; - -struct case_item_list : public Symbol -{ - typedef OR - < - EMPTY, - Seq<case_item, case_item_list>, - Seq<Token<parse_token_type_end>, case_item_list> - > productions; - - SYMBOL(symbol_case_item_list); - - static int production(parse_token_type_t tok, parse_keyword_t key) - { - switch (key) - { - case parse_keyword_case: return 1; - - default: - if (tok == parse_token_type_end) - { - /* empty line */ - return 2; - } - else - { - return 0; - } - - } - } -}; - -struct case_item : public Symbol -{ - typedef Seq<Keyword<parse_keyword_case>, argument_list, statement_terminator, job_list> sole_production; - - SYMBOL(symbol_case_item); -}; - -struct argument_list_nonempty : public Symbol -{ - typedef Seq<Token<parse_token_type_string>, argument_list> sole_production; - SYMBOL(symbol_argument_list_nonempty); -}; - -struct argument_list : public Symbol -{ - typedef OR<EMPTY, argument_list_nonempty> productions; - - SYMBOL(symbol_argument_list); - static int production(parse_token_type_t tok, parse_keyword_t key) - { - switch (tok) - { - case parse_token_type_string: - return 1; - default: - return 0; - } - } -}; - -struct block_statement : public Symbol -{ - typedef Seq<block_header, statement_terminator, job_list, Keyword<parse_keyword_end>, arguments_or_redirections_list> sole_production; - - SYMBOL(symbol_block_statement); -}; - -struct block_header : public Symbol -{ - typedef OR<for_header, while_header, function_header, begin_header> productions; - - SYMBOL(symbol_block_header); - - static int production(parse_token_type_t tok, parse_keyword_t key) - { - switch (key) - { - // todo - case parse_keyword_else: - return NO_PRODUCTION; - case parse_keyword_for: - return 0; - case parse_keyword_while: - return 1; - case parse_keyword_function: - return 2; - case parse_keyword_begin: - return 3; - default: - return NO_PRODUCTION; - } - } -}; - -struct for_header : public Symbol -{ - typedef Seq<Keyword<parse_keyword_for>, Token<parse_token_type_string>, Keyword<parse_keyword_in>, arguments_or_redirections_list> sole_production; - - SYMBOL(symbol_for_header); -}; - -struct while_header : public Symbol -{ - typedef Seq<Keyword<parse_keyword_while>, statement> sole_production; - - SYMBOL(symbol_while_header); -}; - -struct begin_header : public Symbol -{ - typedef Keyword<parse_keyword_begin> sole_production; - SYMBOL(symbol_begin_header); -}; - -struct function_header : public Symbol -{ - typedef Seq< Keyword<parse_keyword_function>, Token<parse_token_type_string>, argument_list> sole_production; - SYMBOL(symbol_function_header); -}; - -/* A boolean statement is AND or OR or NOT */ -struct boolean_statement : public Symbol +inline parse_keyword_t production_element_keyword(production_element_t elem) { - typedef OR< - Seq<Keyword<parse_keyword_and>, statement>, - Seq<Keyword<parse_keyword_or>, statement>, - Seq<Keyword<parse_keyword_not>, statement> - > productions; - - SYMBOL(symbol_boolean_statement); - - static int production(parse_token_type_t tok, parse_keyword_t key) + if (elem > LAST_TOKEN_OR_SYMBOL) { - switch (key) - { - case parse_keyword_and: - return 0; - case parse_keyword_or: - return 1; - case parse_keyword_not: - return 2; - default: - return NO_PRODUCTION; - } + // First keyword is LAST_TOKEN_OR_SYMBOL + 1 + return static_cast<parse_keyword_t>(elem - LAST_TOKEN_OR_SYMBOL - 1); } -}; - -/* A decorated_statement is a command with a list of arguments_or_redirections, possibly with "builtin" or "command" */ -struct decorated_statement : public Symbol -{ - - typedef OR< - Seq<Keyword<parse_keyword_command>, plain_statement>, - Seq<Keyword<parse_keyword_builtin>, plain_statement>, - plain_statement - > productions; - - SYMBOL(symbol_decorated_statement); - - static int production(parse_token_type_t tok, parse_keyword_t key) + else { - switch (key) - { - case parse_keyword_command: - return 0; - case parse_keyword_builtin: - return 1; - default: - return 2; - } + return parse_keyword_none; } -}; - -struct plain_statement : public Symbol -{ - - typedef Seq<Token<parse_token_type_string>, arguments_or_redirections_list, optional_background> sole_production; - - SYMBOL(symbol_plain_statement); - -}; - -struct arguments_or_redirections_list : public Symbol -{ - typedef OR< - EMPTY, - Seq<argument_or_redirection, arguments_or_redirections_list> > - productions; - - SYMBOL(symbol_arguments_or_redirections_list); +} - static int production(parse_token_type_t tok, parse_keyword_t key) - { - switch (tok) - { - case parse_token_type_string: - case parse_token_type_redirection: - return 1; - default: - return 0; - } - } -}; -struct argument_or_redirection : public Symbol +inline bool production_element_is_valid(production_element_t elem) { - typedef OR< - Token<parse_token_type_string>, - redirection - > productions; - - - SYMBOL(symbol_argument_or_redirection); + return elem != token_type_invalid; +} - static int production(parse_token_type_t tok, parse_keyword_t key) - { - switch (tok) - { - case parse_token_type_string: - return 0; - case parse_token_type_redirection: - return 1; - default: - return NO_PRODUCTION; - } - } -}; +typedef production_element_t const production_t[MAX_SYMBOLS_PER_PRODUCTION]; -struct redirection : public Symbol -{ - typedef Token<parse_token_type_redirection> production; - SYMBOL(parse_token_type_redirection); -}; +typedef production_t production_options_t[MAX_PRODUCTIONS]; -struct statement_terminator : public Symbol -{ - typedef Token<parse_token_type_end> production; - SYMBOL(parse_token_type_end); -}; +#define PRODUCE_KEYWORD(x) ((x) + LAST_TOKEN_OR_SYMBOL + 1) -struct optional_background : public Symbol -{ - typedef OR< - EMPTY, - Token<parse_token_type_background> - > productions; - - SYMBOL(symbol_optional_background); - - static int production(parse_token_type_t tok, parse_keyword_t key) - { - switch (tok) - { - case parse_token_type_background: - return 1; - default: - return 0; - } - } -}; +const production_t *production_for_token(parse_token_type_t node_type, parse_token_type_t input_type, parse_keyword_t input_keyword, production_option_idx_t *out_idx, production_tag_t *out_tag); } + #endif |