Analyse syntaxique

Description

ce programme permet de mettre en oeuvre une grammaire context free de type LL(1). La grammaire traité est la célebre grammaire ETF :

E -> TE'
E' -> +TE' | -TE' | eps
T -> FT'
T' -> *FT' | /FT' | eps
F -> (E) | n

Source / Exemple :


# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <ctype.h>

//Fonctions et varaiables du lexer
char Expr[200];
char lex[10];
int pos = 0;

char Getlex();
void Ungetlex();

//Pile d'analyse
//structure de donnée
typedef struct node {
        char val;
        struct node *prev;
        }Tnode;

//Déclaration de la pile
Tnode *stack = NULL;

//Fonctions utilisées avec la pile
void Push(char);
void Pop();
void DispStack();

//Fonction d'analyse syntaxique
int Syntaxe();
int IsTerminal(char);
int Ligne(char);
int Col(char);
void Erreur(int,int);
int Err = 0;

char * matrice[5][8] = {
/* (     )       *        +       -       /       n       $*/
{"TH",	"-1",	"-1",	"-1",	"-1",	"-1",	"TH",	"-1"},  //E
{"(E)",	"-1",	"-1",	"-1",	"-1",	"-1",	"n",	"-1"},  //F
{"-1",	"!",	"*FG",	"!",	"!",	"/FG",	"-1",	"!"},   //G
{"-1",	"!",	"-1",	"+TH",	"-TH",	"-1",	"-1",	"!"},   //H
{"FG",	"-1",	"-1",	"-1",	"-1",	"-1",	"FG",	"-1"}}; //T

int main() {
    Push('$');
    Push('E');
    system("cls");
    printf("\n\t\t\tTaper une xepression valide .. \t");
    gets(Expr);
    if(Syntaxe()) printf("\n\nOk ...");
    else printf("\n\nKo ... ");
//    fflush(stdin); getchar();
    return 0;
}

char Getlex(){
     int i=0;
     switch(Expr[pos]){
       case '+' : case '-' : case '*': case '$':
       case '/' : case '(' : case ')': lex[0] = Expr[pos];lex[1] = '\0';
                           pos++;
                           return Expr[pos-1];
       default : while(isdigit(Expr[pos]) || Expr[pos] == '.')
                 lex[i++] = Expr[pos++];
                 lex[i] = '\0';
                 return 'n';
     }
     }

void Ungetlex(){
     pos -= strlen(lex);
     }

//Fonctions utilisées avec la pile
void Push(char c){
     Tnode*nd = (Tnode*)malloc(sizeof(Tnode));
     nd->val = c; nd->prev = stack;
     stack = nd;
//     DispStack();
     }

void Pop(){
     DispStack();
     if(stack != NULL){
              Tnode *tnd = stack;
              stack = stack->prev;
              free(tnd);
     }
//     DispStack();
     }

//Fonction d'analyse syntaxique
int Syntaxe(){
    int i,lg,ln,col;
    char cel[4];
    char c = Getlex();
    while(stack->val != '$' && c != '$'){
         if(IsTerminal(stack->val)) {
                Pop(); printf("\tréduction");
                if(c != '$') c = Getlex();}
         else {
              ln = Ligne(stack->val);
              col = Col(c);
              strcpy(cel,matrice[ln][col]);
              if(!strcmp(cel,"-1")) {
                       Erreur(ln,col);
                       c = Getlex();
                       ln = Ligne(stack->val);
                       col = Col(c);
                       strcpy(cel,matrice[ln][col]);
                       }
              if(!strcmp(cel,"!")) Pop();
              else {
                   Pop();
                   for(i = 0 , lg = strlen(cel)-1 ; i < strlen(cel); i++)
                         Push(cel[lg--]);
                   }
              }

    }
    if(!Err) return 1;
    return 0;
}

int IsTerminal(char c){
    if(c == 'n' || c == '+' || c == '-' ||
         c == '*' || c == '/' || c == '(' ||
         c == ')' || c == '$' ) return 1;
    return 0;
    }

int Ligne(char c){
    if(c == 'E') return 0;
    if(c == 'F') return 1;
    if(c == 'G') return 2;
    if(c == 'H') return 3;
    if(c == 'T') return 4;
}

int Col(char c){
/* (     )       *        +       -       /       n       $*/
    if(c == '(') return 0;
    if(c == ')') return 1;
    if(c == '*') return 2;
    if(c == '+') return 3;
    if(c == '-') return 4;
    if(c == '/') return 5;
    if(c == 'n') return 6;
}

void Erreur(int l,int cc){
     char c = Getlex();
     Err = 1;
/* (     )       *        +       -       /       n       $
{"TH",	"-1",	"-1",	"-1",	"-1",	"-1",	"TH",	"-1"},  //E
{"(E)",	"-1",	"-1",	"-1",	"-1",	"-1",	"n",	"-1"},  //F
{"-1",	"!",	"*FG",	"!",	"!",	"/FG",	"-1",	"!"},   //G
{"-1",	"!",	"-1",	"+TH",	"-TH",	"-1",	"-1",	"!"},   //H
{"FG",	"-1",	"-1",	"-1",	"-1",	"-1",	"FG",	"-1"}}; //T

  • /
switch( l ) { case 0 : case 1 : case 4 : fprintf(stderr,"\nErreur 1 : nombre ou ( attendu "); while( c != '(' && c != 'n' ) c = Getlex(); Ungetlex(); break; case 3 : fprintf(stderr,"\nErreur 2 : +,-,),$ attendu "); while( c != '+' && c != '-' && c != ')' && c != '$' ) c = Getlex(); Ungetlex(); break; case 2 : fprintf(stderr,"\nErreur 3 : +,-,*,/,),$ attendu "); while( c =='n' || c == '(' ) c = Getlex(); Ungetlex(); break; } } void DispStack() { Tnode * st = stack; printf("\n"); while(st != NULL) { printf("%c ",st->val); st = st->prev; } }

Conclusion :


char * matrice[5][8] = {
/* ( ) * + - / n $*/
{"TH", "-1", "-1", "-1", "-1", "-1", "TH", "-1"}, //E
{"(E)", "-1", "-1", "-1", "-1", "-1", "n", "-1"}, //F
{"-1", "!", "*FG", "!", "!", "/FG", "-1", "!"}, //G
{"-1", "!", "-1", "+TH", "-TH", "-1", "-1", "!"}, //H
{"FG", "-1", "-1", "-1", "-1", "-1", "FG", "-1"}}; //T

j'attend vos commentaires

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.