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:
M | aplat.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;