Expressions régulières Java !! Help !!

lolo80000 Messages postés 22 Date d'inscription mercredi 12 avril 2006 Statut Membre Dernière intervention 16 août 2012 - 23 avril 2008 à 17:35
cs_jojolemariole Messages postés 519 Date d'inscription mercredi 21 mars 2007 Statut Membre Dernière intervention 19 décembre 2016 - 23 avril 2008 à 18:02
Bonjour à tous,

Voila j'ai un peit souci que je n'arrive pas à resoudre, voila j'ai une chaine de caractère du type "65*22/12-6+2..." et j'aimerai effectuer cette opération, j'ai donc pensé à utiliser les expressions regulières pour separer la chaine par rapport aux opérateurs ! mais je n'y arrive pas.

Si vous pouviez m'aider.

Merci à tous

Laurent.

1 réponse

cs_jojolemariole Messages postés 519 Date d'inscription mercredi 21 mars 2007 Statut Membre Dernière intervention 19 décembre 2016 25
23 avril 2008 à 18:02
Je te conseillerais d'utiliser plutôt un générateur de parser, du style javacc.
lien pour windows : https://javacc.dev.java.net/files/documents/17/26777/javacc-4.0.zip

Il s'agit principalement d'un jar, d'exemples, de doc et d'un bat pour appeler le parser sans se taper la ligne de commande java -jar en entier.

Je l'ai utilisé et je ne peux que te le conseiller. Le problème c'est que pour écrire la grammaire, il te faut des connaissances en compilation. Ou alors tu trouves une grammaire toute faite qui te convient.

1) D'abord tu écris tes classes métiers. Dans ton cas c'est simple.

Tu fais une interface expression avec une méthode évaluer qui renvoit un nombre. (int, double, ... ce que tu veux)

et tu dois faire au moins 7 implémentations de cette classe. A savoir :
class ExpressionNombre implements Expression
class ExpressionAddition implements Expression
....

Bien sûr une addition aura deux attributs de type Expression.
Du coup l'implémentation de la méthode evaluer pour la classe ExpressionAddition donne :

public int evaluer(){
    return expressionGauche.evaluer() + expressionDroite.evaluer();
}

etc...

Tu dois prévoir aussi des setters et des getters pour tous les attributs de tes Expression afin de pouvoir construire une expression complexe (n'oublie pas les expression parenthésées et les moins unaires (-5 par exemple)).

Ensuite tu dois écrire un fichier grammaireExpression.jj où tu vas écrire la grammaire d'une expression. C'est-à-dire la façon dont s'écrit une expression correcte. J'ai un exemple que j'ai fait y'a un moment sous la main :

Exemple de grammaire.jj
<hr size="2" width="100%" />

options{
    STATIC = false;
}

PARSER_BEGIN(ParserExpression)

package parsing.expression;

import expressions.*;
import java.util.LinkedList;

public class ParserExpression{}

PARSER_END(ParserExpression)

SKIP :
{
        " "
    |    "\t"
    |    "\n"
    |    "\r"
}

TOKEN :
{

       
    |    <FOIS: "*">
    |    <MOINS: "-">
    |   

    |   
    |   
    |   
    |    <NOMBRE: ["0"-"9"](["0"-"9"])*((["0"-"9"])*)?>
    |    <VIRGULE: ",">
}

InterfaceExpression compile() :
{   
    InterfaceExpression expressionArithmetique;
}
{
    expressionArithmetique = expressionPlusMoins()
    { return expressionArithmetique; }
}

InterfaceExpression expressionPlusMoins() :
{
    InterfaceExpression expressionPlusMoins = null;
    InterfaceExpression expressionDroite;
}
{
    expressionPlusMoins = expressionFoisDiv()
    (
            expressionDroite = expressionFoisDiv()
            { expressionPlusMoins = new ExpressionPlus(expressionPlusMoins, expressionDroite); }
       
        |    <MOINS> expressionDroite = expressionFoisDiv()
            { expressionPlusMoins = new ExpressionMoins(expressionPlusMoins, expressionDroite); }
    )*
    { return expressionPlusMoins; }
}

InterfaceExpression expressionFoisDiv() :
{
    InterfaceExpression expressionFoisDiv = null;
    InterfaceExpression expressionDroite;
}
{
    expressionFoisDiv = expressionMoinsUnaire()
    (
            <FOIS> expressionDroite = expressionMoinsUnaire()
            { expressionFoisDiv = new ExpressionFois(expressionFoisDiv, expressionDroite); }
       
        |   
expressionDroite = expressionMoinsUnaire()
            { expressionFoisDiv = new ExpressionDivise(expressionFoisDiv, expressionDroite); }
    )*
    { return expressionFoisDiv; }
}

InterfaceExpression expressionMoinsUnaire() :
{
    InterfaceExpression expressionInterne;
}
{
    (
            <MOINS> expressionInterne = expressionTerminale()
            { return new ExpressionMoinsUnaire(expressionInterne); }
        |    expressionInterne = expressionTerminale()
            { return expressionInterne; }
    )
   
}

InterfaceExpression expressionTerminale() :
{
    Token t;
    LinkedList parametres;
    InterfaceExpression expressionInterne;
}
{
   
    (
       
            t = <NOMBRE> { return new ExpressionNombre(t.image); }
        |    expressionInterne = expressionPlusMoins()
            { return new ExpressionParenthesee(expressionInterne); }
    )
}

Avec un peu de chance, en recopiant simplement cette grammaire et en faisant la partie métier compatible (observe comment sont construites les expressions dans la grammaire), tu dois t'en sortir.

Pour générer le Parser, il te suffit de compiler la grammaire à l'aide de javacc.
Pour cela tu ouvres une console de commandes, tu te positionnes dans le repertoire où tu as décompressé javacc et tu tapes :
javacc grammaire.jj

si ya pas d'erreurs, ça te donne quelques fichiers que tu peux inclure dans ton projet, le plus important étant le parser en lui-même, il porte le nom de la classe définie dans ta grammaire. Dans mon exemple c'est ParserExpression.java.

Pour l'utiliser c'est simple :

ParserExpression p = new ParserExpression(new StringReader("3 * (1+2)"));
ExpressionArithmetique exp = p.compile();
System.out.prinln(exp.evaluer());

Voilà, je ne sais pas si tu es familier avec les concepts de compilation, mais dans tous les cas, oriente-toi vers cette solution. Ce sera peut-être un petit effort à fournir au début, mais le jeu en vaut la chandelle car les expression régulières ont leurs limites.

N'hésite pas à reposter si tu es bloqué quelque part.
0