Bonjour,
je voudrais mettre un code source dans la section "codes sources" du site. Mais avant, je vous le soumet pour savoir si il pourrait être plus performant.
Il s'agit d'une version unix2dos, à la manière d'un compilateur par descente récursive prédictive.
le schéma de traduction dirigé par la syntaxe est le suivant:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5 fichier -> {ligne.h=""} ligne {fichierprim.h=ligne_s} fichierprim {fichier.s=fichierprim.s} fichierprim -> retourligne {ligne.h=""} ligne {fichierprim1.h=fichierprim.h+"\r\n"+ligne.s} fichierprim1 {fichierprim.s=fichierprim1.s} -> epsilon {fichierprim.s=fichierprim.h} ligne -> caractère {ligne1.h=ligne.h+caractère} ligne1 {ligne.s=ligne1.s} -> epsilon {ligne.s=ligne.h}
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 // main.cpp #include <iostream> #include "syntaxique.hpp" int main(int argc, char *argv[]){ if(argc!=3) std::cerr<<"usage:\nuix2dos fichierentrée fichiersortie"<<std::endl; else{ syntaxique objetsyntaxique(argv[1],argv[2]); objetsyntaxique.fichier(); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 #ifndef TERMINAUX_HPP #define TERMINAUX_HPP enum terminal{FDF,retourligne,caractere}; #endif
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 #ifndef LEXICAL_HPP #define LEXICAL_HPP #include <string> #include <fstream> #include "terminaux.hpp" class lexical{ public: lexical(char* fichierentree); void analex(terminal &retourvaleur,std::string &retourattribut,int &ligne); private: std::string texte; std::ifstream entree; size_t enavant,debutlex; std::string lexeme; std::string readFileIntoString(const char* path); bool obtenir_FDF(); bool obtenir_retourligneoucaractere(int &ligne); std::string carsuiv(); }; #endif
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 //lexical.cpp #include <iostream> #include <fstream> #include <string> #include "lexical.hpp" #include "terminaux.hpp" lexical::lexical(char *fichierentree):enavant(0),debutlex(0){ entree.open(fichierentree); texte = readFileIntoString(fichierentree)+(char)EOF; enavant=0; } std::string lexical::readFileIntoString(const char* path) { if (!entree.is_open()){ std::cerr << "Could not open the file - '" << path << "'" << std::endl; exit(1); } else{ return std::string((std::istreambuf_iterator<char>(entree)), std::istreambuf_iterator<char>()); } } void lexical::analex(terminal &retourvaleur,std::string &retourattribut,int &ligne){ if(obtenir_FDF()) retourvaleur=FDF; else if(obtenir_retourligneoucaractere(ligne)) if(lexeme=="\n") retourvaleur=retourligne; else{ retourattribut=lexeme; retourvaleur=caractere; } } bool lexical::obtenir_FDF(){ debutlex=enavant; int etat=0; std::string c; while(true) switch(etat){ case 0: c=carsuiv(); if(c[0]==(char)EOF) etat=1; else{//echec enavant=debutlex; return false; } break; case 1: return true; } } bool lexical::obtenir_retourligneoucaractere(int &ligne){ debutlex=enavant; int etat=0; std::string c; while(true){ switch(etat){ case 0: c=carsuiv(); if(c=="\n") ligne++; etat=1; break; case 1: lexeme=c; return true; } } } std::string lexical::carsuiv(){ int taille; if((unsigned char)texte[enavant] >= (unsigned char)0 && texte[enavant] <= (unsigned char)127) taille=1; else if((unsigned char)texte[enavant] >= (unsigned char)0xC2 && (unsigned char)texte[enavant] <= (unsigned char)0xdf) taille=2; else if((unsigned char)texte[enavant] >= (unsigned char)0xe0 && (unsigned char)texte[enavant] <= (unsigned char)0xef) taille=3; else taille=4; std::string c=texte.substr(enavant,taille); enavant+=taille; return c; }
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 #ifndef SYNTAXIQUE_HPP #define SYNTAXIQUE_HPP #include <string> #include <vector> #include "lexical.hpp" #include "terminaux.hpp" class syntaxique{ public: syntaxique(char *fichierentree,char *fichiersortie); void fichier(); private: void consommer(terminal const &attendu); std::string ligne(std::string ligne_h); std::ofstream sortie; std::string nomfichiersortie; terminal symbole; int numligne; lexical objetlexical; std::string lexeme; }; #endifje suis ouvert à toute suggestion.
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 // syntaxique.cpp #include <string> #include <iostream> #include <fstream> #include "terminaux.hpp" #include "syntaxique.hpp" #include "lexical.hpp" /* fichier -> {ligne.h=""} ligne {fichierprim.h=ligne.s} fichierprim {fichier.s=fichierprim.s} fichierprim -> retourligne {ligne.h=fichierprim.h} ligne {fichierprim1.h=fichierprim.h+CR+LF+ligne.s} fichierprim1 {fichierprim.s=fichierprim1.s} -> epsilon {fichier.s=fichier.h} ligne -> caractere {ligne1.h=ligne.h+caractere.s} ligne1 {ligne.s=ligne1.s} -> epsilon {ligne.s=ligne.h} */ syntaxique::syntaxique(char *fichierentree,char *fichiersortie):nomfichiersortie(fichiersortie),numligne(1),objetlexical(fichierentree){ objetlexical.analex(symbole,lexeme,numligne); nomfichiersortie=fichiersortie; } void syntaxique::consommer(terminal const &attendu){ if(symbole==attendu && symbole!=FDF) objetlexical.analex(symbole,lexeme,numligne); } void syntaxique::fichier(){ std::string ligne_h=""; std::string fichierprim_h=""; if(symbole==caractere){ std::string ligne_s=ligne(ligne_h); fichierprim_h=ligne_s; while(symbole==retourligne){ consommer(retourligne); ligne_h=""; ligne_s=ligne(ligne_h); fichierprim_h+="\r\n"+ligne_s; } } else{ while(symbole==retourligne){ consommer(retourligne); ligne_h=""; std::string ligne_s=ligne(ligne_h); fichierprim_h+="\r\n"+ligne_s; } } std::string fichierprim_s=fichierprim_h; std::string fichier_s=fichierprim_s; sortie.open(nomfichiersortie.c_str()); sortie<<fichier_s; } std::string syntaxique::ligne(std::string ligne_h){ while(symbole==caractere){ std::string caractere_s=lexeme; consommer(caractere); ligne_h+=caractere_s; } std::string ligne_s=ligne_h; return ligne_s; }
Partager