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 :

Réalisation shell : comment reconnaître commandes ?


Sujet :

C

  1. #1
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut Réalisation shell : comment reconnaître commandes ?
    Bonsoir,

    Je me lance dans la réalisation d'un shell de commandes qui servira a effectuer des calculs mathématiques.

    Exemple de fonctionnement :

    Invite de commandes mathematiques.

    > A = 1 saisie utilisateur
    > B = 2 saisie utilisateur
    > A + B saisie utilisateur
    >> 3 un résultat
    Et par la suite, je pourrais rajouter en plus de ces simples assignations et opérations de bases, des fonctions arithmétiques et géométrique plus amusantes :p

    Voici à quoi ressemble mon main pour l'instant :
    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
     
    #include <stdio.h>
    #include <stdlib.h>
    #include "ed/inc/io.h"
     
     
    #define TAILLE_MAX_COMMANDE 32
     
    int main(int argc, char *argv[])
    {
        printf("Invite de commandes mathematiques.\n\n");
     
        char commande[TAILLE_MAX_COMMANDE] = {0};
        int retour = 0;
     
        for(;;)
        {
            // Affichage du promt
            printf("> ");
            fflush(stdout);
     
            // Tant que la saisie ne se fait pas sans erreur
            while ((retour = get_s(commande, sizeof commande)) != IO_OK)
            {
                // Si l'erreur est un dépassement de taille du tableau
                if (retour == IO_ERR_LENGTH)
                    printf("La commande est trop longue et ne sera donc pas traitee.\n");
     
                // Sinon, on n'analyse pas le cas par cas (inintéressant ici)
                else printf("Erreur indeterminee. La commande ne sera pas traitee.\n");
     
                // Affichage du promt
                printf("> ");
                fflush(stdout);
            }
     
            // Si la chaine saisie est "quit", on quitte le programme normalement
            if (strcmp(commande, "quit") == NULL)
                return EXIT_SUCCESS;
        }
    }
    Pour l'instant, il ne fait pas grand chose...

    Le premier problème que je me pose : comment reconnaître correctement les commandes saisies ?
    En effet, si l'utilisateur entre "A=1", "A= 1", " A = 1", le résultat devra être le même.

    J'ai imaginé un début de solution à partir de fonctions que j'ai créées pour un projet précédant :

    - lire la saisie
    - définir les caractères qui doivent impérativement être "décollés" des autres expressions (ici, c'est =)
    - compter le nombre d'espaces manquants, s'il manque des espaces
    - allouer dynamiquement une nouvelle chaine avec assez de place pour contenir des espaces en plus
    - copier la saisie en rajoutant les espaces manquants

    En gros, ce morceau fait ça :
    "A=1" devient "A = 1".

    Ensuite :
    - on peut désormais lire chaque mot indépendamment
    - on regarde si ça correspond à un "modèle" (ici LETTRE = VALEUR), et on applique la fonction (je n'ai pas encore mis en place cette partie "reconnaissance de modèle")

    Pensez-vous que je parte sur quelque chose de correct ?
    Ca me paraît long comme démarche, fastidieux.
    Comment feriez-vous pour reconnaître que la saisie appartient à un "modèle" défini ?

    Par avance, merci.

  2. #2
    Membre confirmé Avatar de Flow_75
    Femme Profil pro
    Ingénieure
    Inscrit en
    Mai 2005
    Messages
    1 096
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 40
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Ingénieure
    Secteur : Transports

    Informations forums :
    Inscription : Mai 2005
    Messages : 1 096
    Points : 633
    Points
    633
    Par défaut
    salut,

    pourquoi n'utilise pas tu le scanf ?
    tu peux faire par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf("%c %c %f", &var, & operation, &valeur)

  3. #3
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s
    Je me lance dans la réalisation d'un shell de commandes qui servira a effectuer des calculs mathématiques.

    Le premier problème que je me pose : comment reconnaître correctement les commandes saisies ?
    En effet, si l'utilisateur entre "A=1", "A= 1", " A = 1", le résultat devra être le même.
    Tout devient "A=1" : supprimmer les espaces inutiles après la saisie.

    Plouf ! Module STR : STR_DelBlanks()

    J'ai imaginé un début de solution à partir de fonctions que j'ai créées pour un projet précédant :
    <...>
    En gros, ce morceau fait ça :
    "A=1" devient "A = 1".
    Alors ça, c'est autre chose. C'est la 'normalisation'. C'est complexe si il faut agrandir la chaine. Mais ça ne sert à rien. Les séparateurs de tokens sont connus. Ce sont les opérateurs (ici, '='). Avant d'aller plus loin tu dois définir une syntaxe et une grammaire pour toutes les expressions possibles.

    Ensuite lex et yacc sont tes amis ou alors tu fais tout à la main.

    Attention, un automate d'analyse de syntaxe, c'est pas facile à faire évoluer...

    Trop cool :
    Invite de commandes mathematiques.

    > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    La commande est trop longue et ne sera donc pas traitee.
    > ^Z
    Erreur indeterminee. La commande ne sera pas traitee.
    > quit

    Press ENTER to continue.
    J'aurais écrit le code comme ça :
    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
    #include "ed/inc/io.h"
     
    #include <stdlib.h>
    #include <string.h>
     
    int main (void)
    {
       int end = 0;
       printf ("Invite de commandes mathematiques.\n\n");
     
       while (!end)
       {
          char commande[32];
          int retour = 0;
          // Affichage du promt
          printf ("> ");
          fflush (stdout);
     
          // Tant que la saisie ne se fait pas sans erreur
          while ((retour = get_s (commande, sizeof commande)) != IO_OK)
          {
             // Si l'erreur est un dépassement de taille du tableau
             if (retour == IO_ERR_LENGTH)
             {
                printf
                   ("La commande est trop longue et ne sera donc pas traitee.\n");
             }
             // Sinon, on n'analyse pas le cas par cas (inintéressant ici)
             else
             {
                printf
                   ("Erreur indeterminee. La commande ne sera pas traitee.\n");
             }
             // Affichage du promt
             printf ("> ");
             fflush (stdout);
          }
     
          // Si la chaine saisie est "quit", on quitte le programme normalement
          if (strcmp (commande, "quit") == NULL)
          {
             end = 1;
          }
       }
       return EXIT_SUCCESS;
    }
    Pas de Wi-Fi à la maison : CPL

  4. #4
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    salut,

    pourquoi n'utilise pas tu le scanf ?
    Je n'utilise pas (plus) scanf car si on ne s'en sert pas correctement (et c'est assez difficile) on doit s'attendre à des comportements imprévus.

    Tout devient "A=1" : supprimmer les espaces inutiles après la saisie.

    Plouf ! Module STR : STR_DelBlanks()
    Super, je n'avais pas encore regardé str.

    Alors ça, c'est autre chose. C'est la 'normalisation'. C'est complexe si il faut agrandir la chaine. Mais ça ne sert à rien. Les séparateurs de tokens sont connus. Ce sont les opérateurs (ici, '='). Avant d'aller plus loin tu dois définir une syntaxe et une grammaire pour toutes les expressions possibles.

    Ensuite lex et yacc sont tes amis ou alors tu fais tout à la main.

    Attention, un automate d'analyse de syntaxe, c'est pas facile à faire évoluer...
    Ok, merci de toutes ces infos Y a plus qu'à !

    Trop cool :
    Citation:
    Invite de commandes mathematiques.

    > aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
    ...
    N'est-ce pas

  5. #5
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par Flob91
    salut,

    pourquoi n'utilise pas tu le scanf ?
    tu peux faire par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    scanf("%c %c %f", &var, & operation, &valeur)
    scanf(), c'est le Démon !
    Pas de Wi-Fi à la maison : CPL

  6. #6
    Membre confirmé Avatar de Lunixinclar
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2006
    Messages
    416
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 416
    Points : 489
    Points
    489
    Par défaut
    Pour un évaluateur d'expressions mathématiques évolué (qui accepte des noms de variables) tu peux commencer par comprendre le mécanisme avec Flex/Lex/Bison
    http://www.cs.ucr.edu/~lgao/teaching/bison.html
    http://cs.uic.edu/~spopuri/cparser.html
    http://cs.wwc.edu/~aabyan/Linux/compiler/index.html
    http://www.therobs.com/uman/lexyacc.shtml
    http://docs.freebsd.org/info/bison/b...tion_Calc.html
    ... Et plus tard quand tu seras à l' aise, tout faire à la main en employant une pile ou un arbre. Les sources de certains shells sont disponibles (cf busybox qui en contient plusieurs, tous ayant le souci de rester simples).
    http://www.codepedia.com/1/Art_Expressions_p1
    http://www.arstdesign.com/articles/e...valuation.html
    C'est beaucoup de boulot... Fais chauffer google, vive le C et bonne prog.

  7. #7
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    Merci des conseils et liens.

    Quelles sont les différences entre lex/yacc et flex/lex/bison ?

  8. #8
    Expert éminent sénior
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 67
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Points : 20 985
    Points
    20 985
    Par défaut
    Citation Envoyé par odsen.s
    Quelles sont les différences entre lex/yacc et flex/bison ?
    Pas de différence, à part la licence. Le dernier est GNU, donc FSF.
    Pas de Wi-Fi à la maison : CPL

  9. #9
    Membre actif
    Avatar de odsen.s
    Profil pro
    Étudiant
    Inscrit en
    Octobre 2006
    Messages
    269
    Détails du profil
    Informations personnelles :
    Âge : 34
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2006
    Messages : 269
    Points : 243
    Points
    243
    Par défaut
    D'accord, merci.

  10. #10
    Membre averti
    Inscrit en
    Septembre 2006
    Messages
    414
    Détails du profil
    Informations forums :
    Inscription : Septembre 2006
    Messages : 414
    Points : 354
    Points
    354
    Par défaut
    tiens, c'est exactement ce que je suis entrain de faire !
    un conceil: une feuille et un stylo !
    surtout si tu compte prendre en compte les parentheses.
    avec les parentheses imbriquées, je ne voi pas d'autres solutions qu'un arbre !
    alors dessine un diagramme pour te representer tout ca !
    A mon avis (en tout cas c'est comme ca que je fais) il vau mieux commencer par de simples calculs (une calculette quoi) et ENSUITE ajouter une partie affectation pour les variables et les declarations de fonctions...
    enfin, ce n'est qu'un avis de debutant ^^

    bon courage !
    __________
    "Any sufficiently advanced technology is indistinguishable from magic" Arthur C. Clarke

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [SHELL] ligne de commande
    Par Youni_1989 dans le forum Linux
    Réponses: 5
    Dernier message: 06/11/2007, 09h54
  2. Réponses: 8
    Dernier message: 30/05/2007, 11h30
  3. Réponses: 2
    Dernier message: 30/03/2007, 21h05
  4. Réponses: 2
    Dernier message: 27/12/2005, 11h47
  5. Comment reconnaître une trame Profibus ?
    Par hasna45 dans le forum Développement
    Réponses: 4
    Dernier message: 25/10/2004, 19h53

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