Analyseur syntaxique en Java [Résolu]

Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 11:26 - Dernière réponse :
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 15 mars 2012 à 09:46
Salut,

Je cherche un code en JAVA qui me permet d'analyser une chaîne de caractère et indiquer s'il existe une erreur syntaxique Exemple : (a*b) "la chaîne à analyser" mon programme doit lever une exception si une erreur est détectée par exemple si je saisie "(a*b" il doit mentionner qu'une parenthèse manquante avec précision de l'endroit de l'erreur.

Donc mon programme doit fournir le même traitement que celui de la classe "PatternSyntaxeException" du paquatge Regex .

j'espère avoir des réponses le plus tôt possible.

Merci d'avance pour votre aide .
Afficher la suite 

Votre réponse

26 réponses

Meilleure réponse
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 12:03
3
Merci
Bonjour,

je vais commencer par déplacer ton sujet vers le forum java (bien qu'il utilise également des regex).

Merci cs_Julien39 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de cs_Julien39
Meilleure réponse
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 12:06
3
Merci
Je te conseil de regarder cette source qui doit a peu près correspondre à ce que tu cherches à faire : http://www.javafr.com/codes/VERIFIER-TEXTE-JTEXTFIELD-AVEC-REGEX_54130.aspx

Les regex s'utilisent simplement en java. La difficulté sera peut être pour toi d'écrire l'expression régulière de contrôle (je ne sais pas si tu as de bonnes connaissances des regex). Si tu as un soucis sur ce sujet, je peux t'aider.

Merci cs_Julien39 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de cs_Julien39
Meilleure réponse
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 12:24
3
Merci
Merci Julien39 pour ta réponse :) mon programme doit principalement indiquer l'erreur exemple( "{" qui manque ou bien '(' qui n'est pas fermée ... et il doit mentionner l'emplacement de cette erreur..) et donc il doit pas analyser seulement la chaîne de caractère et dire si elle est valide ou pas (False/true) mais plutôt déterminer exactement les erreurs.

Merci VerInfo 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 90 internautes ce mois-ci

Commenter la réponse de VerInfo
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 20:03
1
Merci
Alors, dans ce cas là, ce n'est pas si complexe que ca : tu peux utiliser la récursivité habilement.

//Dans le cas ou il n'y a que deux parenthèses
public boolean testSimple(String invocation){
   return invocation.matches("[A-Za-z0-9]+\\.[A-Za-z0-9]+\\([A-Za-z0-9 ]*\\)");
}

//Ensuite, ca se complique, si il y a plusieurs méthodes appelées par exemple : m.afficher(f.calculer());

public boolean testCompose(String invocation){
   boolean res;
   //Si il y a plusieurs parentheses
   if(invocation.matches("[^\\(]*\\([^\\(]*\\("){
      res=testCompose(recupererSousGroupe(invocation)) && testSimple(supprimerSousGroupe(invocation));
   }
   else {
      res=testSimple(invocation);
   }
   return res;
}

public String recupererSousGroupe(String ligne){
    String res="";
    String patternStr = "[^\\(]*\\([^\\(]*\\((.*).*";
    Pattern pattern = Pattern.compile(patternStr);
    Matcher matcher = pattern.matcher(ligne);
    boolean matchFound = matcher.find();
    if (matchFound && matcher.groupCount()>=1) {
        res = matcher.group(1);
    }
    return res;
}
Commenter la réponse de cs_Julien39
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 20:39
1
Merci
j'ai ces deux classe "Lexicale" et "Syntaxique"

package analyseur;
import java.util.List;
public class Lexicale {
    public String chaine="(a+b)";
    private int pos=0;
    public Lexicale(String chaine){this.chaine=chaine;}
    public boolean haveLexeme()
    {return(chaine.length()>pos);}

    public String getNextLexeme(){
    ignoreSpaceTabulationRetourLigne();
    while (haveLexeme())
    {
        switch(chaine.charAt(pos)){
        case '+':pos++; return("+");
        case '-':pos++; return("-");
        case '*':pos++; return("*");
        case '/':pos++; return("/");
        case '^':pos++; return("^");
        case '(':pos++; return("(");
        case ')':pos++; return(")");
        
        case'0': case'1': case'2': case'3':
        case'4':case'5':case'6':case'7':case'8':case'9':

         pos++; 

       while (haveLexeme()&& chaine.charAt(pos)<='9'&& chaine.charAt(pos)>='0')
       pos++;

       return("nb");
      
            case'a': case'b': case'c': case'd': case'e': case'f': case'g':
            case'h': case'i': case'j': case'k': case'l': case'm': case'n':
            case'o': case'p': case'q': case'r': case's': case't': case'u':
            case'v': case'w': case'x': case'y': case'z': case'A': case'B':
            case'C': case'D': case'E': case'F': case'G': case'H': case'I': case'J':
            case'K': case'L':case'M': case'N': case'O': case'P': case'Q': case'R':
            case'S':case'T': case'U': case'V': case'W': case'X': case'Y': case'Z': 
       {pos++;}
    while (haveLexeme()&& (chaine.charAt(pos)<='9')&&
     chaine.charAt(pos)>='0'||chaine.charAt(pos)>='a'&&
     chaine.charAt(pos)<='z'||chaine.charAt(pos)>='A'&& chaine.charAt(pos)<='Z')
    {pos++;} 
    return("id");

    case'\n':
    case'\t':
    case' ':
         ignoreSpaceTabulationRetourLigne();

         default: pos++;
         return (chaine.charAt(pos-1)+"n'est pas élément du langage");
    }
    }

    return ("EOF");
    }

    private void ignoreSpaceTabulationRetourLigne(){
    if (haveLexeme()&& ((chaine.charAt(pos))=='\n')||((chaine.charAt(pos))=='\t')||(chaine.charAt(pos))==' ')
    {pos++;
    while (haveLexeme()&& ((chaine.charAt(pos))=='\n')||
    ((chaine.charAt(pos))=='\t')||(chaine.charAt(pos))==' ') {pos++;}
    }
    }

    public int getPos(){return pos;}
    public void setPos(int pos){this.pos=pos;}


public void synchro(List <String>l)
{String lex="";
 if (haveLexeme())
     lex= getNextLexeme();
  while (haveLexeme()&& (!l.contains(lex)))
  {lex= getNextLexeme();}
 if (l.contains(lex))
 {int gh=getPos()-1;
 setPos(gh);
 }
}


  
}
Commenter la réponse de VerInfo
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 20:42
1
Merci
Et voilà la classe Syntaxe

package analyseur;
import java.*;
import java.util.List;
import analyseur.Lexicale.*;



public class Syntaxe {
   
    private static String symbole;
    static List<String> L;
  static String chaine = null;
      static Lexicale x = new Lexicale(chaine);


      public grammaire (String chaine ){
          this.chaine= chaine;

      }
   static void E()
    {
    T();
    R1();
    }

 static void T()
   {
   F();
   R2();
   }

   static void R1()
   {   //int i=0; while (i< chaine.length())
       //symbole = chaine.charAt(0);
      if (symbole== "+")
    { accepter ("+");
      T();
      R1();
    }else if( symbole=="-"){
       accepter ("-");
      T();
      R1();}else
      {erreur(1);} // on ne met pas else erreur car on a epsilon
   }

   static void R2()
   { 
      if (symbole=="*")
    { accepter ("*");
      T();
      R1();
    }else if( symbole=="/"){
       accepter ("/");
      T();
      R1();}else{erreur(2);} // on ne met pas else erreur car on a epsilon
   }
   
  static void F()
   {
    H();
    R3();

   }
  
  static void R3()
   { if (symbole =="^")
     {accepter("^");
     F();}
     else
     {erreur(3);}
   }

    static void H(){
    if(symbole =="(")
    {
    accepter("(");
    E();
    }
    else if (symbole =="id")
    { 
       accepter ("id");
      }else{erreur(4);}
    }

   private static  void accepter(String cc) {

     if (symbole cc){symbole x.getNextLexeme();}
     
    }
public static void m(String xx){
  symbole = x.getNextLexeme();
  E();
  if (symbole=="§")
{ System.out.println("Succès");}
 else
{System.out.println("Echec");
}
}



    private static void erreur(int n){
        switch (n){
            case 1:{System.out.println("le symbole + ou - est manquant");
            L.add("§");
            L.add("(");
            L.add(")");
            L.add("id"); 
            L.add("nb");
            
            x.synchro(L);
            List L1 = null;// L1 contient les premiers de R1
           //List L2 = null;// contient les suivants de R1
            L1.add('+');
            L1.add('-');

           // L2.add(')');
            //L2.add('§');

            if (L1.contains(symbole))  {T();}
           /* else if
                    (L2.contains(symbole)){}*/
            }
            case 2:{System.out.println("le symbole * ou / est manquant");
            L.add("*");
            L.add("/");
            L.add("+");
            L.add("-");
            L.add("§");
            L.add(")");
            x.synchro(L);
            List L3 = null;
            L3.add("*");
             L3.add("/");//
            if ( L3.contains(symbole)){F();}}

            case 3:{System.out.println("le symbole ^ est manquant");  
            L.add("*");
            L.add("/");
            L.add("+");
            L.add("-");
            L.add("§");
            L.add( ")");
            L.add("^");
            x.synchro(L);
            List L4 = null;
            L4.add("^");
            if ( L4.contains(symbole)){F();}}

            case 4:{System.out.println("un id est manquant");}
            L.add("*");
            L.add("/");
            L.add("+");
            L.add("-");
            L.add("§");
            L.add(" )");L.add("(");L.add("^");
            L.add("nb");L.add("id");
            x.synchro(L);
            
            if (symbole == "("){ E();}
           
    
       }

   
    }
}

Commenter la réponse de VerInfo
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 13:33
0
Merci
Alors le problème n'est pas uniquement lié à l'utilisation d'une expression régulière. Je n'ai pas vraiment d'idée très claire sur la façon de procéder.

Je pense qu'à ta place, je découperais la chaine pour l'analyser avec l'expression régulières suivante : [^\(].*(\([^\(]\)).* et j'essayerais d'analyser le contenu des parentèles de facon récursive jusqu'à ce que le capturing group ne contienne plus le sympbole ( ni )

Je pense que tu as un gros travail à effectuer pour créer l'algorithme qui va te permettre d'effectuer le contrôle. Les expression régulières ne résoudront pas tout mais pourront t'aider, c'est certain.
Commenter la réponse de cs_Julien39
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 14:35
0
Merci
justement j'arrive pas à créer l'algorithme qui me permettra d'effectuer ce contrôle
si tu peux m'aider à trouver l'algorithme de la classe "PatternSyntaxeException" je te serais vraiment reconnaissante

Car cette classe est responsable de lever une exception si la syntaxe de l'expression n'est pas valide donc sûrement elle fait des analyses pour déterminer l'emplacement de l'erreur et sa nature,et pour cela j'ai besoin de connaitre comment la "PatternSyntaxeException" réalise son traitement car je pense que ça va m'aider .

merci infiniment
Commenter la réponse de VerInfo
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 14:56
0
Merci
Désolé de te décevoir mais le code de la classe PatternSyntaxException est celui-ci :


public class PatternSyntaxeException extends Exception {

/**
 * 
 */
public PatternSyntaxeException() {
super();
// TODO Auto-generated constructor stub
}

/**
 * @param message
 * @param cause
 */
public PatternSyntaxeException(String message, Throwable cause) {
super(message, cause);
// TODO Auto-generated constructor stub
}

/**
 * @param message
 */
public PatternSyntaxeException(String message) {
super(message);
// TODO Auto-generated constructor stub
}

/**
 * @param cause
 */
public PatternSyntaxeException(Throwable cause) {
super(cause);
// TODO Auto-generated constructor stub
}



}



Toutes les exceptions fonctionnent de la même façon : on considère que les données sont correctes et on fait le traitement : s'il y a une erreur, l'exception est levée. Il n'y a pas de contrôle d'effectué.
Commenter la réponse de cs_Julien39
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 14:59
0
Merci
Mais bon, ce n'est pas si complexe que ca : pour vérifier que les parenthèses sont équilibrées par exemple :

String chaine="(3+2)*(4+5";
int nb=0;
for(int i=0; i<chaine.length; i++){
if(chaine.charAt(i)=="(".charAt(0)){
nb++;
}
else if(chaine.charAt(i)==")".charAt(0)){
nb--;
}
}
if(nb!=0){
System.out.println("Syntaxe incorrecte");
}
Commenter la réponse de cs_Julien39
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 15:01
0
Merci
Mais par contre, on ne peut pas vraiment savoir d'où vient l'erreur sur cet exemple précis.

La chaine correcte peut être soit "(3+2)*(4)+5" soit "(3+2)*(4+5)" comment trancher ?

et pour les autres contrôles, ca doit se faire aussi...
Commenter la réponse de cs_Julien39
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 15:25
0
Merci
Merci bien mais ce que je voulais savoir comment cette classe peut déterminer que l'expression n'est pas correcte par exemple elle produit une exception car une parenthèse ouvrante est présente sans la parenthèse fermante ...

Exemple :
Exception in thread "main" java.util.regex.PatternSyntaxException: Unmatched closing ')' near index 31 ^([01]?\d\d?|2[0-4]\d|25[0-5])\.)([01]?\d\d?|2[0-4]\d|25[0-5]\).([01]?\d\d?|2[0-4]\d|25[0-5])\.([01]?\d\d?|2[0-4]\d|25[0-5])$

Donc moi je veux réaliser un programme qui permet de détecter et mentionner les erreurs d'une expression.
Commenter la réponse de VerInfo
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 15:58
0
Merci
C'est au moment de la compilation de d'expression régulière : le code analyse la chaine caractère par caractère : si le caractère i est une parenthèse alors il va chercher la parenthèse fermante de même niveau, en java, ca donnerait :

for(int i=0; i<regex.length; i++){
if(regex.charAt(i)=="(".charAt(0)){
determinerSousExpression(regex, i);
}
}

public void determinerSousExpression(String regex, int pos){
int niveau=0;
boolean match=false;
for(int i=pos; i<regex.length; i++){
if(regex.charAt(i)=="(".charAt(0)){
niveau++;
}
if(regex.charAt(i)==")".charAt(0)){
if(niveau==0){
System.out.prinln(regex.substring(pos, pos+i));
match=true;
}
niveau--;
}
}
if(!match){
// Et là, il font une petite mise en forme sur la sortie pour te montrer ton erreur
throw new PatternSyntaxException("Erreur en position "+pos);
}

}


Mais il n'y a pas d'analyse de la chaine à proprement parler, juste une compilation. Remarque, tu peux compiler le motif correspondant à ta chaine et récupérer l'exception si elle est levée et le tour est joué non ?
Commenter la réponse de cs_Julien39
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 16:16
0
Merci
Vraiment merci pour ton aide mais j ai pas bien saisi ta dernière question ?
Commenter la réponse de VerInfo
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 16:19
0
Merci
Non, à la réflexion, c'est une mauvaise idée, les utilisations détournées, c'est toujours un peu foireux.

Mais tu devrais pouvoir utiliser un mécanisme similaire pour vérifier ton expression : à quoi correspond ton expression et qu'en fais tu ? Quelles vérifications fait tu dessus ?
Commenter la réponse de cs_Julien39
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 16:43
0
Merci
ah ok merci pour l'explication

Bon réellement je dois réaliser une application qui permet d'analyser une expression(syntaxiquement et sémantiquement) et indiquer les erreurs comme j'ai mentionné en haut ,ces expressions sont de type d'invocation de méthodes par exemple "m.afficher();" cette application sera réalisée dans le cadre de mon projet de fin d'études .

Mais vu que je suis un peu perdue j'ai voulu commencer par un petit exemple qui me permet de comprendre le mécanisme c'est pour cela que j'ai demandé de l'aide

je te remercie encore une fois pour ton aide
Commenter la réponse de VerInfo
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 20:03
0
Merci
Reste à coder supprimerSousGroupe mais je n'ai pas eu le courage... Si tu as compris le reste, tu devrais t'en sortir.
Commenter la réponse de cs_Julien39
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 20:05
0
Merci
Ha oui : je n'ai rien testé, j'ai tout écris directement dans la fenêtre du forum, il y a peut être une ou deux erreurs.

Si c'est vraiment trop moche, dis le moi et j'ouvrirai éclipse.

Je pense qu'il y a encore du travail à effectuer, là, tu ne peux pas détecter les structures du genre m.methodeA().methodeB(); mais tu peux déjà en faire pas mal.
Commenter la réponse de cs_Julien39
Messages postés
6450
Date d'inscription
mardi 8 mars 2005
Dernière intervention
17 mai 2018
- 14 mars 2012 à 20:06
0
Merci
Il y a quelques jours, j'ai déposé un tuto sur les expression régulières, ca peut te servir : http://www.javafr.com/tutoriaux/UTILISATION-EXPRESSIONS-REGULIERES_1286.aspx
Commenter la réponse de cs_Julien39
Messages postés
20
Date d'inscription
mercredi 14 mars 2012
Dernière intervention
3 juillet 2012
- 14 mars 2012 à 20:32
0
Merci
je te remercie pour l'effort que t'as fournis

Mais je pense que ce programme ne permet pas de mentionner les erreurs, il indique seulement si l'expression valide ou non .
je pense que pour vérifier l'équilibrage des parenthèses je dois utiliser la pile ,et pour indiquer la position de l'erreur j'utilise la récursivité

Mais le problème c'est que j'arrive pas à combinais les deux et j'arrive pas à m'en sortir
Commenter la réponse de VerInfo

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.