/** @file evaldesc.c *@author Michel Meynard *@brief Evaluation descendante récursive d'expression arithmétique. *Chaque expression arithmétiques est composée de littéraux entiers sur un car, * des opérateurs +, * et du parenthésage (). On utilise l'associativité à * gauche : 1+2+3=(1+2)+3; 1*2*3=(1*2)*3. Soit rediriger en entrée un fichier, * soit terminer par deux caractères EOF (Ctrl-D), un pour lancer la lecture, * l'autre comme "vrai" EOF. */ #include #include #include /* les macros sont des blocs : pas de ';' apres */ #define AVANCER {jeton=getchar();numcar++;} #define TEST_AVANCE(prevu) {if (jeton==(prevu)) AVANCER else ERREUR_SYNTAXE} #define ERREUR_SYNTAXE {printf("\nMot non reconnu : erreur de syntaxe \ au caractère numéro %d, de jeton %d \n",numcar,jeton); exit(1);} #define INVITE "Veuillez saisir une expression numérique SVP (q pour quitter) : " /* déclarations en avant des fonctions */ void X();int E();int R(int g);int T();int S(int g);int F(); int jeton; int numcar=0; /* caractère courant du flot d'entrée */ /* numero du caractère courant (jeton) */ /* AXIOME */ void X(){ int r; if (jeton==-1){ /* règle : X -> EOF */ exit(0); } else if (jeton=='q'){ AVANCER; if (jeton=='\n') return; else ERREUR_SYNTAXE; } else { r=E(); if (jeton=='\n'){ printf("Mot reconnu de valeur : %d\n",r); printf(INVITE); numcar=0; AVANCER; X(); } else ERREUR_SYNTAXE; } } int E(){ return R(T()); } int R(int g){ if (jeton=='+') { AVANCER; return R(g+T()); } else return g; } int T(){ return S(F()); } int S(int g){ if (jeton=='*') { AVANCER; return S(g*F()); } else return g; } int F(){ int r; if (jeton=='(') { AVANCER; r=E(); TEST_AVANCE(')'); } else if (isdigit(jeton)) { r=jeton-'0'; AVANCER; } else ERREUR_SYNTAXE; return r; } int main(){ printf(INVITE); numcar=0; AVANCER; X(); return 0; /* ne retourne jamais que par X */ }