From a984cf3f28d3a5935c84f96f6da3bc7bd39a9ff1 Mon Sep 17 00:00:00 2001 From: Pixel <> Date: Fri, 13 Apr 2001 12:03:09 +0000 Subject: Assembleur. --- lib/meta.c | 179 ++++++++++++++++++++++++++++++++++--------------------------- 1 file changed, 99 insertions(+), 80 deletions(-) (limited to 'lib/meta.c') diff --git a/lib/meta.c b/lib/meta.c index 275d60b..52e29ff 100644 --- a/lib/meta.c +++ b/lib/meta.c @@ -7,14 +7,17 @@ #include "config.h" #else #define _(x) x -void exception(int, char *); -char * Estrdup(char *); -void * Emalloc(size_t); #endif #include "exceptions.h" #include "numbers.h" #include "meta.h" +/*************************\ +* * +* Meta Parser * +* * +\*************************/ + static char meta_ops[] = ":.;(){}[=, "; static char meta_firsts[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_"; static char meta_chars[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz_0123456789"; @@ -24,6 +27,8 @@ field_t *fields = NULL; pattern_t *patterns = NULL; instruct_t *instructs = NULL; +/* Fonction interne pour déterminer si une chaîne forme un identifier correct. */ + static int isident(char *word) { if (!strchr(meta_firsts, *word)) { @@ -37,6 +42,8 @@ static int isident(char *word) return 1; } +/* La fonction getword pour le meta parser. Beaucoup plus simple que le parser normal. */ + static char *getword(char *line, char *p) { char o; @@ -50,17 +57,21 @@ static char *getword(char *line, char *p) return line; } +/* La terrible fonction meta_parse_line. Elle lit une chaîne correspondant à une ligne du fichier texte d'entrée. +Le problème réside surtout dans le fait qu'il y a des variables globales et des effets de bords, ce qui empèche le +découpage en sous routines. */ + 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, errbuff[BUFSIZ]; + *Snames[MAXF], *Sinames[MAXF], gotname = 0, goteoi = 0, errbuff[BUFSIZ]; 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; } @@ -73,6 +84,7 @@ void meta_parse_line(char *line) sprintf(errbuff, _("Analysing word '%s'"), buffer); pushcontext(errbuff); if (!m) { + /* Premier mot lut de la chaîne */ if (*line != ':') { exception(1, _("Missing operator ':'")); } @@ -97,6 +109,7 @@ void meta_parse_line(char *line) break; } } else { + /* Nous avons lut le premier mot, nous savons ce qu'il faut faire. */ switch (m) { case 1: /* Champ */ if (gotname) { @@ -117,6 +130,7 @@ void meta_parse_line(char *line) 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]; @@ -169,7 +183,7 @@ void meta_parse_line(char *line) } else { tmetaexpr->string = NULL; } - + if (metaexpr) { metaexpr->right = tmetaexpr; } else { @@ -177,7 +191,8 @@ void meta_parse_line(char *line) } if (*line == ';' || !*line) { tabmetaexpr[nbfields++] = metaexpr; - if (*line) line++; + if (*line) + line++; metaexpr = NULL; } if (!*line) { @@ -185,7 +200,8 @@ void meta_parse_line(char *line) pattern->next = patterns->next; patterns->next = pattern; pattern->name = first; - pattern->expr = (metaexpr_t **) Emalloc(nbfields * sizeof(metaexpr_t *)); + pattern->expr = + (metaexpr_t **) Emalloc(nbfields * sizeof(metaexpr_t *)); for (i = 0; i < nbfields; i++) { pattern->expr[i] = tabmetaexpr[i]; } @@ -311,6 +327,7 @@ void meta_parse_line(char *line) 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]; @@ -332,10 +349,12 @@ void meta_parse_line(char *line) } popcontext(); } - + popcontext(); } +/* Initialiseur et destructeur du meta parser */ + int meta_init(void) { if (!(phons = (phon_t *) malloc(sizeof(phon_t)))) { @@ -351,14 +370,14 @@ int meta_init(void) 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; } @@ -373,23 +392,25 @@ int meta_init(void) return 0; } -static void recurs_free_phon(phon_t * phon) { +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) { +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]); @@ -399,11 +420,12 @@ static void recurs_free_field(field_t * field) { free(field); } -static void recurs_free_metaexpr(metaexpr_t * metaexpr) { +static void recurs_free_metaexpr(metaexpr_t * metaexpr) +{ if (metaexpr->left) { recurs_free_metaexpr(metaexpr->left); } - + if (metaexpr->right) { recurs_free_metaexpr(metaexpr->right); } @@ -411,21 +433,22 @@ static void recurs_free_metaexpr(metaexpr_t * metaexpr) { if (metaexpr->name) { free(metaexpr->name); } - + if (metaexpr->string) { free(metaexpr->string); } - + free(metaexpr); } -static void recurs_free_pattern(pattern_t * pattern) { +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]); @@ -434,20 +457,21 @@ static void recurs_free_pattern(pattern_t * pattern) { free(pattern); } -static void recurs_free_instruct(instruct_t * instruct) { +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]); @@ -462,11 +486,16 @@ static void recurs_free_instruct(instruct_t * instruct) { 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); +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); @@ -477,14 +506,16 @@ void meta_flush(void) { instructs = NULL; } -int meta_load(char * n) { - FILE * f; - char buf[BUFSIZ], *p; - +int meta_load(char *n) +{ + FILE *f; + char buf[BUFSIZ], errctx[BUFSIZ], *p; + int i = 0; + pushcontext("Loading meta file"); - sprintf(buf, "Opening file '%s'", n); - pushcontext(buf); - + sprintf(errctx, "Opening file '%s'", n); + pushcontext(errctx); + if (!(f = fopen(n, "r"))) { pushcontext(strerror(errno)); return 1; @@ -492,6 +523,8 @@ int meta_load(char * n) { popcontext(); pushcontext("Reading file"); while (fgets(buf, BUFSIZ, f)) { + sprintf(errctx, "Reading line %i", ++i); + pushcontext(errctx); if ((p = strchr(buf, '\r'))) { *p = '\0'; } @@ -499,39 +532,19 @@ int meta_load(char * n) { *p = '\0'; } meta_parse_line(buf); + popcontext(); } popcontext(); popcontext(); - - + + fclose(f); return 0; } #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); -} +/* Programme de test si on compile le meta parser indépendament du reste du projet */ void main(void) { @@ -558,7 +571,7 @@ void main(void) 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); @@ -566,17 +579,20 @@ void main(void) 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"); + 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->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->string ? pattern->expr[i]->right-> + string : "Aucune chaîne associée", pattern->expr[i]->right->type ? "Constante prédéfinie" : "Feuille"); } } @@ -584,29 +600,32 @@ void main(void) 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, " 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"); + 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; + 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 -- cgit v1.2.3