%{ /* This file is part of Ellinika project. Copyright (C) 2004 Sergey Poznyakoff Ellinika is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. Ellinika is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Ellinika; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include "trans.h" #define obstack_chunk_alloc malloc #define obstack_chunk_free free #include struct obstack stk; struct descr *make_descr(enum descr_type type, u_char *value); static int _register_topic(void *item, void *data); static int convert_pos(char *text, int *pos); %} %token NODE POS END MEANING ALIAS ANT TOPIC FORMS XREF %token STRING %type pos %type string forms %type
nodehdr alias %type descr %type list aliases descrlist header %type item %union { int num; u_char *string; struct header *header; struct descr *descr; RAD_LIST *list; struct gram_item item; }; %% input : list { node_list = $1; } ; list : item { $$ = list_create(); switch ($1.type) { case item_node: list_append($$, $1.v.node); break; case item_list: list_concat($$, $1.v.list); list_destroy(&$1.v.list, NULL, NULL); } } | list item { switch ($2.type) { case item_node: list_append($1, $2.v.node); break; case item_list: list_concat($1, $2.v.list); list_destroy(&$2.v.list, NULL, NULL); } $$ = $1; } ; item : header descrlist end { $$.type = item_node; $$.v.node = create_node($1, $2); } | TOPIC string list end { $$.type = item_list; $$.v.list = $3; list_iterate($3, _register_topic, make_descr(descr_topic, $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 */ { $$ = -1; } | POS string { if (convert_pos($2, &$$)) YYERROR; } ; 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 ? file_name : "", input_line, s); } int parse(int argc, char **argv) { if (argc) open_input(argc, argv); 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; } static int _register_topic(void *item, void *data) { struct node *node = item; list_append(node->descr, data); return 0; } static int convert_pos(char *text, int *pos) { unsigned long n; if (sql_query_n(&n, "SELECT id FROM pos WHERE abbr=\"%s\"", text) && sql_query_n(&n, "SELECT id FROM pos WHERE abbr_lat=\"%s\"", text) && sql_query_n(&n, "SELECT id FROM pos WHERE name=\"%s\"", text)) { yyerror("unknown or misspelled part of speech"); return 1; } *pos = n; return 0; }