Skip to content

Instantly share code, notes, and snippets.

@osvein
Created November 12, 2017 21:29
Show Gist options
  • Select an option

  • Save osvein/abf1dee423deac0195060ff6ea2362b2 to your computer and use it in GitHub Desktop.

Select an option

Save osvein/abf1dee423deac0195060ff6ea2362b2 to your computer and use it in GitHub Desktop.
#include "parser.h"
/* general */
Nonterminal n_doc_string = {
PROD_LEAF(t_bracket_curly_closing),
PROD(NULL, n_doc_string),
};
Nonterminal n_doc = {
PROD_LEAF(t_bracket_curly_opening, n_doc_string),
PROD_END(NULL),
};
/* group */
Nonterminal n_group_statements = {
PROD_LEAF(t_endgroup),
PROD(NULL, n_group_statements),
};
/* script */
Nonterminal n_script_extends = {
PROD_LEAF(t_extends, n_identifier),
PROD_END(NULL),
};
Nonterminal n_script_flags = {
PROD_LEAF(t_native, n_script_flags),
PROD_LEAF(t_const, n_script_flags),
PROD(NULL, n_identifier, n_script_flags),
};
Nonterminal n_script_statements = {
PROD_LEAF(t_import, n_identifier, n_script_statements),
PROD_LEAF(t_group, n_identifier, n_group_statements),
PROD_LEAF(t_customevent
};
Nonterminal n_scripts = {
PROD_LEAF(t_scriptname, n_identifier, n_extends, n_script_flags, n_doc, n_script_statements, n_scripts),
PROD_END(t_end),
PROD_ERR(NULL),
};
#include "parser.h"
void
parse(FILE *in, Terminal lookahead, Nonterminal n)
{
Production *i;
Symbol **child;
for (i = n; i->token; i++) {
if (lookahead) {
if (i->token == lookahead)
break
} else if (istok(in, i->token)) {
lookahead = i->token;
break;
}
}
if (!i->children) {
parse_err();
return;
}
for (child = i->children; *child; child++) {
if ((*child)->type) {
} else {
}
}
}
int
istok(Input in, const char *expect)
{
if (in->token) {
return expect == in->token;
} else {
ifg
}
#define PROD(next, ...) { next, &(Symbol *[]){ __VA_ARGS__, NULL } }
#define PROD_LEAF(next, ...) PROD(next, next, __VA_ARGS__)
#define PROD_END(next) { next, sym_empty }
#define PROD_ERR(next) { next, NULL }
typedef struct {
Terminal *next;
Symbol **children;
} Production;
typedef Production Nonterminal[];
typedef struct {
enum {
SYM_T,
SYM_N
} type;
union {
Terminal t;
Nonterminal n;
} sym;
} Symbol;
Symbol *sym_empty[] = { NULL };
Terminal *t_any = "";
#include "parser.h"
#define TOKSEP " \t\r\n\v\f{};+-*/%=<>!&|:,"
#define TOKSEP_FMT ("%1[" TOKSEP "]")
const char
*t_doc_open = "{",
*t_doc_close = "}",
*t_comment = ";",
*t_comment_open = ";/",
*t_comment_close = "/;",
*t_add = "+",
*t_sub = "-",
*t_mul = "*",
*t_div = "/",
*t_mod = "%",
*t_assign = "=",
*t_assign_add = "+=",
*t_assign_sub = "-=",
*t_assign_mul = "*=",
*t_assign_div = "/=",
*t_assign_mod = "%=",
*t_cmp_eq = "==",
*t_cmp_neq = "!=",
*t_cmp_lt = "<",
*t_cmp_lteq = "<=",
*t_cmp_gt = ">",
*t_cmp_gteq = ">=",
*t_not = "!",
*t_and = "&&",
*t_or = "||",
*t_scope = ":",
*t_listsep = ",",
*t_as = "as",
*t_is = "is",
*t_flag_native = "native",
*t_flag_const = "const",
*t_flag_auto = "auto",
*t_flag_autoreadonly = "autoreadonly",
*t_flag_global = "global",
*t_type_bool = "bool",
*t_type_float = "float",
*t_type_int = "int",
*t_type_string = "string",
*t_type_var = "var",
*t_type_customevent = "customeventname",
*t_type_scriptevent = "scripteventname",
*t_type_structvar = "structvarname",
*t_literal_none = "none",
*t_literal_false = "false",
*t_literal_true = "true",
*t_new = "new",
*t_if = "if",
*t_if_elseif = "elseif",
*t_if_else = "else",
*t_if_end = "endif",
*t_while = "while",
*t_while_end = "endwhile",
*t_return = "return",
*t_script_name = "scriptname",
*t_script_extends = "extends",
*t_event = "event",
*t_event_end = "endevent",
*t_func = "function",
*t_func_end = "endfunction",
*t_group = "group",
*t_group_end = "endgroup",
*t_import = "import",
*t_prop = "property",
*t_prop_end = "endproperty",
*t_state = "state",
*t_state_end = "endstate",
*t_struct = "struct",
*t_struct_end = "endstruct",
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment