Bonjour,
je suis entrain de faire un une petit Compilateur en utilisant flex et bison qui doit compiler du PASCAL.
Voila je voudrai vous demandé si il y a pas une grammaire en LALR(1) pour du PASCAL que je pourrait utiliser
Merci d'avance..
Bonjour,
je suis entrain de faire un une petit Compilateur en utilisant flex et bison qui doit compiler du PASCAL.
Voila je voudrai vous demandé si il y a pas une grammaire en LALR(1) pour du PASCAL que je pourrait utiliser
Merci d'avance..
Pascal serait plus LL que LALR... mais il y a sans doute moyen de faire du LALR
je ne sais pas si tu connais Coco/R
http://www.scifac.ru.ac.za/coco/#Available
sinon avec fslex, je ferai comme cela... (attention, j'ai pris un sous-ensemble, trop long à faire sinon )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50 { open Types open Parser open Lexing } let chiffre = ['0'-'9'] let lettre = ['a'-'z''A'-'Z'] let alphanum = lettre | chiffre rule nextToken = parse |"+" |"-" |"*" |"/" |"%" |"and" |"or" |"=" |"<>" |"<=" |"<" |">=" |">" { let op = Lexing.lexeme lexbuf in BINOP(Factory.create_operator op) } |"not" { let op = Lexing.lexeme lexbuf in UNOP(Factory.create_operator op) } |"(" { OPENPAR } |")" { CLOSEPAR } |chiffre chiffre* { let nb = Lexing.lexeme lexbuf in INT(int_of_string nb) } |"true" { BOOL(true) } |"false" { BOOL(false) } |"begin" { BEGIN } |"end" { END } |":=" { ASSIGN } |"var" { VAR } |"const" { CONST } |";" { INSTR_SEP } |"," { PARAM_SEP } |"if" { IF } |"then" { THEN } |"else" { ELSE } |"while" { WHILE } |"do" { DO } |"return" { RETURN } |lettre alphanum* { let id = Lexing.lexeme lexbuf in IDENT(id) } |eof { EOF } |_ { nextToken lexbuf } { }
Bonjour
si c'est possible d'avoir une confirmation:
il reconnait l'exemple suivant: ( je n'ai pas vraiment compris )
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84 PROGRAMME : Cprogram identificateur CORPS_POGRAMME Cendprog '.' {printf("ADD0");} ; CORPS_POGRAMME : SUITE_DECLARATION ';' Cbegin SUITE_INSTRUCTION Cend ';' {printf("ADD1");} ; SUITE_INSTRUCTION : INSTRUCTION ';' SUITE_INSTRUCTION {printf("ADD2");} | INSTRUCTION ';' ; INSTRUCTION : INST_IF | SUITE_AFFECTATION ';' {printf("ADD5");} ; SUITE_DECLARATION : DECLARATION | DECLARATION SUITE_DECLARATION {printf("ADD7");} ; DECLARATION : Decvar LISTE_VAR {printf("ADD8");} | Dconst LISTE_CONST ; LISTE_CONST : LISTE_CONST ',' identificateur affect TERME {printf("ADD10");} | identificateur affect TERME {printf("ADD1");} ; LISTE_VAR : typeint LISTE_IDENTIFICATEUR ';' {printf("ADD11");} | typereal LISTE_IDENTIFICATEUR ';' {printf("ADD12");} | typechar LISTE_IDENTIFICATEUR ';' {printf("ADD13");} | typebool LISTE_IDENTIFICATEUR ';' {printf("ADD14");} ; LISTE_IDENTIFICATEUR : LISTE_IDENTIFICATEUR ',' identificateur {printf("ADD15");} | identificateur {printf("ADD16");} ; SUITE_AFFECTATION : SUITE_AFFECTATION ',' AFFECTATION {printf("ADD17");} | AFFECTATION {printf("ADD18");} ; AFFECTATION : identificateur affect EXPRESSION ';' {printf("ADD19");} ; INST_IF : Tif CONDITION Tthen SUITE_INSTRUCTION Tfinsi {printf("ADD20");} | Tif CONDITION Tthen SUITE_INSTRUCTION Tfinsi Telse SUITE_INSTRUCTION Tfinsinon {} ; CONDITION : identificateur OPL identificateur {printf("ADD21");} ; OPL : ega {printf("ADD22");} | diff {printf("ADD23");} | inf {printf("ADD24");} | infega {printf("ADD25");} | sub {printf("ADD26");} | subega {printf("ADD27");} | Tand {printf("ADD28");} | Tor {printf("ADD29");} ; EXPRESSION : identificateur OP identificateur {printf("ADD30");} ; OP : plus {printf("ADD31");} | moins {printf("ADD32");} | fois {printf("ADD33");} | divi {printf("ADD34");} | modulo {printf("ADD35");} | Tand {printf("ADD36");} | Tor {printf("ADD37");} | ega {printf("ADD38");} | diff {printf("ADD39");} | inf {printf("ADD40");} | infega {printf("ADD41");} | sub {printf("ADD42");} | subega {printf("ADD43");} ; TERME : reel {printf("ADD44");} | Tentier {printf("ADD45");} | identificateur {printf("ADD47");} ;
si quelqu'un peu donne une petite explication. (utilisant Flex et Bison)
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 PROGRAM ahmed VAR REAL a,b,2c,d; VAR INT e,f,g; VAR CHAR h,i,m,j; VAR BOOLEAN k,l,m; CONST a=m,w=555 BEGIN a:=d+h;; IF a<>b THEN a:=d+h;;; IF z==p THEN a2:=d2+h2;;ELSE o5:=l+g;;; END.
Merci d'avance
une question, es-tu "obligé" d'utiliser flex/bison ?
parce que je peux t'aider, mais ce sera long à cause de petit problème de C
alors que si tu passes en langage fonctionnel (ocaml, F#), avec ocamllex/ocamlyacc, tu as exactement l'équivalent de flex/bison mais avec un style plus propre et concis
Bonjour
Alors oui je suis obligé d'utiliser flex et bison dans le cadre d'un TP de Compilation
(J’utilise linux avec Ubuntu )
Voilà ce que j'ai réalisé jusque là
Fichier lex.l
fichier yacc.y
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 %{ #include "yacc.tab.h" int mot_r(char *s); int type_smp(char *s); int yywrap(void); %} signe [+-] blanc [" "\n\t] lettre [A-Za-z] idf {lettre}("_"|{lettre}|{chiffre})* chiffre [0-9] entier {signe}?{chiffre}+ exposant [eE][+-]?{entier} reel {entier}("."{entier})?{exposant}? nombre {reel}|{entier} comant ("(*"({idf}|({blanc})?)*"*)")* type_simple "INT"|"BOOLEAN"|"REAL"|"CHAR" mot_reserves "IF"|"THEN"|"ELSE"|"PROGRAM"|"BEGIN"|"END"|"VAR"|"CONST" %% {nombre} { ECHO; printf("c'est du Nombre\n"); return NOMBRE;} {mot_reserves} { ECHO; return(mot_r(yytext)); } [,;.=] { /*ECHO; printf("c'est du ','ou';'ou'.'ou'=':\n");*/ return(yytext[0]);} {type_simple} { /*ECHO;*/ return(type_smp(yytext)); } ">" { /*ECHO; printf("c'est du OP_RELATION\n");*/ return SUP;} ">=" { /*ECHO; printf("c'est du OP_RELATION\n");*/ return SUPEG;} "<=" { /*ECHO; printf("c'est du OP_RELATION\n");*/ return INFEG;} "<" { /*ECHO; printf("c'est du OP_RELATION\n");*/ return INF;} "==" { /*ECHO; printf("c'est du OP_RELATION\n");*/ return EGAL;} "<>" { /*ECHO; printf("c'est du OP_RELATION\n");*/ return DIF;} "AND"|"and" { /*ECHO; printf("c'est du OP_LOGIQUE\n");*/ return(OP_AND);} "OR"|"or" { /*ECHO; printf("c'est du OP_LOGIQUE\n");*/ return(OP_OR);} "not"|"NOT" { /*ECHO; printf("c'est du OP_LOGIQUE\n");*/ return(OP_NOT);} "+" { /*ECHO;*/ return(OP_PLUS);} "-" { /*ECHO;*/ return(OP_MOINS);} "*" { /*ECHO;*/ return(OP_MULT);} "/" { /*ECHO;*/ return(OP_DIV);} "MOD"|"mod" { /*ECHO;*/ return(OP_MOD);} ":=" { /*ECHO;*/ return(AFFECT);} {blanc} { /*ECHO;*/ /* rien */ /*printf("c'est du Blanc\n");*/ } {comant} { /*ECHO; ?(* 7idf *)!?*/ /*printf("c'est du COMANTER\n");*/ return COMANT; } {idf} { ECHO; /*printf("c'est du IDF\n");*/ return IDF; } . { ECHO; printf("c'est le SINON de tout le Réste OU Erreur Lexiquale\n"); return(yytext[0]); } %% int mot_r(char *s) { if(strcmp(s,"IF")==0) return(IF); else if(strcmp(s,"ELSE")==0) return(ELSE); else if(strcmp(s,"THEN")==0) return(THEN); else if(strcmp(s,"PROGRAM")==0) return(PROGRAM); else if(strcmp(s,"BEGIN")==0) {/*fin_decl=1*/;return(Begin);} else if(strcmp(s,"END")==0) return(END); else if(strcmp(s,"VAR")==0) return(VAR); else return(CONST); } int type_smp(char *s) {if(strcmp(s,"INT")==0) return(INT); else if(strcmp(s,"CHAR")==0) return(CHAR); else if(strcmp(s,"REAL")==0) return(REAL); else return(BOOLEAN); } int yywrap(void) { return 1; }
Si c'est possible de me dire où je dois modifier la grammaire
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132 %{ #include <stdio.h> int yyerror(char *); %} %token NOMBRE %token IF %token THEN %token ELSE %token PROGRAM %token Begin %token END %token VAR %token CONST %token DO %token INT %token CHAR %token REAL %token BOOLEAN %token SUP %token SUPEG %token INFEG %token INF %token EGAL %token DIF %token OP_AND %token OP_OR %token OP_NOT %token OP_PLUS %token OP_MOINS %token OP_MULT %token OP_DIV %token OP_MOD %token AFFECT %token COMANT %token IDF %start programme %union {char chaine[256]; double valeur;} %type <chaine> corp_de_programme suite_d_declarations suite_d_instructions %type <chaine> declaration instruction inst_if liste_daffectation %type <chaine> liste_var liste_const liste_identificateur %type <chaine> affectation expression condition %type <chaine> opl op %type <valeur> terme %type <valeur> A B %left OP_PLUS OP_MOINS %left OP_MULT OP_DIV OP_MOD %% programme:PROGRAM IDF corp_de_programme {printf("ADD0");} ; corp_de_programme :suite_d_declarations Begin suite_d_instructions END '.' {printf("ADD1");} | {/*Vide MOI ajouter*/} ; suite_d_declarations :declaration {printf("ADD2");} | declaration suite_d_declarations {printf("ADD3");} ; suite_d_instructions:instruction ';' suite_d_instructions {printf("ADD4");} |instruction ';' {printf("ADD5");} ; instruction:inst_if {printf("ADD6");} |liste_daffectation {printf("ADD7");} ; declaration :VAR liste_var {printf("ADD8");} |CONST liste_const {printf("ADD9");} ; liste_const :liste_const ','IDF '=' terme {printf("ADD10");} |IDF '=' terme {printf("ADD11");} ; liste_var : INT liste_identificateur {printf("ADD12");} | REAL liste_identificateur {printf("ADD13");} | CHAR liste_identificateur {printf("ADD14");} | BOOLEAN liste_identificateur {printf("ADD15");} ; liste_identificateur :IDF ',' liste_identificateur {printf("ADD16");} | IDF ';' {printf("ADD17");} ; liste_daffectation : affectation liste_daffectation {printf("ADD18");} |affectation {printf("ADD19");} ; affectation :IDF AFFECT expression ';' {printf("ADD20");} ; inst_if :A THEN suite_d_instructions {printf("ADD21");} |B ELSE suite_d_instructions {printf("ADD22");} ; B :A THEN suite_d_instructions {printf("ADD23");} ; A :IF condition {printf("ADD24");} ; condition : IDF opl IDF {printf("ADD25");} opl :SUP {printf("ADD26");} |SUPEG {printf("ADD27");} |INFEG {printf("ADD28");} |INF {printf("ADD29");} |EGAL {printf("ADD30");} |DIF {printf("ADD31");} |OP_OR {printf("ADD32");} |OP_NOT {printf("ADD33");} |OP_AND {printf("ADD34");} ; expression :IDF op IDF {printf("ADD35");} ; op :OP_PLUS {printf("ADD36");} |OP_MOINS {printf("ADD37");} |OP_MULT {printf("ADD38");} |OP_DIV {printf("ADD39");} |OP_MOD {printf("ADD40");} |OP_OR {printf("ADD41");} |OP_NOT {printf("ADD42");} |OP_AND {printf("ADD43");} |SUP {printf("ADD44");} |SUPEG {printf("ADD45");} |INFEG {printf("ADD46");} |INF {printf("ADD47");} |EGAL {printf("ADD48");} |DIF {printf("ADD49");} ; terme :NOMBRE {printf("ADD50");} |IDF {printf("ADD51");} ; %% int yyerror(char *s) { printf("<<< \n %s \n", s); } int main(void) { if (yyparse() == 0) printf(" Expression correcte\n"); }
pour qu'elle reconnaisse du PASCAL surtout au niveau des ";"
Cette grammaire reconnait le langage suivant: (qui est mélange de C et PASCAL)
Pour l'exécution:
j'ai tester et il reconnée comme exemple le programme suivant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 bison -d yacc.y flex lex.l gcc lex.yy.c yacc.tab.c -o lexyacc ./lexyacc
Et aussi si c'est possible quelques indications sur la sémantique que je n'ai pas commencer.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 PROGRAM idantifiant VAR REAL a,b,d; VAR INT e,f,g; VAR CHAR h,i,m,j; VAR BOOLEAN k,l,m; CONST a=m,w=555 BEGIN a:=d+h;; IF a<>b THEN a:=d+h;;; IF z==p THEN a2:=d2+h2;;ELSE o5:=l+g;;; END.
Merci d'avance.
dans un premier temps, si tu veux un peu de lecture (cours en français)
http://quincy.inria.fr/data/courses/itlp/
je regarderai le code plus tard
Bonjour,
voila j'ai un problème avec le yyin
il marche mais il ne parce pas le fichier voulu
il fait comme si je ne lui avais pas changer l'entre standar vers mon fichier !!?
j'ai test avec ce code c'est la même chause:
voila le main() du code que moi jutilise:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 int main(int argc, char * argv[]) { if(argc > 1) yyin=fopen( argv[1], "r"); else yyin= stdin; yyparse(); if (argc > 1) { fclose ( yyin ) ; } return( 0 ) ; }
si quelle que peu m'aider
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 int main(void) { FILE *yyin; printf("donner le nom [ le chemin si le repertoire est <>] du fichie\n\n=>"); scanf("%s", prog); if(!(yyin=fopen(prog, "rt"))) { printf("FAUX yyin=fopen(prog, r);= et prog=%s", prog); /*exit(0);*/ } printf("VRAIS yyin=fopen(prog, r);= et prog=%s", prog); if(yyin==NULL){puts("fichier introuvable");getchar(); } if(yyparse()!=0) { fclose(yyin); yyerror("programme incorrect syntaxiquement"); getchar(); } fclose(yyin); ....
Merci d'avance.
désolé, je n'ai pas eu le temps de regarder le code d'avant
ici, ton problème vient de la définition de yyin qui est faite dans la libfl, et donc de sa déclaration dans ton programme qui doit être extern
je te conseille de regarder ceci : http://www.ensta.fr/~vallee/cours/in104/flex-bison.zip
c'est un petit exemple d'utilisation de flex/bison sur un pseudo micro-prolog
Merci sa Marche
je voudrai savoire c'est quoi libfl
je vais voire ton exemple.la définition de yyin qui est faite dans la libfl
Merci d'avance
pour compiler tu faiscela signifie une liaison statique avec la bibliothèque fl et donc sous unix avec le fichier libfl.a
Code : Sélectionner tout - Visualiser dans une fenêtre à part gcc -lfl ...
OK
Re_Merci
A+
Bonjour,
Dans mon min compilateur j’ai réaliser la fonction prédéfinit à ce compilateur les deux fonctions READ() et WRITE() avec un(1) paramètre chacune.
Au début pour la fonction READ(); j’ai fait à l’intérieur un simple scanf(); et pour WRITE(); un simple printf();
Mais c’est comme si je mélanger la compilation à l’exécution (ce qui fait que lorsque je lui donne un fichier en avec yyin il ne va pas analyser tout le fichier il s’arrêter à la premier fonction rencontré).
Le but c’est qu’à la génération de code Objet (en Assembleur) que tout ce passe le READ et la WRITE c.à.d : à l’exécution.
Mais alors que faire d’ente met fonction READ() et WRITE() sachant que j’ai réaliser la génération de code intermédiaire en Quadrupler est pour la fonction scanf() ; je l’es interpréter comme une affectation simple.
Merci d’avance.
as-tu construit ton Arbre de Syntaxe Abstraite (AST) ?
Bonjour,
je n'est pas utiliser les AST (Arbre de Syntaxe Abstraite) comme code intermédiaire à généré j'ai utiliser les Quadrupler:
Exemple: qui marche dans mon compilou..
Avec le résultat de se code en utilisant la forme intermédiaire en Quadrupler:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 PROGRAM calcul; CONST C=2,G='ZERO',H=7 VAR A,B:INT; VAR D,E:CHAR; BEGIN A:=0;; (*initialisation*) READ(B);; WHILE A<B DO A:=A+1;;; (* Pour sortie de la Boucle ou d'un if en fait 3";;" *) B:=B-C;; WRITE(A);; WRITE(B);; END.
Ben sur je fait les vérification Sémantique comme la compatibilité de type et si la variable et déclaré ou pas .....
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 /* *************Explication des Quadrupler************ */ 0 -( :=, 0, , A ) /* A:=0;; */ 1 -( BL, 4, A, B ) /* Test de la condition du WHILE A<B (Binére:(BL, <)) Si c'est correcte en va a 4 Sinon à 2 dans notre cas A:=0;; ET B=2;; A<B est Correcte dans Temp_condition_while=1 Alors en vas à 4 */ 2 -( :=, 0, , Tempf ) /* dans ces cas: le Temporaire qui contiens la valeur Booléen de la condition (cas faux)*/ 3 -( BR, 5, , ) /* Branchement vers 5 */ 4 -( :=, 1, , Tempv ) /* Affectation au Temporaire que la condition est correcte */ 5 -( BNZ, 7, 1, ) /* d'après le Résulta Booléenne de la condition (qui est dans le Tamp == à la valeur de 3em Position sur le Quadrupler ) (Unére:(BNZ, <>0) test val condition) et Branche vers 7 si correct au suivant Sinon. (dans notre cas la valeur du 3em position de ce Quoide ==1 donc condition correct en va Brancher sur 7 ) */ 6 -( BR, 10, , ) /* Sinon en Branche vers la Fin en cas de Sorti de Boucle */ 7 -( +, A, 1, m_temp ) /* les instruction ( dans le Corps de le boucle) à l'intérieur de la Boucle*/ 8 -( :=, 1, , A ) /* l'affectation de A:=A+1;;; */ 9 -( BR, 1, , ) /* EN fait une Boucle rebranché vers la condition du While */ 10 -( -, B, C, m_temp ) /* instruction à prés la sortie de la Boucle (B-C) sachant que en à fait READ(B);; je lui B=77 */ 11 -( :=, 75, , B ) /* ce qui fait que le résulta qui doit être affecte à B est 77-2 (C=2 de la CONST) et B:=75 */ /* ******************************************************* */
et je panse qu'il est plus facile de généré du code objet (Assembleur) avec les quadrupler.
si il est possible de données quelle que ides.
Merci d’avance.
si j'ai ben comprit
Le principe est de générer du code source assembleur (qui n'est que du texte pur) dans un fichier, et de le confier ensuite à un traducteur (as, par exemple) qui générera le code machine
je ne comprant pas pour quoi
ta pas une solution avec les Quoidrupler
et pour mon probléme de la fonction READ() et WRITE()
SI tu peu merciEnvoyé par bilred
si non tu me le dite
Bonjour
je suis entrain de faire un une petit Compilateur en utilisant flex et bison qui doit compiler du PASCAL.
est ce que il y a quelqu'un qui un projet fonctionnel sur lequel je peux basé
merci
Vous avez un bloqueur de publicités installé.
Le Club Developpez.com n'affiche que des publicités IT, discrètes et non intrusives.
Afin que nous puissions continuer à vous fournir gratuitement du contenu de qualité, merci de nous soutenir en désactivant votre bloqueur de publicités sur Developpez.com.
Partager