%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
typedef struct {
char* from;
char input;
char* to;
} Transition;
Transition* transitions = NULL;
int transition_count = 0;
bool initial_declared = false;
bool final_declared = false;
void check_deterministic() {
for (int i = 0; i < transition_count; i++) {
for (int j = i + 1; j < transition_count; j++) {
if (strcmp(transitions[i].from, transitions[j].from) == 0 &&
transitions[i].input == transitions[j].input) {
yyerror("Automate non-déterministe : transition multiple pour le
même état et symbole");
}
}
}
}
void add_transition(const char* from, char input, const char* to) {
transitions = realloc(transitions, (transition_count + 1) *
sizeof(Transition));
transitions[transition_count].from = strdup(from);
transitions[transition_count].input = input;
transitions[transition_count].to = strdup(to);
transition_count++;
}
extern FILE *yyin;
extern int yylex(void);
void yyerror(const char *s) {
fprintf(stderr, "Erreur: %s\n", s);
exit(1);
}
%}
%union {
char *str;
}
%token INITIAL FINAL INIT_FINAL FIN_AUTOMATE
%token DEUX_POINTS POINT_VIRGULE
%token ETIQUETTE_A ETIQUETTE_B
%token <str> ETAT
%start automate
%%
automate : declaration_init declaration_final liste_etats_transitions FIN_AUTOMATE
{
if (!initial_declared) yyerror("État initial manquant");
if (!final_declared) yyerror("État final manquant");
check_deterministic();
printf("Automate déterministe valide.\n");
/* Nettoyage */
for (int i = 0; i < transition_count; i++) {
free(transitions[i].from);
free(transitions[i].to);
}
free(transitions);
}
;
declaration_init : ETAT DEUX_POINTS INITIAL POINT_VIRGULE
{
if (initial_declared) yyerror("État initial déjà déclaré");
initial_declared = true;
printf("État initial: %s\n", $1);
free($1);
}
| ETAT DEUX_POINTS INIT_FINAL POINT_VIRGULE
{
if (initial_declared) yyerror("État initial déjà déclaré");
if (final_declared) yyerror("État final déjà déclaré");
initial_declared = final_declared = true;
printf("État initial et final: %s\n", $1);
free($1);
}
;
declaration_final : ETAT DEUX_POINTS FINAL POINT_VIRGULE
{
if (final_declared) yyerror("État final déjà déclaré");
final_declared = true;
printf("État final: %s\n", $1);
free($1);
}
;
liste_etats_transitions : etat_avec_transitions
| liste_etats_transitions etat_avec_transitions
;
etat_avec_transitions : declaration_etat
| declaration_etat liste_transitions
;
declaration_etat : ETAT POINT_VIRGULE
{
printf("État: %s\n", $1);
free($1);
}
;
liste_transitions : transition
| liste_transitions transition
;
transition : ETIQUETTE_A ETAT POINT_VIRGULE
{
printf("Transition a -> %s\n", $2);
add_transition($1, 'a', $2);
free($1); free($2);
}
| ETIQUETTE_B ETAT POINT_VIRGULE
{
printf("Transition b -> %s\n", $2);
add_transition($1, 'b', $2);
free($1); free($2);
}
;
%%
int main(int argc, char *argv[]) {
if (argc < 2) {
fprintf(stderr, "Usage: %s fichier_automate\n", argv[0]);
return 1;
}
yyin = fopen(argv[1], "r");
if (!yyin) {
perror("Erreur d'ouverture du fichier");
return 1;
}
initial_declared = final_declared = false;
transitions = NULL;
transition_count = 0;
if (yyparse() == 0) {
printf("Analyse terminée avec succès.\n");
}
fclose(yyin);
return 0;
}