Previous Up Next

4  L’architecture de mcc

D’abord, quand on exécute mcc, il va commencer par exécuter le code qui se trouve dans le fichier main.ml.

Celui-ci lit les options de commande (-E par exemple), puis appelle l’analyseur syntaxique Ctab.translation_unit, auquel on passe l’analyseur lexical Clex.ctoken.

Le source de l’analyseur syntaxique, qui servira aussi de documentation pour la grammaire du langage C--, est dans le fichier ctab.mly. La description des tokens lexicaux est dans clex.mll.

L’analyseur syntaxique fournit un programme sous forme d’une liste de Cparse.var_declaration. Les d’une liste de var_declaration sont déclarées au début du fichier cparse.ml, comme suit:

type mon_op = M_MINUS | M_NOT | M_POST_INC | M_POST_DEC | M_PRE_INC | M_PRE_DEC (* Les operations unaires: M_MINUS: calcule l'oppose -e de e; M_NOT: calcule la negation logique ~e de e; M_POST_INC: post-incrementation e++; M_POST_DEC: post-decrementation e--; M_PRE_INC: pre-incrementation ++e; M_PRE_DEC: pre-decrementation --e. *) type bin_op = S_MUL | S_DIV | S_MOD | S_ADD | S_SUB | S_INDEX (* Les operations binaires: S_MUL: multiplication entiere; S_DIV: division entiere (quotient); S_MOD: division entiere (reste); S_ADD: addition entiere; S_SUB: soustraction entiere; S_INDEX: acces \`a un element de tableau a[i]. *) type cmp_op = C_LT | C_LE | C_EQ (* Les operations de comparaison: C_LT (less than): <; C_LE (less than or equal to): <=; C_EQ (equal): ==. *) type loc_expr = locator * expr and expr = VAR of string (* une variable --- toujours de type int. *) | CST of int (* une constante entiere. *) | STRING of string (* une constante chaine. *) | SET_VAR of string * loc_expr (* affectation x=e. *) | SET_ARRAY of string * loc_expr * loc_expr (* affectation x[e]=e'. *) | CALL of string * loc_expr list (* appel de fonction f(e1,...,en) *) (* operations arithmetiques: *) | OP1 of mon_op * loc_expr (* OP1(mop, e) denote -e, ~e, e++, e--, ++e, ou --e. *) | OP2 of bin_op * loc_expr * loc_expr (* OP2(bop,e,e') denote e*e', e/e', e%e', e+e', e-e', ou e[e']. *) | CMP of cmp_op * loc_expr * loc_expr (* CMP(cop,e,e') vaut e<e', e<=e', ou e==e' *) | EIF of loc_expr * loc_expr * loc_expr (* EIF(e1,e2,e3) est e1?e2:e3 *) | ESEQ of loc_expr list (* e1, ..., en [sequence, analogue a e1;e2 au niveau code]; si n=0, represente skip. *) type var_declaration = CDECL of locator * string (* declaration de variable de type int. *) | CFUN of locator * string * var_declaration list * loc_code (* fonction avec ses arguments, et son code. *) and loc_code = locator * code and code = CBLOCK of var_declaration list * loc_code list (* { declarations; code; } *) | CEXPR of loc_expr (* une expression e; vue comme instruction. *) | CIF of loc_expr * loc_code * loc_code (* if (e) c1; else c2; *) | CWHILE of loc_expr * loc_code (* while (e) c1; *) | CRETURN of loc_expr option (* return; ou return (e); *)

Le type locator est juste un pointeur sur des informations permettant aux fonctions Error.error et Error.warning d’afficher des message d’erreur sensés.

Le fichier cparse.ml contient aussi des fonctions utiles, comme string_of_loc_expr, qui vous permettent d’obtenir une version imprimable d’une expression C--, ce que vous pouvez utiliser en phase de débogage.

Le fichier genlab.ml contient une fonction genlab qui vous permettra de fabriquer des labels uniques, ce qui devrait être bien pratique lorsque vous émettrez des instructions de saut dans votre code assembleur.

Le fichier verbose.ml déclare une variable verbose que vous pourrez tester pour régler le niveau d’informations de débogage que vous voudrez afficher (elle vaut 1 si vous appelez mcc avec l’option -v1, 2 si avec l’option -v2, et 0 par défaut).


Previous Up Next