aplat

Documents structurés pour Unix
git clone git://git.asteride.xyz/~ldp/aplat.git
Journaux | Fichiers | Références | LISEZ-MOI | LICENCE

commit df3adb557251edd49fdd00f05387e9454cdf9229
parent e5df96e2c5bcec6769c861fcc299dc86fd40ab64
Auteur: Selve <selve@asteride.xyz>
Date:   Sat, 18 Nov 2023 16:41:24 -0500

désentremêlage des analyses lexicale et syntaxique

Diffstat:
Maplat.c | 202+++++++++++++++++++++++++++++++++++++++++++------------------------------------
1 file changed, 110 insertions(+), 92 deletions(-)

diff --git a/aplat.c b/aplat.c @@ -12,10 +12,18 @@ #define DRAP_PARG 01 #define DRAP_PARD 02 +#define TP_TYPE_ETQ 0 +#define TP_TYPE_TXT 1 + +#define JT_PARG 0 +#define JT_PARD 1 +#define JT_FICT 2 +#define JT_ATOM 3 + void utilisation(void); int transformer(FILE *); +int prch_jeton(FILE *, struct tampon *, int); int afficher_ligne(struct tampon *, struct tampon *, int *); -int manger_espaces(FILE *); int guillemets(FILE *, struct tampon *); char *nom_prog; /* nom du programme */ @@ -50,10 +58,8 @@ utilisation(void) printf("UTILISATION: %s <[fichier]\n", nom_prog); } -int -transformer(FILE *f) +int transformer(FILE *f) { - int c; int prfd; /* profondeur */ int draps; /* drapeaux */ @@ -62,85 +68,60 @@ transformer(FILE *f) prfd = 0; draps = 0; - if ((c = manger_espaces(f)) == EOF) + switch (prch_jeton(f, &etq, TP_TYPE_ETQ)) { + case JT_PARG: + break; + case EOF: return 0; - if (c != '(') { + default: fprintf(stderr, "%s: le premier caractère affichable doit être « ( »\n", nom_prog); return -1; } - + ouv: prfd++; tp_ecr(':', &etq); - if ((c = manger_espaces(f)) == EOF) + switch (prch_jeton(f, &etq, TP_TYPE_ETQ)) { + case JT_PARG: + draps |= DRAP_PARG; + afficher_ligne(&etq, &txt, &draps); + goto ouv; + case JT_PARD: + draps |= DRAP_PARG | DRAP_PARD; + afficher_ligne(&etq, &txt, &draps); + goto ferm; + case JT_FICT: + draps |= DRAP_PARG; + afficher_ligne(&etq, &txt, &draps); + tp_ecr('\\', &etq); + goto ouv; + case JT_ATOM: + draps |= DRAP_PARG; + goto val; + case EOF: goto deseq; - - do { - switch (c) { - case ' ': case '\t': case '\n': - draps |= DRAP_PARG; - goto val; - case '(': - draps |= DRAP_PARG; - afficher_ligne(&etq, &txt, &draps); - goto ouv; - case ')': - draps |= DRAP_PARG | DRAP_PARD; - afficher_ligne(&etq, &txt, &draps); - goto ferm; - case '"': - if (guillemets(f, &etq) == EOF) - goto deseq; - continue; - case '\\': - if ((c = getc(f)) == EOF) - goto deseq; - if (c == '\\') - tp_ecr('\\', &etq); - tp_ecr(c, &etq); - continue; - case ':': - draps |= DRAP_PARG; - afficher_ligne(&etq, &txt, &draps); - prfd++; - tp_ecr('\\', &etq); - default: - tp_ecr(c, &etq); - } - } while ((c = getc(f)) != EOF); - goto deseq; + } + assert(0); val: - do { - switch (c) { - case ' ': case '\t': case '\n': - continue; - case '(': - afficher_ligne(&etq, &txt, &draps); - goto ouv; - case ')': - draps |= DRAP_PARD; - afficher_ligne(&etq, &txt, &draps); - goto ferm; - case '"': - if (guillemets(f, &txt) == EOF) - goto deseq; - break; - case '\\': - if ((c = getc(f)) == EOF) - goto deseq; - if (c == '\\') - tp_ecr('\\', &txt); - /* CASCADE */ - default: - tp_ecr(c, &txt); - } - } while ((c = getc(f)) != EOF); - goto deseq; + switch (prch_jeton(f, &txt, TP_TYPE_TXT)) { + case JT_PARG: + afficher_ligne(&etq, &txt, &draps); + goto ouv; + case JT_PARD: + draps |= DRAP_PARD; + afficher_ligne(&etq, &txt, &draps); + goto ferm; + case JT_ATOM: + goto val; + case EOF: + goto deseq; + } + assert(0); ferm: if (--prfd == 0) @@ -154,23 +135,22 @@ ferm: goto fin; } - if ((c = manger_espaces(f)) == EOF) - goto deseq; - switch (c) { - case '(': + switch (prch_jeton(f, &txt, TP_TYPE_TXT)) { + case JT_PARG: goto ouv; - case ')': + case JT_PARD: draps |= DRAP_PARD; afficher_ligne(&etq, &txt, &draps); goto ferm; - default: + case JT_ATOM: goto val; + case EOF: + goto deseq; } - - goto val; + assert(0); fin: - switch (manger_espaces(f)) { + switch (prch_jeton(f, &etq, TP_TYPE_ETQ)) { case EOF: return 0; case '(': case ')': @@ -188,13 +168,64 @@ deseq: } int +prch_jeton(FILE *f, struct tampon *tp, int tp_type) +{ + int c; + + assert(f != NULL); + assert(tp != NULL); + assert(tp_type == TP_TYPE_ETQ || tp_type == TP_TYPE_TXT); + + while ((c = getc(f)) == ' ' || c == '\n' || c == '\t') + if (c == EOF) + return EOF; + + switch (c) { + case '(': + return JT_PARG; + case ')': + return JT_PARD; + } + + do { + switch (c) { + case ' ': case '\t': case '\n': + return JT_ATOM; + case '(': case ')': + ungetc(c, f); + return JT_ATOM; + case '"': + if (guillemets(f, tp) == EOF) + return EOF; + continue; + case ':': + if (tp_type == TP_TYPE_ETQ) { + tp_ecr('\\', tp); + tp_ecr(':', tp); + return JT_FICT; + } + tp_ecr(':', tp); + case '\\': + if ((c = getc(f)) == EOF) + return EOF; + if (c == '\\') + tp_ecr('\\', tp); + /* CASCADE */ + default: + tp_ecr(c, tp); + } + } while ((c = getc(f)) != EOF); + return EOF; +} + +int afficher_ligne(struct tampon *etq, struct tampon *txt, int *draps) { assert(etq != NULL); assert(txt != NULL); assert(draps != NULL); - tp_etq_aff(etq); + tp_txt_aff(etq); putc('\t', stdout); if (*draps & DRAP_PARG) putc('(', stdout); @@ -209,19 +240,6 @@ afficher_ligne(struct tampon *etq, struct tampon *txt, int *draps) } int -manger_espaces(FILE *f) -{ - int c; - - assert(f != NULL); - - while ((c = getc(f)) == ' ' || c == '\n' || c == '\t') - if (c == EOF) - break; - return c; -} - -int guillemets(FILE *f, struct tampon *tp) { int c;