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

Langage Perl Discussion :

Pb Grammaire récursive


Sujet :

Langage Perl

  1. #1
    Membre à l'essai
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2016
    Messages : 39
    Points : 23
    Points
    23
    Par défaut Pb Grammaire récursive
    C'est fou ,tout ce que l'on peut faire en quelques lignes de Perl6 ...


    Mon code :
    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
    #!/opt/rakudo-star-2016.10/bin/perl6
    use v6;
    #use Grammar::Tracer;
     
    grammar NVL {
     
        rule  TOPNVL    { <main>* <textfin> }
          rule  main   { <text>  <nvl> }
            regex text     {:s .+?}
            rule  nvl    {:i  <nvltxt> <paraIn> <expr1> <comma> <expr2> <paraOut> }
              regex expr1     {:s .+?}
              regex expr2     {<nvl>|<expr2txt> }
              regex expr2txt     {.+?}
          regex textfin     {:s .+ }
          regex comma   {',' }
          regex paraIn  {'('}
          regex nvltxt {:i 'nvl'\s* }
          regex paraOut {')'}
          token ws { <!ww> }
    }
     
    ### Parsing
    my $cbl = "select nvl(toto,nvl(titi,tata) ) from dual ";
    say NVL.parse($cbl, rule => 'TOPNVL');
    -bash-4.2$
    le resultat :
    「select nvl(toto,nvl(titi,tata) ) from dual 」
    main => 「select nvl(toto,nvl(titi,tata)」
    text => 「select 」
    nvl => 「nvl(toto,nvl(titi,tata)」
    nvltxt => 「nvl」
    paraIn => 「(」
    expr1 => 「toto」
    comma => 「,」
    expr2 => 「nvl(titi,tata」
    expr2txt => 「nvl(titi,tata」
    paraOut => 「)」
    textfin => 「 ) from dual 」

    Le pb, c'est que cela ne marche pas.

    on a
    main => 「select nvl(toto,nvl(titi,tata)」
    au lieu de
    main => 「select nvl(toto,nvl(titi,tata))

    Il manque une parenthèse fermante (que je retrouve dans textfin) ... du coup nvl(titi,tata ne peut pas correspondre à la régle nvl ...

    Mais je bloque sur la façon de garder cette parenthèse fermante dans le main...
    J'ai peur qu'il s'agisse d'un problème de conception de ma grammaire.
    Voilà, si vous avez une idée...

    Merci pour votre aide.
    Bien cordialement,

  2. #2
    Membre à l'essai
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2016
    Messages : 39
    Points : 23
    Points
    23
    Par défaut
    Bon, finalement, comme je ne pense pas, je puisse transférer la parenthèse fermante dans main, j'ai pris le partie de gérer cette situation en ajoutant une régle à ma grammaire pour identifier une fonction nvl sans paranthèse fermante ...

    Cela donne :

    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
    #!/opt/rakudo-star-2016.10/bin/perl6
    use v6;
    use Grammar::Tracer;
     
    grammar NVL {
     
        rule  TOPNVL    { <main>* <textfin> }
          rule  main   { <text>  <nvl> }
            regex text     {:s .+?}
            rule  nvl    {:i  <nvltxt> <paraIn> <expr1> <comma> <expr2> <paraOut> }
            rule  nvlinside   {:i  <nvltxt> <paraIn> <expr1> <comma> <expr2> }
              regex expr1     {:s .+?}
              regex expr2     {<nvlinside>|<expr2txt> }
              regex expr2txt     {.+?}
          regex textfin     {:s .+ }
          regex comma   {',' }
          regex paraIn  {'('}
          regex nvltxt {:i 'nvl'\s* }
          regex paraOut {')'}
          token ws { <!ww> }
    }
     
    ### Parsing
    my $cbl = "select nvl(toto,nvl(titi,tata) ) from dual ";
    say NVL.parse($cbl, rule => 'TOPNVL');

    Le résultat :

    「select nvl(toto,nvl(titi,tata) ) from dual 」
    main => 「select nvl(toto,nvl(titi,tata)」
    text => 「select 」
    nvl => 「nvl(toto,nvl(titi,tata)」
    nvltxt => 「nvl」
    paraIn => 「(」
    expr1 => 「toto」
    comma => 「,」
    expr2 => 「nvl(titi,tata」
    nvlinside => 「nvl(titi,tata」
    nvltxt => 「nvl」
    paraIn => 「(」
    expr1 => 「titi」
    comma => 「,」
    expr2 => 「tata」
    expr2txt => 「tata」
    paraOut => 「)」
    textfin => 「 ) from dual 」


    Voilà pb résolu, désolé pour le dérangement ...

    Bien cordialement,

  3. #3
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonsoir,

    je ne suis pas sûr de ce que tu cherches à capturer exactement, ni des variations possibles dans ta cible à analyser, mais voici un exemple qui me paraît faire ce que tu désires en utilisant une définition récursive de nvl et un nombre de lignes de Perl 6 encore plus faible.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    grammar NVL2 {
        regex TOP { <start-text>? <nvl> <end-text>? }
        rule nvl  { :i  nvl \s* '(' <-[()]>+? <nvl>* ')' \s* }
        regex start-text { ^ .+? }
        regex end-text   { .+? $ }
    }
    Ce qui, avec ta chaîne en entrée, me donne l'objet reconnu suivant:

    「select nvl(toto,nvl(titi,tata) ) from dual 」
    start-text => 「select 」
    nvl => 「nvl(toto,nvl(titi,tata) ) 」
    nvl => 「nvl(titi,tata) 」
    end-text => 「from dual 」

  4. #4
    Membre à l'essai
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2016
    Messages : 39
    Points : 23
    Points
    23
    Par défaut
    Bonjour,

    Je m'apercois que j'ai oublié de répondre à ta dernière proposition.Faut dire que la grippe ne m'en a pas vraiment laisser l'occasion
    Cette nouvelle syntaxe est effectivement intéressante. Notamment parce que la partie "end-text => correspond bien à la fin de l'ordre sql.
    Par contre, il me faut extraire également les arguments de la fonction nvl afin pouvoir les utiliser par ailleurs. Je ne vois pas comment les extraire avec cette syntaxe...

    Merci beaucoup pour ton aide.
    Bien cordialement,

  5. #5
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    avec cette grammaire modifiée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    grammar NVL2 {
        regex TOP { <start-text>? <nvl> <end-text>? }
        rule nvl  { :i  nvl \s* '(' <mot> ',' [<mot>|<nvl>] ')' \s* }
        rule mot  { <-[()]>+? }
        regex start-text { ^ .+? }
        regex end-text   { .+? $ }
    }
    j'obtiens ceci:

    「select nvl(toto,nvl(titi,tata) ) from dual 」
    start-text => 「select 」
    nvl => 「nvl(toto,nvl(titi,tata) ) 」
    mot => 「toto」
    nvl => 「nvl(titi,tata) 」
    mot => 「titi」
    mot => 「tata」
    end-text => 「from dual 」

    Mais peut-être que cette grammaire plus flexible correspondrait mieux à ton besoin:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    grammar NVL2 {
        regex TOP { <start-text>? <nvl> <end-text>? }
        rule nvl  { :i  nvl \s* '(' [<mot>|<nvl>] ',' [<mot>|<nvl>] ')' \s* }
        rule mot  { <-[()]>+? }
        regex start-text { ^ .+? }
        regex end-text   { .+? $ }
    }
    dans le cas ou le premier argument d'une nvl serait lui-même une nvl imbriquée comme c'est déjà le cas pour le second argument de la nvl de ton exemple.

    Par exemple, cela marche aussi avec cette chaîne en entrée: "select nvl(nvl(tutu,tata),nvl(titi,tata) ) from dual ":

    「select nvl(nvl(tutu,tata),nvl(titi,tata) ) from dual 」
    start-text => 「select 」
    nvl => 「nvl(nvl(tutu,tata),nvl(titi,tata) ) 」
    nvl => 「nvl(tutu,tata)」
    mot => 「tutu」
    mot => 「tata」
    nvl => 「nvl(titi,tata) 」
    mot => 「titi」
    mot => 「tata」
    end-text => 「from dual 」

    Il serait peut-être souhaitable de rendre la règle mot plus restrictive, par exemple que des lettres, des chiffres ou caractères souligné avec { \w+? }, mais je ne connais pas les variations possibles de tes données en entrée.

  6. #6
    Membre à l'essai
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2016
    Messages : 39
    Points : 23
    Points
    23
    Par défaut
    Effectivement, avec ces 2 dernières versions de grammaire, on a la valeur des arguments et une fin d'ordre qui a du sens là, C'est intéressant car cela va me permettre de transformer nvl (expr1,nvl(expr2,expr3)) en coalesce ( expr1,expr2, expr3).
    (Dans le cas du nvl, cela n'a pas trop de sens que le 1er argument soit aussi un nvl, mais je retiens la façon de faire. J'ai d'autre cas ou cela va être utile)

    Encore merci ...
    Bien cordialement,

  7. #7
    Rédacteur/Modérateur

    Avatar de Lolo78
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Mai 2012
    Messages
    3 612
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2012
    Messages : 3 612
    Points : 12 469
    Points
    12 469
    Billets dans le blog
    1
    Par défaut
    Bonsoir,

    Citation Envoyé par jeepc Voir le message
    (Dans le cas du nvl, cela n'a pas trop de sens que le 1er argument soit aussi un nvl, mais je retiens la façon de faire. J'ai d'autre cas ou cela va être utile)
    Je ne savais pas ce que signifiait nvl (et pourtant, on a des bases Oracle au boulot, mais, bon, c'est assez rare que je fasse quelque chose dessus).

    Du coup, j'ai "googlé" et, effectivement, si j'ai bien compris, ça n'a sans doute pas trop de sens pour le premier argument.

    Bonne soirée.

  8. #8
    Membre à l'essai
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Octobre 2016
    Messages
    39
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Octobre 2016
    Messages : 39
    Points : 23
    Points
    23
    Par défaut
    Mais, cela va avoir du sens pour d'autres fonctions propriétaire Oracle comme Decode(), par exemple, le but étant de traduire ces fonctions en fonctions SQL standard.

    Donc, cela va mettre très utile.
    Merci encore.
    Bien cordialement,

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

Discussions similaires

  1. problème que je n'arrive pas à résoudre de façon récursive
    Par miam dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 31/07/2004, 11h21
  2. Décomposition d'une propriété : grammaire ?
    Par mathieu dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 04/05/2004, 09h47
  3. Procédure Récursives
    Par DocCoinCoin dans le forum Algorithmes et structures de données
    Réponses: 8
    Dernier message: 30/10/2002, 19h27
  4. Réponses: 2
    Dernier message: 21/05/2002, 10h25

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