32Fermer34
BrunniLe 19/04/2009 à 13:32
En effet, comme le dit Kevin le but de mon parseur c'est d'être simple. Quand je voudrai aller plus loin et faire un "vrai" langage j'utiliserai yacc ou autre smile
Sinon merci Zeph, je pense qu'effectivement je me complique la vie tongue Pour ma façon de faire chaque fonction (représentant une règle de production) reçoit un arbre (AST) auquel elle doit attacher le sous arbre produit. Lit permet d'obtenir le prochain jeton. Pour l'expression:
// [OP_UNAIRE] (CTE_ENTIERE | SYMBOLE [TUPLE] | TUPLE) [OP_BINAIRE EXPR]
static void SOUS_EXPR(AST &expr) {
	AST operande;
	AST *courant = &operande;

	if (opUnaire())
		// On attachera le reste à cet opérateur
		courant = &courant->attach(ES_OP_UNAIRE, lit());

	if (prochain(CTE_NOMBRE))
		courant->attach(ES_JETON, lit());
	else if (prochain(IDENTIFICATEUR)) {
		SYMBOLE(*courant);
		if (prochain(PAR_OUVRANTE))
			TUPLE(*courant);
	}
	else if (prochain(PAR_OUVRANTE)) {
		AST tuple;
		TUPLE(tuple);
		// Tuple à un seul élément = expression
		// FIXME: optimisation haut niveau de l'arbre?
		if (tuple.fils.size() == 1) {
			tuple.removeRoot();			// <TUPLE>
			tuple.removeRoot();			// <EXPRESSION>
		}
		courant->attach(tuple);
	}
	else
		erreur("expression attendue");

	// Opérateur binaire + autre expr
	if (opBinaire()) {
		AST operation(ES_OP_BINAIRE, lit()), operande2;
		SOUS_EXPR(operande2);
		operation.attach(operande);
		operation.attach(operande2);
		expr.attach(operation);
	}
	else
		expr.attach(operande);
}

static void EXPR(AST &arbre) {
	AST expr(ES_EXPRESSION);
	SOUS_EXPR(expr);
	arbre.attach(expr);
}

Ca me donne pour l'instant un arbre associatif à droite et sans priorité des opérateurs en notation préfixée, ce qui correspond à ma grammaire. Happy! smile Exemple pour a=0+(1*-2)-3;
<PROG>
    <BLOC_INSTRUCTION>
        <AFFECTATION>
            <SYMBOLE {IDENTIFICATEUR 'a'}>
            <EXPRESSION>
                <OP_BINAIRE {OP_PLUS '+'}>
                    <JETON {CTE_NOMBRE '0'}>
                    <OP_BINAIRE {OP_MOINS '-'}>
                        <OP_BINAIRE {OP_FOIS '*'}>
                            <JETON {CTE_NOMBRE '1'}>
                            <OP_UNAIRE {OP_MOINS '-'}>
                                <JETON {CTE_NOMBRE '2'}>
                        <JETON {CTE_NOMBRE '3'}>

Maintenant je vais virer ça et faire avec une conversion RPN smile