Une suite de caractères est lu par un analyseur lexical, et celui-ci produit une suite de symboles (unités syntaxiques, “tokens”). Ces symboles comprennent des identifiants, des mots réservés, des constantes, des délimiteurs 1), des opérateurs simples ou composés (+ - * / := , e.g., qui sont de petits mots réservés).
Pour faire cette analyse, l'analyseur lexical a besoin de trois choses :
L'analyseur syntaxique (yacc ou bison, e.g.) demande à l'analyseur lexical (lex ou flex, e.g.) de reconnaitre et passer le prochain token. Lorsqu'il s'agit d'un identifiant, le lexeur l'inscrit (si ce n'est déjà fait) dans la table des symboles avant de le transmettre. L'analyseur syntaxique complètera les informations concernant l'identifiant dans la table des symboles lorsqu'il pourra : dimensions pour un tableau, type et paramètres pour une fonction, etc.
Il y a, comme on a vu en parlant des actions, deux sortes de token :
Ce n'est pas si simple (cf. “Flex & Bison”), mais dans notre exemple on s'est contenté de supposer qu'il commence par un chiffre (et pas directement par un point),
Comment reconnaitre un commentaire style C : ”/* ... */” ?
| ( ) | groupe |
| * | 0 à n occurrences |
| + | 1 à n occurrences |
| \cup | union |
Posons
| état | lecture | état suivant |
|---|---|---|
| 1 | '/' | 2 |
| 1 | \sigma \in N = \Sigma \setminus \left\{'/'\right\} | 1 |
| 2 | '/' | 2 |
| 2 | \sigma \in M | 1 |
| 2 | '*' | 3 |
| 3 | '*' | 4 |
| 3 | \sigma \in N | 2 |
| 4 | '*' | 4 |
| 4 | '/' | Fin |
| 4 | \sigma \in M | 3 |
Donc, avec /*N^{*} nous arriverons dans l'état 3. Est-ce que \left( *^{*} \cup M N^{*} * \right)^{*} nous emmène de l'état 3 à l'état 4, d'où un simple '/' nous permettra de terminer? Non, mais presque, car il faut le faire au moins une fois. Oon voit que
Pour perspective, dans le livre “Flex & Bison” ces commentaires sont traités par un état spécifique déclenché par ”/*” . Dans cet état, on recherche ”*/” et l'on ignore presque tout: ”([^*] | \n) + | . ” – tout sauf “*”, 1..n fois.
Il est aussi donné une expression pour traiter ce cas, mais il déconseille son emploi :
/\*([^*]|\*+[^/*])*\*+/
ce qui revient (dans notre notation) à
/* \left( N \cup *^{+} M \right)^{*} *^{+} /