/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Copyright (C) 2011-2013 Marchand Eric <ricoh51@free.fr>
This file is part of Freegressi.
Freegressi is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Freegressi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with Freegressi. If not, see <http://www.gnu.org/licenses/>.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package freegressi.parser;
import freegressi.tableur.Noeud;
import freegressi.tableur.Sym;
import freegressi.tableur.Tableur;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author marchand
*/
public class Verificateur {
public static ArrayList<Noeud> lexe(String line){
ArrayList<Noeud> nodes= new ArrayList<>();
try {
Lexer lex = new Lexer(new java.io.StringReader(line), nodes);
lex.yylex();
} catch (Exception ex) {
return null;
}
return nodes;
}
// public static Noeud stringExpressionVariableToNoeud(Tableur tableur, String expression, String nomSerie) {
// // Créer la liste de noeuds avec le lexer
// ArrayList<Noeud> liste = new ArrayList<Noeud>();
// try {
// Lexer lex = new Lexer(new java.io.StringReader(expression), liste);
// lex.yylex();
// } catch (Exception e) {
// System.err.println("Erreur interne du lexer!");
// return new Noeud(Sym.ERROR, "Erreur interne du lexer! Ne devrait pas survenir!");
// }
//
// // Vérifier que les noeuds ne comprennent pas d'ID inconnus, c.a.d. que
// // tous les noms de variables utilisées sont définis AVANT dans listeSeries
// for (Noeud noeud : liste) {
// if (noeud.getType() == Sym.ID) {
// if (!tableur.estIDConnu(noeud.getNom(), nomSerie)) {
// //Noeud erreur = new Noeud();
// noeud.setType(Sym.ERROR);
// noeud.setTexteErreur("Identificateur inconnu! : " + noeud.getNom());
// return noeud;
// }
// }
// }
//
// // Créer le noeud correspondant à l'expression
// Parser parser = new Parser(liste);
// Noeud racine = parser.parser();
//
// return racine;
// }
/**
* Vérifie l'expression fournie par l'utilisateur. Les id inconnus sont
* acceptés et deviendront les paramètres à déterminer.
* @param exp l'expression sous forme de chaine
* @param nomSerie
* @return le noeud fourni par le parser, ou un noeud "erreur"
*/
public static Noeud parseExpressionTendance(String exp, String nomSerie) {
// Créer la liste de noeuds avec le lexer
ArrayList<Noeud> liste = new ArrayList<>();
try {
Lexer lex = new Lexer(new java.io.StringReader(exp), liste);
lex.yylex();
} catch (Exception e) {
System.err.println("Erreur interne du lexer!");
return new Noeud(Sym.ERROR, "Erreur interne du lexer! Ne devrait pas survenir!");
}
// Marquer les noeuds d'ID inconnus comme parametres
for (Noeud noeud : liste) {
if (noeud.getType() == Sym.ID) {
if (!noeud.getNom().equals(nomSerie)) {
noeud.setType(Sym.PARAMETRE);
//noeud.setTexteErreur("Identificateur inconnu! : " + noeud.getNom());
//return noeud;
}
}
}
// Créer le noeud correspondant à l'expression
Parser parser = new Parser(liste);
Noeud racine = parser.parser();
return racine;
}
/**
* Vérifie l'expression fournie par l'utilisateur
* @param exp l'expression sous forme de chaine
* @return le noeud fourni par le parser, ou un noeud "erreur"
*/
public static Noeud parseExpression(Tableur tableur, String exp, String nomSerie) {
// Créer la liste de noeuds avec le lexer
ArrayList<Noeud> liste = new ArrayList<>();
try {
Lexer lex = new Lexer(new java.io.StringReader(exp), liste);
lex.yylex();
} catch (Exception e) {
System.err.println("Erreur interne du lexer!");
return new Noeud(Sym.ERROR, "Erreur interne du lexer! Ne devrait pas survenir!");
}
// Vérifier que les noeuds ne comprennent pas d'ID inconnus, c.a.d. que
// tous les noms de variables utilisées sont définis AVANT dans listeSeries
// et qu'il n'y a pas d'auto-référencement
for (Noeud noeud : liste) {
if (noeud.getType() == Sym.ID) {
if (tableur == null || noeud.getNom().equals(nomSerie)) {
noeud.setType(Sym.ERROR);
noeud.setTexteErreur(Sym.ERREUR_AUTOREFERENCE);
return noeud;
}
if (tableur == null || !tableur.estIDConnu(noeud.getNom(), nomSerie)) {
noeud.setType(Sym.ERROR);
noeud.setTexteErreur(Sym.ERREUR_NOM_INCONNU + " : " + noeud.getNom());
return noeud;
}
}else{
if (noeud.getType() == Sym.EGAL || noeud.getType() == Sym.COMMENT || noeud.getType() == Sym.UNIT){
noeud.setType(Sym.ERROR);
noeud.setTexteErreur(Sym.ERREUR_CARACTERE_INTERDIT + " : " + noeud.getNom());
return noeud;
}
}
}
// Créer le noeud correspondant à l'expression
Parser parser = new Parser(liste);
Noeud racine = parser.parser();
return racine;
}
/**
* Vérifie uniquement qu'un nom de variable est bien formé
* @param nom le nom de la variable
* @return le noeud correspondant (avec son erreur éventuelle)
*/
public static Noeud parseNomDeVariable(String nom) {
String erreurId = "<html>Un nom de variables est composé d'une lettre (ou _) suivie de caractères ou lettres!</html>";
ArrayList<Noeud> liste = new ArrayList<>();
Noeud erreur = new Noeud(Sym.ERROR, "");
try {
Lexer lex = new Lexer(new java.io.StringReader(nom), liste);
lex.yylex();
} catch (Exception e) {
System.err.println("Erreur interne du lexer! : " + e.getMessage());
erreur.setTexteErreur("Erreur interne du lexer! Ne devrait pas survenir! : " + e.getMessage());
return erreur;
}
// il doit y avoir au moins un noeud
if (liste.isEmpty()) {
return null;
}
// il ne doit pas y avoir plus qu'un noeud
if (liste.size() > 1) {
liste.get(1).setType(Sym.ERROR);
liste.get(1).setTexteErreur(erreurId);
return liste.get(1);
}
// Maintenant il y a le bon compte de noeuds
// vérifions que c'est bien un id
if (liste.get(0).getType() != Sym.ID) {
erreur.setTexteErreur(erreurId);
return erreur;
}
return liste.get(0);
}
/**
* Vérifie que l'unité est un texte sans @ ni #
* @param unite
* @return -1 si pas d'unité ou unité valide
* ou la position de l'erreur sinon
*/
public static int parseUnite(String unit) {
int n1 = unit.indexOf("@");
//System.out.println("@ dans unit : " + n1);
if (n1 != -1) return n1;
int n2 = unit.indexOf("#");
if (n2 != -1) return n2;
return -1;
// StringTokenizer st = new StringTokenizer(unite);
// int n = st.countTokens();
// if (n < 2) {
// return 0;
// } else {
// String str = st.nextToken();
// return str.length() + 1;
// }
}
/**
* Change ancienNom d'un ID en nouveauNom dans cette expression
* @param ancienNom
* @param nouveauNom
* @param expression
* @return la nouvelle expression
*/
public static String modifyExpression(String oldName, String newName, String expression) {
if (oldName.equals(newName)){
return expression;
}
String exp = "";
List<Noeud> nodes = new ArrayList<>();
Lexer lexer = new Lexer(new java.io.StringReader(expression), nodes);
try {
lexer.yylex();
} catch (Exception e) {
}
for (Noeud node : nodes) {
if (node.getNom().equals(oldName)) {
node.setNom(newName);
node.setTexteLexer(newName);
}
exp += node.getTexteLexer().trim();
}
return exp;
}
}