* @param index du prochain noeud dans la liste
* @param parG est le noeud "(" si parse est appelée par une parenthèse ouvrante "("
* @return la racine de l'arbre
*/
private Noeud parse(int index, Noeud parG) {
Noeud noeud = getNoeudSuivant();
Noeud nCourant = null;
boolean attendArgument = false;
while (noeud != null) {
switch (noeud.getType()) {
case Sym.ERROR:
noeud.setTexteErreur("Erreur du lexer!");
return noeud;
case Sym.UNIT:
case Sym.COMMENT:
case Sym.COMMENT_TEXT:
case Sym.UNIT_TEXT:
attendArgument = false;
//nCourant = ajouteNoeudTerminal(noeud, nCourant);
break;
case Sym.EGAL:
attendArgument = false;
nCourant = ajouteNoeudNonTerminal(noeud, nCourant);
break;
case Sym.NOMBRE:
attendArgument = false;
nCourant = ajouteNoeudTerminal(noeud, nCourant);
//System.out.print("N");
break;
case Sym.PLUS:
case Sym.MOINS:
case Sym.FOIS:
case Sym.DIVISE:
attendArgument = false;
nCourant = ajouteNoeudNonTerminal(noeud, nCourant);
break;
case Sym.VIRGULE:
//System.out.println("Virgule : " + noeud.getTexteLexer());
if (attendArgument){
nCourant.setType(Sym.PARSER_COHERENCE_ERROR);
nCourant.setTexteErreur("Attente d'un argument");
return nCourant;
}
attendArgument = true;
nCourant = ajouteNoeudNonTerminal(noeud, nCourant);
break;
case Sym.PUIS:
attendArgument = false;
nCourant = ajouteNoeudNonTerminal(noeud, nCourant);
//System.out.print("^");
break;
case Sym.PUIS2:
attendArgument = false;
Noeud n = new Noeud(Sym.NOMBRE, Sym.CATEGORIE_SANS, Sym.PRIORITE_BASSE, 2.0, noeud.getLigne(), noeud.getColonne(), "");
noeud.setType(Sym.PUIS);
nCourant = ajouteNoeudNonTerminal(noeud, nCourant); // ajout du noeud PUIS
nCourant = ajouteNoeudTerminal(n, nCourant); // ajout du noeud NOMBRE : 2
//System.out.print("^2");
break;
case Sym.PUISN:
attendArgument = false;
Noeud n1 = new Noeud(Sym.NOMBRE, Sym.CATEGORIE_SANS, Sym.PRIORITE_BASSE, (double) noeud.getPuissance(), noeud.getLigne(), noeud.getColonne(), "");
//System.out.println(noeud.getPuissance());
noeud.setType(Sym.PUIS);
noeud.setCategorie(Sym.CATEGORIE_OPERATEUR);
noeud.setPriorite(Sym.PRIORITE_HAUTE);
nCourant = ajouteNoeudNonTerminal(noeud, nCourant); // ajout du noeud PUIS
nCourant = ajouteNoeudTerminal(n1, nCourant); // ajout du noeud NOMBRE : N
//System.out.print("^2");
break;
case Sym.ID:
case Sym.PARAMETRE:
attendArgument = false;
nCourant = ajouteNoeudTerminal(noeud, nCourant);
//System.out.print("Id : "+noeud.getNom());
break;
case Sym.SIN:
case Sym.COS:
case Sym.TAN:
case Sym.ASIN:
case Sym.ACOS:
case Sym.ATAN:
attendArgument = false;
nCourant = ajouteNoeudTerminal(noeud, nCourant);
break;
case Sym.LOG:
case Sym.LN:
case Sym.EXP:
case Sym.SQR:
case Sym.SQRT:
case Sym.ABS:
attendArgument = false;
nCourant = ajouteNoeudTerminal(noeud, nCourant);
break;
case Sym.PI:
case Sym.E:
attendArgument = false;
nCourant = ajouteNoeudTerminal(noeud, nCourant);
//System.out.print("ATAN");
break;
case Sym.MOYENNE:
attendArgument = false;
nCourant = ajouteNoeudTerminal(noeud, nCourant);
//System.out.print("ATAN");
break;
case Sym.DERIVEE:
case Sym.INTEGRALE:
case Sym.RAND:
attendArgument = false;
nCourant = ajouteNoeudTerminal(noeud, nCourant);
break;
case Sym.PARENG:
//attendArgument = true;
noeud = parse(indexListe + 1, noeud);
if (noeud != null && noeud.getType() == Sym.PARSER_COHERENCE_ERROR) {
return noeud;
}
// Mettre les arguments de fonction sous forme de liste
if (nCourant != null && nCourant.getCategorie() == Sym.CATEGORIE_FONCTION) {
if (nCourant.getNombreParametres() > 1) { // uniquement pour les fonctions à plusieurs paramètres
List<Noeud> listeP = new ArrayList<Noeud>();
int nombreParametres = getListeParametres(noeud, listeP);
if (nCourant.getNombreParametres() == Integer.MAX_VALUE || nombreParametres == nCourant.getNombreParametres()) {
ajouteNoeudTerminalArguments(listeP, nCourant);
break;
} else {
nCourant.setType(Sym.PARSER_COHERENCE_ERROR);
nCourant.setTexteErreur("Cette fonction nécessite " + nCourant.getNombreParametres() + " arguments!");
return nCourant;
}
} else { // fonction à 1 paramètre, vérifier qu'il n'y en a qu'un
List<Noeud> listeP = new ArrayList<Noeud>();
int nombreParametres = getListeParametres(noeud, listeP);
if (nombreParametres != 1){
nCourant.setType(Sym.PARSER_COHERENCE_ERROR);
nCourant.setTexteErreur("Cette fonction nécessite 1 seul argument!");
return nCourant;
}
}
}
nCourant = ajouteNoeudTerminal(noeud, nCourant);
attendArgument = false;
break;
case Sym.PAREND:
if (attendArgument){
nCourant.setType(Sym.PARSER_COHERENCE_ERROR);
nCourant.setTexteErreur("Attente d'un argument");
return nCourant;
}
if (parG == null) { // ici erreur : on détecte une parenthese droite mais il n'y a pas de gauche
noeud.setType(Sym.PARSER_COHERENCE_ERROR);
noeud.setTexteErreur("pas de parenthèse ouvrante associée!");
return noeud;
}
if (nCourant == null) {
Noeud erreur = new Noeud(Sym.PARSER_COHERENCE_ERROR, Sym.CATEGORIE_SANS, Sym.PRIORITE_HAUTE, 0, parG.getColonne(), "");
erreur.setTexteErreur("Expression vide!");
return erreur;
} else {
attendArgument = false;
return nCourant.getRacine();
}