diff options
author | Pixel <> | 2001-03-29 23:40:57 +0000 |
---|---|---|
committer | Pixel <> | 2001-03-29 23:40:57 +0000 |
commit | 80fdb0714b75cb240d8b8068d718b915f1904110 (patch) | |
tree | 113acad9045d0ad77ba4660ac0540dfc3e5ced8c /lib/meta.c |
First.start
Diffstat (limited to 'lib/meta.c')
-rw-r--r-- | lib/meta.c | 560 |
1 files changed, 560 insertions, 0 deletions
diff --git a/lib/meta.c b/lib/meta.c new file mode 100644 index 0000000..7aa5add --- /dev/null +++ b/lib/meta.c @@ -0,0 +1,560 @@ +#include <stdlib.h> +#include <stdio.h> +#include <limits.h> +#include <string.h> +#ifdef HAVE_CONFIG_H +#include "config.h" +#else +#define _(x) x +void exception(int, char *); +char * Estrdup(char *); +void * Emalloc(size_t); +#endif +#include "global.h" +#include "numbers.h" +#include "meta.h" + +static char meta_ops[] = ":.;(){}[=, "; +static char meta_firsts[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"; +static char meta_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"; + +phon_t *phons = NULL; +field_t *fields = NULL; +pattern_t *patterns = NULL; +instruct_t *instructs = NULL; + +static int isident(char *word) +{ + if (!strchr(meta_firsts, *word)) { + return 0; + } + while (*word) { + if (!strchr(meta_chars, *(word++))) { + return 0; + } + } + return 1; +} + +static char *getword(char *line, char *p) +{ + char o; + + do { + o = *(p++) = *line; + line++; + } while ((*line) && (!strchr(meta_ops, o)) && (!strchr(meta_ops, *line))); + *p = '\0'; + return line; +} + +void meta_parse_line(char *line) +{ + char buffer[BUFSIZ], *first = NULL, m = 0, *p1 = NULL, *p2 = NULL, *Fnames[MAXF], *Fimplicits[MAXF], + *Snames[MAXF], *Sinames[MAXF], gotname = 0, goteoi = 0; + phon_t *phon = NULL; + field_t *field = NULL; + pattern_t *pattern = NULL; + instruct_t *instruct = NULL; + metaexpr_t *metaexpr = NULL, *tmetaexpr, *tabmetaexpr[MAXM]; + int Fsizes[MAXF], Fvalues[MAXF], Itypes[MAXF], Etypes[MAXF], nbfields = 0, valid, i, nbimplicit = 0; + + if (*line == '#') { + return; + } + while (*line) { + line = getword(line, buffer); + if (!m) { + if (*line != ':') { + exception(1, _("Missing operator ':'")); + } + line++; + switch (buffer[0]) { + case 'F': + first = Estrdup(&buffer[1]); + m = 1; + break; + case 'P': + first = Estrdup(&buffer[1]); + pattern = (pattern_t *) Emalloc(sizeof(pattern_t)); + pattern->name = first; + pattern->next = NULL; + m = 2; + break; + case 'p': + m = 3; + break; + case 'I': + m = 4; + break; + } + } else { + switch (m) { + case 1: /* Champ */ + if (gotname) { + Fsizes[nbfields++] = char_to_number(buffer, &valid); + if (!valid) { + exception(1, _("Invalid number.")); + } + if (*line) { + if (*line != ';') { + exception(1, _("Expecting ';' for field separator.")); + } + line++; + gotname = 0; + } else { + field = (field_t *) Emalloc(sizeof(field_t)); + field->next = fields->next; + fields->next = field; + field->name = first; + field->names = (char **) Emalloc(nbfields * sizeof(char *)); + field->sizes = (int *) Emalloc(nbfields * sizeof(int)); + for (i = 0; i < nbfields; i++) { + field->names[i] = Fnames[i]; + field->sizes[i] = Fsizes[i]; + } + field->nbr = nbfields; + } + } else { + if (*line != ',') { + exception(1, _("Expecting ',' for field separator.")); + } + line++; + Fnames[nbfields] = Estrdup(buffer); + gotname = 1; + } + break; + case 2: /* Pattern */ + if (*buffer == '[') { + tmetaexpr = (metaexpr_t *) Emalloc(sizeof(metaexpr_t)); + tmetaexpr->name = NULL; + tmetaexpr->string = NULL; + tmetaexpr->left = metaexpr; + metaexpr = tmetaexpr; + } else { + tmetaexpr = (metaexpr_t *) Emalloc(sizeof(metaexpr_t)); + tmetaexpr->left = tmetaexpr->right = NULL; + tmetaexpr->type = 0; + if (*buffer == '.') { + tmetaexpr->type = 1; + line = getword(line, buffer); + } + if (!isident(buffer)) { + exception(1, _("Identifier incorrect.")); + } + tmetaexpr->name = Estrdup(buffer); + if (*line == '=') { + if (*(++line) != '.') { + exception(1, _("Error: Expecting a . after a =")); + } + line = getword(++line, buffer); + if (!isident(buffer)) { + exception(1, _("Identifier incorrect.")); + } + tmetaexpr->string = Estrdup(buffer); + } else { + tmetaexpr->string = NULL; + } + + if (metaexpr) { + metaexpr->right = tmetaexpr; + } else { + metaexpr = tmetaexpr; + } + if (*line == ';' || !*line) { + tabmetaexpr[nbfields++] = metaexpr; + if (*line) line++; + metaexpr = NULL; + } + if (!*line) { + pattern = (pattern_t *) Emalloc(sizeof(pattern_t)); + pattern->next = patterns->next; + patterns->next = pattern; + pattern->name = first; + pattern->expr = (metaexpr_t **) Emalloc(nbfields * sizeof(metaexpr_t *)); + for (i = 0; i < nbfields; i++) { + pattern->expr[i] = tabmetaexpr[i]; + } + pattern->nbr = nbfields; + } + } + break; + case 3: /* Phonème */ + if (p1) { + if (p2) { + exception(1, _("Extra parameters for field 'p'.")); + } else { + if (isident(buffer)) { + p2 = Estrdup(buffer); + } else { + exception(1, _("Identifier incorrect.")); + } + if (*line) { + exception(1, _("Unexpected char at end of line.")); + } + + phon = (phon_t *) Emalloc(sizeof(phon_t)); + phon->next = phons->next; + phons->next = phon; + phon->p1 = p1; + phon->p2 = p2; + } + } else { + if (isident(buffer)) { + p1 = Estrdup(buffer); + if (*line != '=') { + exception(1, _("Expecting operator '=' for field 'p'.")); + } + line++; + } else { + exception(1, _("Identifier incorrect.")); + } + } + break; + case 4: /* Instruction */ + if (!goteoi) { + if (isident(buffer) || (*buffer == '.')) { + Etypes[nbfields] = 0; + if (*buffer == '.') { + Etypes[nbfields] = 1; + line = getword(line, buffer); + } + Fnames[nbfields] = Estrdup(buffer); + if (*line == '=') { + if (*(++line) != '.') { + exception(1, _("Error: character . expected.")); + } + line = getword(++line, buffer); + if (!isident(buffer)) { + exception(1, _("Identifier incorrect.")); + } + Snames[nbfields] = Estrdup(buffer); + } else { + Snames[nbfields] = NULL; + } + nbfields++; + if (*line == ';') { + goteoi = 1; + line++; + } + } + } else { + if (!isident(buffer)) { + exception(1, _("Identifier incorrect.")); + } + Fimplicits[nbimplicit] = Estrdup(buffer); + if (*line != '=') { + exception(1, _("= expected after an implicit name")); + } + line = getword(++line, buffer); + + if (*buffer == '.') { + Itypes[nbimplicit] = 1; + line = getword(line, buffer); + if (!isident(buffer)) { + exception(1, _("Identifier incorrect")); + } + Sinames[nbimplicit] = Estrdup(buffer); + } else { + Sinames[nbimplicit] = NULL; + Itypes[nbimplicit] = 2; + Fvalues[nbimplicit] = char_to_number(buffer, &valid); + if (!valid) { + if (!isident(buffer)) { + exception(1, _("Identifier incorrect")); + } + Sinames[nbimplicit] = Estrdup(buffer); + Itypes[nbimplicit] = 0; + } + } + nbimplicit++; + + if (*line) { + if (*line != ';') { + exception(1, _("expecting ; as field separator")); + } + line++; + } else { + instruct = (instruct_t *) Emalloc(sizeof(instruct_t)); + instruct->next = instructs->next; + instructs->next = instruct; + instruct->names = (char **) Emalloc(nbfields * sizeof(char *)); + instruct->strings = (char **) Emalloc(nbfields * sizeof(char *)); + instruct->etypes = (int *) Emalloc(nbfields * sizeof(int)); + instruct->implicits = (char **) Emalloc(nbimplicit * sizeof(char *)); + instruct->ivalues = (int *) Emalloc(nbimplicit * sizeof(int)); + instruct->istrings = (char **) Emalloc(nbimplicit * sizeof(char *)); + instruct->itypes = (int *) Emalloc(nbimplicit * sizeof(int)); + for (i = 0; i < nbfields; i++) { + instruct->names[i] = Fnames[i]; + instruct->strings[i] = Snames[i]; + instruct->etypes[i] = Etypes[i]; + } + instruct->nbexplicit = nbfields; + for (i = 0; i < nbimplicit; i++) { + instruct->implicits[i] = Fimplicits[i]; + instruct->ivalues[i] = Fvalues[i]; + instruct->istrings[i] = Sinames[i]; + instruct->itypes[i] = Itypes[i]; + } + instruct->nbimplicit = nbimplicit; + goteoi = 0; + } + } + break; + } + } + } +} + +int meta_init(void) +{ + if (!(phons = (phon_t *) malloc(sizeof(phon_t)))) { + return -1; + } + phons->p1 = phons->p2 = NULL; + phons->next = NULL; + + if (!(fields = (field_t *) malloc(sizeof(field_t)))) { + return -1; + } + fields->name = NULL; + fields->names = NULL; + fields->sizes = NULL; + fields->next = NULL; + + if (!(patterns = (pattern_t *) malloc(sizeof(pattern_t)))) { + return -1; + } + patterns->name = NULL; + patterns->expr = NULL; + patterns->next = NULL; + + if (!(instructs = (instruct_t *) malloc(sizeof(instruct_t)))) { + return -1; + } + instructs->names = NULL; + instructs->strings = NULL; + instructs->etypes = NULL; + instructs->implicits = NULL; + instructs->ivalues = NULL; + instructs->istrings = NULL; + instructs->itypes = NULL; + + return 0; +} + +static void recurs_free_phon(phon_t * phon) { + if (phon->next) { + recurs_free_phon(phon->next); + } + + free(phon->p1); + free(phon->p2); + free(phon); +} + +static void recurs_free_field(field_t * field) { + int i; + + if (field->next) { + recurs_free_field(field->next); + } + + free(field->name); + for (i = 0; i < field->nbr; i++) { + free(field->names[i]); + } + free(field->names); + free(field->sizes); + free(field); +} + +static void recurs_free_metaexpr(metaexpr_t * metaexpr) { + if (metaexpr->left) { + recurs_free_metaexpr(metaexpr->left); + } + + if (metaexpr->right) { + recurs_free_metaexpr(metaexpr->right); + } + + if (metaexpr->name) { + free(metaexpr->name); + } + + if (metaexpr->string) { + free(metaexpr->string); + } + + free(metaexpr); +} + +static void recurs_free_pattern(pattern_t * pattern) { + int i; + + if (pattern->next) { + recurs_free_pattern(pattern->next); + } + + free(pattern->name); + for (i = 0; i < pattern->nbr; i++) { + recurs_free_metaexpr(pattern->expr[i]); + } + free(pattern->expr); + free(pattern); +} + +static void recurs_free_instruct(instruct_t * instruct) { + int i; + + if (instruct->next) { + recurs_free_instruct(instruct->next); + } + + for (i = 0; i < instruct->nbexplicit; i++) { + free(instruct->names[i]); + if (instruct->strings[i]) { + free(instruct->strings[i]); + } + } + + for (i = 0; i < instruct->nbimplicit; i++) { + free(instruct->implicits[i]); + free(instruct->istrings[i]); + } + + free(instruct->names); + free(instruct->strings); + free(instruct->etypes); + free(instruct->implicits); + free(instruct->istrings); + free(instruct->itypes); + free(instruct); +} + +void meta_flush(void) { + if (phons->next) recurs_free_phon(phons->next); + if (fields->next) recurs_free_field(fields->next); + if (patterns->next) recurs_free_pattern(patterns->next); + if (instructs->next) recurs_free_instruct(instructs->next); + free(phons); + free(fields); + free(patterns); + free(instructs); + phons = NULL; + fields = NULL; + patterns = NULL; + instructs = NULL; +} + +#ifndef HAVE_CONFIG_H +char * Estrdup(char * o) { + char * r; + + if (!(r = strdup(o))) { + exception(1, _("Out of memory.")); + } + return r; +} + +void * Emalloc(size_t s) { + void * r; + + if (!(r = malloc(s))) { + exception(1, _("Out of memory.")); + } + return r; +} + +void exception(int level, char *msg) +{ + fprintf(stderr, "%s\n", msg); + exit(level); +} + +void main(void) +{ + FILE *f; + char buf[BUFSIZ], *p; + phon_t *phon; + field_t *field; + pattern_t *pattern; + instruct_t *instruct; + int i; + + if (meta_init()) + exception(1, _("Meta parser init failed.")); + + f = fopen("instructions.txt", "r"); + while (fgets(buf, BUFSIZ, f)) { + if ((p = strchr(buf, '\n'))) { + *p = '\0'; + } + meta_parse_line(buf); + } + + fprintf(stderr, "\nListe des phonèmes:\n"); + for (phon = phons->next; phon; phon = phon->next) { + fprintf(stderr, " o %s <===> %s\n", phon->p1, phon->p2); + } + + fprintf(stderr, "\nListe des champs:\n"); + for (field = fields->next; field; field = field->next) { + fprintf(stderr, " o Champ nommé %s, contenant %i parties:\n", field->name, field->nbr); + for (i = 0; i < field->nbr; i++) { + fprintf(stderr, " + %s (%i bits)\n", field->names[i], field->sizes[i]); + } + } + + fprintf(stderr, "\nListe des patterns:\n"); + for (pattern = patterns->next; pattern; pattern = pattern->next) { + fprintf(stderr, " o Pattern nommée %s, contenant %i metaexpressions:\n", pattern->name, pattern->nbr); + for (i = 0; i < pattern->nbr; i++) { + fprintf(stderr, " + %s (%s) type: %s\n", + pattern->expr[i]->name ? pattern->expr[i]->name : "Opérateur [", + pattern->expr[i]->string ? pattern->expr[i]->string : "Aucune chaîne associée", + pattern->expr[i]->type ? "Constante prédéfinie" : pattern->expr[i]->left ? "Binaire" : pattern->expr[i]->right ? "Unaire" : "Feuille"); + if (pattern->expr[i]->left) { + fprintf(stderr, " - gauche: %s (%s) type: %s\n", + pattern->expr[i]->left->name ? pattern->expr[i]->left->name : "Opérateur [", + pattern->expr[i]->left->string ? pattern->expr[i]->left->string : "Aucune chaîne associée", + pattern->expr[i]->left->type ? "Constante prédéfinie" : "Feuille"); + } + if (pattern->expr[i]->right) { + fprintf(stderr, " - droite: %s (%s) type: %s\n", + pattern->expr[i]->right->name ? pattern->expr[i]->right->name : "Opérateur [", + pattern->expr[i]->right->string ? pattern->expr[i]->right->string : "Aucune chaîne associée", + pattern->expr[i]->right->type ? "Constante prédéfinie" : "Feuille"); + } + } + } + + fprintf(stderr, "\nListe des instructions:\n"); + for (instruct = instructs->next; instruct; instruct = instruct->next) { + fprintf(stderr, " o Instruction contenant %i champs explicites et %i champs implicites.\n", instruct->nbexplicit, instruct->nbimplicit); + fprintf(stderr, " => Champs explicites.\n"); + for (i = 0; i < instruct->nbexplicit; i++) { + fprintf(stderr, " + %s <= %s (type %s)\n", + instruct->names[i], + instruct->strings[i] ? instruct->strings[i] : "Pas de chaîne associée", + instruct->etypes[i] ? "prédéfinit" : "direct"); + } + fprintf(stderr, " => Champs implicites.\n"); + for (i = 0; i < instruct->nbimplicit; i++) { + switch (instruct->itypes[i]) { + case 0: + fprintf(stderr, " + %s <= %s (type direct)\n", instruct->implicits[i], instruct->istrings[i]); + break; + case 1: + fprintf(stderr, " + %s <= %i (type prédéfinit)\n", instruct->implicits[i], instruct->istrings[i]); + break; + case 2: + fprintf(stderr, " + %s <= %i (type valeur)\n", instruct->implicits[i], instruct->ivalues[i]); + break; + } + } + } +} + +#endif |