diff options
Diffstat (limited to 'src/gram.y')
-rw-r--r-- | src/gram.y | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/src/gram.y b/src/gram.y new file mode 100644 index 0000000..c065bcf --- /dev/null +++ b/src/gram.y @@ -0,0 +1,181 @@ +%{ +#include "trans.h" +#define obstack_chunk_alloc malloc +#define obstack_chunk_free free +#include <obstack.h> + +struct obstack stk; + +struct descr *make_descr(enum descr_type type, u_char *value); + +%} + +%token NODE POS END MEANING ALIAS ANT TOPIC FORMS XREF +%token <string> STRING + +%type <string> string pos forms +%type <header> nodehdr alias +%type <descr> descr +%type <list> aliases descrlist header + +%union { + u_char *string; + struct header *header; + struct descr *descr; + RAD_LIST *list; +}; + + +%% + +input : list + ; + +list : node + | list node + ; + +node : header descrlist end + { + register_node($1, $2); + } + ; + +end : END + ; + +header : nodehdr + { + $$ = list_create(); + list_append($$, $1); + } + | nodehdr aliases + { + list_prepend($2, $1); + $$ = $2; + } + ; + +nodehdr : NODE string pos forms + { + $$ = emalloc(sizeof(*$$)); + $$->key = $2; + $$->pos = $3; + $$->forms = $4; + } + ; + +pos : /* empty */ + { + $$ = NULL; + } + | POS string + { + $$ = $2; + } + ; + +forms : /* empty */ + { + $$ = NULL; + } + | FORMS string + { + $$ = $2; + } + ; + +aliases : alias + { + $$ = list_create(); + list_append($$, $1); + } + | aliases alias + { + list_append($1, $2); + $$ = $1; + } + ; + +alias : ALIAS string pos forms + { + $$ = emalloc(sizeof(*$$)); + $$->key = $2; + $$->pos = $3; + $$->forms = $4; + } + ; + +descrlist: descr + { + $$ = list_create(); + list_append($$, $1); + } + | descrlist descr + { + list_append($1, $2); + $$ = $1; + } + ; + +descr : TOPIC string + { + $$ = make_descr(descr_topic, $2); + } + | MEANING string + { + $$ = make_descr(descr_meaning, $2); + } + | ANT string + { + $$ = make_descr(descr_antonym, $2); + } + | XREF string + { + $$ = make_descr(descr_xref, $2); + } + ; + +string : mstring + { + obstack_1grow(&stk, 0); + $$ = obstack_finish(&stk); + } + ; + +mstring : STRING + { + obstack_grow(&stk, $1, strlen($1)); + } + | mstring STRING + { + obstack_1grow(&stk, '\n'); + obstack_grow(&stk, $2, strlen($2)); + } + ; + +%% + +yyerror(char *s) +{ + fprintf (stderr, "%s:%d: %s\n", + file_name, input_line, s); +} + +int +parse(char *name) +{ + if (name) + open_input(name); + obstack_init(&stk); + return yyparse(); +} + +struct descr * +make_descr(enum descr_type type, u_char *value) +{ + struct descr *p = emalloc(sizeof(*p)); + p->type = type; + p->value = value; + return p; +} |