IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C++ Discussion :

pour soumettre un programme dans la section code sources


Sujet :

C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 396
    Billets dans le blog
    16
    Par défaut pour soumettre un programme dans la section code sources
    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;
    };
    #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
    // 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;
    }
    je suis ouvert à toute suggestion.

  2. #2
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 122
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 122
    Billets dans le blog
    148
    Par défaut
    Bonjour,

    Dur de savoir pour la performance, vous n'expliquez pas ce que c'est sensé faire. (Et) Il y a zéro commentaire.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        switch(etat){
        case 0:
          c=carsuiv();
          if(c[0]==(char)EOF)
    	etat=1;
          else{//echec
    	enavant=debutlex;
    	return false;
          }
          break;
        case 1:
          return true;
        }
    Pas besoin d'un switch() ici.
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  3. #3
    Expert confirmé
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Décembre 2015
    Messages
    1 599
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Décembre 2015
    Messages : 1 599
    Par défaut
    Bonjour,

    L'expression c[0]==(char)EOF met un doute sur la validité de ce code.
    EOF a une valeur qui est forcément distincte de tous les caractères possibles. Donc ou bien un caractère n'est jamais géré (par exemple \377 si EOF==-1 et les char sont signés) ou bien la fin n'est pas détectée.

  4. #4
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 396
    Billets dans le blog
    16
    Par défaut
    Pourtant, ce code fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ xxd test
    00000000: 6466 670a 686a 6b0a 6c6d 0a              dfg.hjk.lm.
    $ ./a.out test resultat
    $ xxd resultat 
    00000000: 6466 670d 0a68 6a6b 0d0a 6c6d 0d0a       dfg..hjk..lm..
    comme je l'ai indiqué, c'est une version de unix2dos, à la manière d'un parseur par descente récursive predictive

  5. #5
    Membre éprouvé
    Homme Profil pro
    Admin systèmes (Windows, Linux) et réseaux - Dev DB &Java IHM calcul scientifique
    Inscrit en
    Mai 2016
    Messages
    90
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Admin systèmes (Windows, Linux) et réseaux - Dev DB &Java IHM calcul scientifique
    Secteur : Enseignement

    Informations forums :
    Inscription : Mai 2016
    Messages : 90
    Par défaut
    Citation Envoyé par emmesse Voir le message
    Pourtant, ce code fonctionne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ xxd test
    00000000: 6466 670a 686a 6b0a 6c6d 0a              dfg.hjk.lm.
    $ ./a.out test resultat
    $ xxd resultat 
    00000000: 6466 670d 0a68 6a6b 0d0a 6c6d 0d0a       dfg..hjk..lm..
    comme je l'ai indiqué, c'est une version de unix2dos, à la manière d'un parseur par descente récursive predictive
    Bonsoir,
    ça marche parce que tu appliques la conversion à un fichier ASCII 7 bits
    Cordialement

  6. #6
    Membre éclairé

    Homme Profil pro
    développeur à la maison
    Inscrit en
    Septembre 2006
    Messages
    396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : développeur à la maison

    Informations forums :
    Inscription : Septembre 2006
    Messages : 396
    Billets dans le blog
    16
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    fichier test:
    é
    è
    ÿ
    à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    $ xxd test
    00000000: c3a9 0ac3 a80a c3bf 0ac3 a00a 
    $ unix2dos test resultat
    $ xxd resultat
    00000000: c3a9 0d0a c3a8 0d0a c3bf 0d0a c3a0 0d0a  ................
    C[0] peut être négatif comme (char)EOF, qui est égal à -1
    les char sont codé sur 8 bits et peuvent donc être négatifs, comme (char)EOF, qui est égal à -1 (=FF)
    si c[0] vaut FF alors dans ce cas on a bien c[0]==(char)EOF;

Discussions similaires

  1. Réponses: 0
    Dernier message: 24/09/2022, 18h23
  2. Réponses: 3
    Dernier message: 10/01/2014, 11h18
  3. idée pour un programme qui lit le code source
    Par snoopo dans le forum Langage
    Réponses: 3
    Dernier message: 20/07/2010, 10h24

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo