Bison et Flex: exemple simple d'analyse syntaxique

Retour à la page Systèmes

Motivation

Ce mini-tutorial s'adresse à ceux qui connaissent déjà les principes de l'analyse lexicale et syntaxique, et qui ont simplement besoin d'un résumé des commandes élémentaires pour les mettre en œuvre avec Flex et Bison.

Exemple: mini-calculette

Le travail se décompose typiquement comme suit:

Ensuite tout est automatique:

Le fichier calculette.y pour Bison

Les fichiers C produits par bison s'attendent par défaut à ce que l'on ait déclaré quelque-part:

%{
#include <stdio.h>
#define YYSTYPE int
int yyparse();
int yylex();
int yyerror(char *s);
%}

//Symboles terminaux qui seront fournis par yylex()
%token ENTIER
%left PLUS
%left MOINS
%left FOIS
%left DIVISE
%token OUVRIR
%token FERMER

%%

Total: Calcul { printf("Resultat: %d\n", $1); }

Calcul: ENTIER | Add | Moins | Fois | Divise | Paren { $$ = $1; }

Paren : OUVRIR Calcul FERMER { $$ = $2; }

Add : Calcul PLUS Calcul { $$ = $1 + $3; }

Moins : Calcul MOINS Calcul { $$ = $1 - $3; }

Fois : Calcul FOIS Calcul { $$ = $1 * $3; }

Divise : Calcul DIVISE Calcul { $$ = $1 / $3; }

%%

int yyerror(char *s) {
	printf("yyerror : %s\n",s);
	return 0;
}

int main(void) {
	yyparse();
	return 0;
}

On remarquera dans la syntaxe du fichier:

Le fichier calc_flex.l pour Flex

Entre autres choses que le fichier C produit par Flex s'attend à trouver dans le fichier calculette.h produit par Bison:

%{
#include "calculette.h"
%}

%option noyywrap

blanks          [ \t\n]+
entier		[0-9]+
plus		\+
moins		\-
fois		\*
divise		\/
ouvrir		\(
fermer		\)

%%

{blanks}        { /* ignore */ }

{entier}	{ yylval = atoi(yytext); return(ENTIER); }
{plus}		{ return(PLUS); }
{moins}		{ return(MOINS); }
{fois}		{ return(FOIS); }
{divise}	{ return(DIVISE); }
{ouvrir}	{ return(OUVRIR); }
{fermer}	{ return(FERMER); }

Quelques remarques:

Tout mettre ensemble

Exemple en environnement Linux:

$ bison calculette.y --defines=calculette.h -o calculette.c
$ gcc -c -Wall calculette.c
$ flex -o calc_flex.c calc_flex.l
$ gcc -c -Wall calc_flex.c
$ gcc -Wall calculette.o calc_flex.o -o calculette

Un exemple d'expression à calculer dans un fichier valid.txt:

3*4-(7-3)

Place au test:

$ ./calculette < valid.txt 
Resultat: 8

Pour aller plus loin

Dernière modification: 18 février 2017