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

Java Discussion :

[expression] Quelle méthode choisir ?


Sujet :

Java

  1. #1
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut [expression] Quelle méthode choisir ?
    Bonjour

    J'ai un problème à résoudre et je ne sais quelle approche choisir.

    J'ai des expressions textuelles dont la syntaxe est

    constituée de [] pour dire que le contenu est optionnel et ${... pour substituer une valeur

    say ${hello} [${name}[ ${firstname}]]

    le but est de remplacer les ${...} par leur valeur.
    par exemple
    si
    hello = bonjour, name= foo, fristname=barr -> "say bonjour foo bar"
    hello = bonjour, name= foo, fristname=NULL -> "say bonjour foo" (car firstname est optionnel notez que l'espace est aussi dans le [])
    hello = bonjour, name= NULL, fristname=barr -> "say bonjour" (car name est optionnel notez que [ ${firstname}] est dans le [])
    etc.

    pour les optionnel si un des ${...} présent directement dans le [] est NULL alors le bloc n'est pas produit

    La difficulté est donc de gérer les imbrications de [] (pour le ${} une regexp ou ongl fait le taf)

    la question est donc quelle approche choisir ? un parsing avec tokenizer ? des regexps ? quelque chose de spécifique ? une lib qui fait déjà ce genre de chose ?


    merci à tous.
    JYT

  2. #2
    Rédacteur/Modérateur

    Avatar de bouye
    Homme Profil pro
    Information Technologies Specialist (Scientific Computing)
    Inscrit en
    Août 2005
    Messages
    6 840
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : Nouvelle-Calédonie

    Informations professionnelles :
    Activité : Information Technologies Specialist (Scientific Computing)
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Août 2005
    Messages : 6 840
    Points : 22 854
    Points
    22 854
    Billets dans le blog
    51
    Par défaut
    En allant voir du cote de javacc peut-etre ?
    Merci de penser au tag quand une réponse a été apportée à votre question. Aucune réponse ne sera donnée à des messages privés portant sur des questions d'ordre technique. Les forums sont là pour que vous y postiez publiquement vos problèmes.

    suivez mon blog sur Développez.

    Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the universe trying to produce bigger and better idiots. So far, the universe is winning. ~ Rich Cook

  3. #3
    Expert éminent
    Avatar de sekaijin
    Homme Profil pro
    Urbaniste
    Inscrit en
    Juillet 2004
    Messages
    4 205
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Yvelines (Île de France)

    Informations professionnelles :
    Activité : Urbaniste
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2004
    Messages : 4 205
    Points : 9 127
    Points
    9 127
    Par défaut
    Bonjour
    Merci pour la réponse

    J'ai finalement fait une grammaire ANTLR4
    J'ai ainsi un parser pour les expressions

    J'ai implémenter un Visitor qui me permet de construire un arbre représentant l'expression
    et j'ai ensuite une méthode qui évalue chaque neud en fonction de son type (texte, optional, attribute) de façon récurcive.
    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
    /**
     * Define a grammar called ExpressionDsl
     */
     
    grammar ExpressionDsl;
     
    // an expression is a list of elements
    expression	: element+;
     
    // an element is a TEXT, an attribute, or an optional
    element : TEXT | attribute | optional;
     
    //any text expected attribute or optional separator
    TEXT : ~[${}[\]]+;
     
    // a list of elements between []
    optional : '[' element+ ']';
     
    // a name between ${}
    attribute   : '${' TEXT '}';
    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
    public class Compiler
    {
     
       private ParseTree tree;
     
       private ParseTreeWalker walker = new ParseTreeWalker();
     
       private ExpressionListener listener = new ExpressionListener();
     
       private Compiler(ParseTree tree){
          this.tree = tree;
       }
     
       /**
        * Generate a compiler conform to an expression write using ExpressionDsl language.
        * @param expression String conform to ExpressionDsl.g4
        * @return a new compiler for this expression
        */
       public static Compiler generate(String expression){
     
          ExpressionDslLexer lexer = new ExpressionDslLexer(CharStreams.fromString(expression));
     
          CommonTokenStream tokens = new CommonTokenStream(lexer);
          ExpressionDslParser parser = new ExpressionDslParser(tokens);
          return new Compiler(parser.expression());
     
       }
     
       /**
        * Compile an environment using generated compiler to produce a conform string.
        * @param environment
        * @return new String conform to the expression created using the environment
        */
       public String compile(Map<String, String> environment){
          listener.setConf(environment);
     
          walker.walk(listener, tree);
     
          return Builder.generate(listener.getRoot());
     
       }
    }
    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
    public class ExpressionListener extends ExpressionDslBaseListener
    {
     
       private Node parent;
     
       private Node current;
     
       private Map<String, String> conf;
     
       @Override
       public void enterExpression(ExpressionContext ctx){
          parent = Node.of(ExpressionDslParser.ruleNames[ctx.getRuleIndex()]);
          current = parent;
       }
     
       @Override
       public void exitElement(ElementContext ctx){
          TerminalNode text = ctx.TEXT();
          if(null != text){
             current.addChild(new Node(TEXT, "", text.getText()));
          }
       }
     
       @Override
       public void enterAttribute(AttributeContext ctx){
          String attrName = ctx.TEXT().getText();
          current.addChild(Node.of(ExpressionDslParser.ruleNames[ctx.getRuleIndex()], attrName, getConf(attrName)));
       }
     
       @Override
       public void enterOptional(OptionalContext ctx){
          Node optional = Node.of(ExpressionDslParser.ruleNames[ctx.getRuleIndex()]);
          current.addChild(optional);
          current = optional;
       }
     
       @Override
       public void exitOptional(OptionalContext ctx){
          current = current.getParent();
       }
     
       public void setConf(Map<String, String> conf){
          this.conf = conf;
       }
     
       private String getConf(String key){
          return conf.get(key);
       }
     
       public Node getRoot(){
          return parent;
       }
     
    }
    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
    public class Builder
    {
     
       public static final String EXPRESSION = "expression";
     
       public static final String OPTIONAL = "optional";
     
       public static final String ATTRIBUTE = "attribute";
     
       public static final String TEXT = "TEXT";
     
       public static boolean hasValue(Node node){
          switch(node.getType()){
             case TEXT:
                return true;
             case ATTRIBUTE:
                return null != node.getValue();
             case OPTIONAL:
                return node.getChildren().stream().filter(n -> OPTIONAL != n.getType()).allMatch(n -> hasValue(n));
             case EXPRESSION:
                return true;
             default:
                return false;
          }
       }
     
       public static String generate(Node node){
          switch(node.getType()){
             case TEXT:
                return node.getValue();
             case ATTRIBUTE:
                return hasValue(node) ? node.getValue() : "${" + node.getName() + "}";
             case OPTIONAL:
                StringBuffer op = new StringBuffer();
                if(hasValue(node)){
                   node.getChildren().forEach(n -> op.append(generate(n)));
                }
                return op.toString();
             case EXPRESSION:
                StringBuffer ex = new StringBuffer();
                node.getChildren().forEach(n -> ex.append(generate(n)));
                return ex.toString();
             default:
                return "";
          }
     
       }
    }
    A+JYT

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

Discussions similaires

  1. Réponses: 7
    Dernier message: 11/01/2011, 18h53
  2. [XL-2003] Vitesse d'execution : quelle méthode choisir?
    Par Haoru45 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 06/07/2009, 18h32
  3. [Architecture] Quelle méthode choisir?
    Par aneugnot dans le forum Général Java
    Réponses: 2
    Dernier message: 15/05/2007, 16h56
  4. Quelle méthode choisir ? MySql, CSV,PHP
    Par redvivi dans le forum Linux
    Réponses: 1
    Dernier message: 25/12/2006, 18h38
  5. Réponses: 4
    Dernier message: 05/06/2005, 14h05

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