Pages : 1
#1 Le 22/03/2008, à 04:09
- Splotch
Utilisation Lex/Yacc
Voila, je tente l'utilisatoin de lex/yacc.
Je souhaiterais parser un fichier que je vous passe desuite histoire que vous voyiez la gueule qu'il a :
;; Function main (main)
main ()
{
int j;
int i;
int D.1885;
# BLOCK 2, starting at line 4
# PRED: ENTRY (fallthru)
[test3.c : 4] j = 0;
[test3.c : 6] i = 0;
[test3.c : 6] goto <bb 4> (<L1>);
# SUCC: 4 (fallthru)
# BLOCK 3, starting at line 7
# PRED: 4 (true)
<L0>:;
[test3.c : 7] j = j + 1;
[test3.c : 6] i = i + 1;
# SUCC: 4 (fallthru)
# BLOCK 4, starting at line 6
# PRED: 2 (fallthru) 3 (fallthru)
<L1>:;
[test3.c : 6] if ([test3.c : 6] i <= 9) [test3.c : 6] goto <L0>; else [test3.c : 6] goto <L4>;
# SUCC: 3 (true) 6 (false)
# BLOCK 5, starting at line 10
# PRED: 6 (true)
<L3>:;
[test3.c : 10] i = i - 1;
# SUCC: 6 (fallthru)
# BLOCK 6, starting at line 9
# PRED: 4 (false) 5 (fallthru)
<L4>:;
[test3.c : 9] if ([test3.c : 9] i != 0) [test3.c : 9] goto <L3>; else [test3.c : 9] goto <L5>;
# SUCC: 5 (true) 7 (false)
# BLOCK 7, starting at line 12
# PRED: 6 (false)
<L5>:;
[test3.c : 12] switch (i)
{
[test3.c : 14] case 0: goto <L6>;
[test3.c : 17] case 1: goto <L7>;
default : goto <L9>;
}
# SUCC: 8 9 10
# BLOCK 8, starting at line 15
# PRED: 7
<L6>:;
[test3.c : 15] j = j + 1;
[test3.c : 16] goto <bb 10> (<L9>);
# SUCC: 10 (fallthru)
# BLOCK 9, starting at line 18
# PRED: 7
<L7>:;
[test3.c : 18] j = j - 1;
# SUCC: 10 (fallthru)
# BLOCK 10, starting at line 24
# PRED: 7 8 (fallthru) 9 (fallthru)
<L9>:;
[test3.c : 24] D.1885 = 0;
return D.1885;
# SUCC: EXIT
}
Pour parser, ce fichier je voudrais utiliser Lex/Yacc, que je maitrise très mal.
Pour cela, j'ai donc un fichier .lex avec les tokens de définis et le fichier .y contenant ma grammaire :
%option noyywrap
Number [0-9]
AlphaMin [a-z]
AlphaMaj [A-Z]
Alpha ({AlphaMin}|{AlphaMaj})
AlphaNum ({Alpha}|{Number})
%%
"# BLOCK" {yylval = yytext; return USELESS;}
"# PRED:" {yylval = yytext; return USELESS;}
"# SUCC:" {yylval = yytext; return USELESS;}
"(fallthru)" {yylval = yytext; return COMMSP;}
"(true)" {yylval = yytext; return COMMSP;}
"(false)" {yylval = yytext; return COMMSP;}
"ENTRY" {yylval = yytext; return ENTRY;}
"EXIT" {yylval = yytext; return EXIT;}
"int" {yylval = yytext; return INT;}
"if" {yylval = yytext; return IF;}
"goto" {yylval = yytext; return GOTO;}
"switch" {yylval = yytext; return SWITCH;}
"else" {yylval = yytext; return ELSE;}
"case" {yylval = yytext; return CASE;}
"default" {yylval = yytext; return DEFAULT;}
"return" {yylval = yytext; return RETURN;}
", starting at line" {yylval = yytext; return USELESS;}
"["{AlphaNum}*"."{AlphaNum}*" : "{Number}*"]" {yylval = yytext; return LIGNENUM;}
";; Function "{AlphaNum}*" ("{AlphaNum}*")" {yylval = yytext; return USELESS;}
{AlphaNum}*" ()" {yylval = yytext; return USELESS;}
"<bb "{Number}*">" {yylval = yytext; return USELESS;}
"(<L"{Number}*">)" {yylval = yytext; return USELESS;}
"<L"{Number}*">:;" {yylval = yytext; return USELESS;}
"<L"{Number}*">" {yylval = yytext; return USELESS;}
{AlphaNum}*"."{Number}* {yylval = yytext; return NOMVAR;}
"==" {yylval = yytext; return EGALITE;}
"!=" {yylval = yytext; return DIFF;}
">=" {yylval = yytext; return SUPEGAL;}
"<=" {yylval = yytext; return INFEGAL;}
">" {yylval = yytext; return SUP;}
"<" {yylval = yytext; return INF;}
"=" {yylval = yytext; return AFFECT;}
"+" {yylval = yytext; return PLUS;}
"-" {yylval = yytext; return MOINS;}
"*" {yylval = yytext; return FOIS;}
"/" {yylval = yytext; return DIV;}
"{" {yylval = yytext; return LACCOLADE;}
"}" {yylval = yytext; return RACCOLADE;}
"(" {yylval = yytext; return LPARENT;}
")" {yylval = yytext; return RPARENT;}
";" {yylval = yytext; return POINTVIRGULE;}
":" {yylval = yytext; return DEUXPOINTS;}
{Number}* {yylval = yytext; return NUMBER;}
{Alpha}* {yylval = yytext; return ALPHA;}
%%
#include <stdio.h>
#include <stdlib.h>
%{
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define YYSTYPE char*
%}
%token USELESS COMMSP LIGNENUM
%token ENTRY EXIT
%token INT
%token IF SWITCH ELSE CASE DEFAULT
%token GOTO RETURN NOMVAR
%token EGALITE DIFF SUPEGAL INFEGAL SUP INF
%token AFFECT PLUS MOINS FOIS DIV
%token LACCOLADE RACCOLADE LPARENT RPARENT POINTVIRGULE DEUXPOINTS
%token NUMBER ALPHA
%%
statement: cfg;
cfg:
USELESS USELESS LACCOLADE Initialisation Block RACCOLADE {
printf("%s", $3);
};
Initialisation:
Type NomVariable POINTVIRGULE {}
| Type NomVariable POINTVIRGULE Initialisation{};
NomVariable:
ALPHA {}
| NOMVAR {};
Type:
INT {};
Block:
USELESS NUMBER USELESS NUMBER USELESS LstSP Contexte USELESS LstSP {}
| USELESS NUMBER USELESS NUMBER USELESS LstSP USELESS Contexte USELESS LstSP {}
| USELESS NUMBER USELESS NUMBER USELESS LstSP Contexte USELESS LstSP Block {}
| USELESS NUMBER USELESS NUMBER USELESS LstSP USELESS Contexte USELESS LstSP Block {};
LstSP:
NUMBER {}
| ENTRY {}
| EXIT {}
| NUMBER COMMSP {}
| ENTRY COMMSP {}
| EXIT COMMSP {}
| NUMBER LstSP {}
| ENTRY LstSP {}
| EXIT LstSP {}
| NUMBER COMMSP LstSP {}
| ENTRY COMMSP LstSP {}
| EXIT COMMSP LstSP {};
Contexte:
Action {}
| Garde {};
Action:
LIGNENUM NomVariable AFFECT Expression POINTVIRGULE {}
| LIGNENUM NomVariable AFFECT Expression POINTVIRGULE Action {}
| LIGNENUM GOTO USELESS USELESS POINTVIRGULE {}
| LIGNENUM RETURN NUMBER POINTVIRGULE {}
| LIGNENUM RETURN NomVariable POINTVIRGULE {}
| RETURN NUMBER POINTVIRGULE {}
| RETURN NomVariable POINTVIRGULE {};
Garde:
LIGNENUM IF LPARENT LIGNENUM Comparaison RPARENT LIGNENUM GOTO USELESS POINTVIRGULE ELSE LIGNENUM GOTO USELESS POINTVIRGULE {}
| LIGNENUM SWITCH LPARENT NomVariable RPARENT LACCOLADE Case RACCOLADE {};
Case:
LIGNENUM CASE NUMBER DEUXPOINTS GOTO USELESS POINTVIRGULE {}
| LIGNENUM CASE NUMBER DEUXPOINTS GOTO USELESS POINTVIRGULE Case {}
| LIGNENUM DEFAULT DEUXPOINTS GOTO USELESS POINTVIRGULE {}
| DEFAULT DEUXPOINTS GOTO USELESS POINTVIRGULE {};
Comparaison:
Comparaison EGALITE Compar {}
| Comparaison DIFF Compar {}
| Comparaison SUPEGAL Compar {}
| Comparaison INFEGAL Compar {}
| Comparaison SUP Compar {}
| Comparaison INF Compar {}
| Compar {};
Compar:
LPARENT Comparaison RPARENT {}
| NUMBER {}
| NomVariable {};
Expression:
Expression PLUS Expr {}
| Expression MOINS Expr {}
| Expr {};
Expr:
Expr FOIS Exp {}
| Expr DIV Exp {}
| Exp {};
Exp:
LPARENT Expression RPARENT {}
| NUMBER {}
| NomVariable {};
%%
#include "lex.yy.c"
yyerror(char *s){fprintf(stderr,"%s\n",s);}
Voila, dans mon code, j'ai donc bien mes tokens et ma grammaire qui ont l'air de correctement correspondre avec mon fichier texte à parser.
Par contre, dans mon .y, lorsque je veux récupérer les données avec les $* j'obtiens en réponse le dollar demandé et les dollars suivants (ex : $2 renvoie $2 $3 $4 ...).
Mais tous les dollars ont bien l'air de bien pointer tout de même vers la bonne information, ce qui me fait dire que le code reste globalement correct.
Mais quel est l'astuce pour ne récupérer que l'information demandé (ex : $2 ne renvoie que $2) ?
Autre exemple concret :
Dans mon cas un CFG est composé d'un commentaire $1(;; Function ...), du nom de la fonction $2, d'une accolade $3, d'un phase d'initialisation $4, d'une série de bloc 5, et de la fermeture d'accoldade $6.
Si je souhaitais afficher juste l'ouverture d'accolade, j'imagine le code printf("%s", $3); dans le .y. Mais cette instruction affiche tout le code à partir de cette accolade jusqu'à la fin. (Le renvoie de l'accolade dans mon cas est bien sur totalement inutile c'est ce que je désire juste à titre d'exemple.)
Pour ceux qui le veulent j'ai fait un fichier compréssé de mes codes : splotch.free.fr/pdp.tar.gz
Merci d'avance.
Hors ligne
#2 Le 23/03/2008, à 13:03
- Splotch
Re : Utilisation Lex/Yacc
Bon je up le message pour aujourd'hui sinon je trouverais une autre solution.
Hors ligne
#3 Le 23/03/2008, à 15:10
- telliam
Re : Utilisation Lex/Yacc
mes derniers programmes en lex/yacc date un peu mais si $3 'matche' toute la fin de la ligne c'est surement qu'il y a une erreur dans ta grammaire.
"- Un intellectuel assis va moins loin qu'un con qui marche."
Maurice Biraud - Un Taxi pour Tobrouk
Michel Audiard
Hors ligne
#4 Le 24/03/2008, à 16:44
- Splotch
Re : Utilisation Lex/Yacc
Ok ben je te remercie je vais voir ce qui va pas alors.
Hors ligne
Pages : 1