aboutsummaryrefslogtreecommitdiffhomepage
path: root/parse_productions.h
diff options
context:
space:
mode:
authorGravatar ridiculousfish <corydoras@ridiculousfish.com>2013-07-28 15:19:38 -0700
committerGravatar ridiculousfish <corydoras@ridiculousfish.com>2013-07-28 15:19:38 -0700
commitb133137a1f0341f9e21b622448bf5d5056c53046 (patch)
treee7903ede24052ebe81852bfd3436ebc8463af639 /parse_productions.h
parent9dc91925e7bf4dc43936f7657a1a85cbd1ec4909 (diff)
Removed templates (yay)
Diffstat (limited to 'parse_productions.h')
-rw-r--r--parse_productions.h631
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