class AST {

  char op;
  AST filsG, filsD;


  AST (char x, AST a, AST b) {
    op = x;
    filsG = a;
    filsD = b;
  }

  static String f;
  static int i;

  static AST expression() throws ErreurDeSyntaxe {
    AST a, b;

    a = terme();
    if (f.charAt(i) == '+') {
        ++i;
        b = expression();
        return new AST('+', a, b);
    }
    else return a;
  }

  static AST terme() throws ErreurDeSyntaxe {
    AST a, b;

    a = facteur();
    if (f.charAt(i) == '*') {
        ++i;
        b = terme();
        return new AST ('*', a, b);
    }
    else return a;
  }

  static AST facteur() throws ErreurDeSyntaxe {
    AST a;

    if (f.charAt(i) == '(') {
        ++i;
        a = expression();
        if (f.charAt(i) == ')') {
            ++i;
            return a;
            }
        else throw new ErreurDeSyntaxe(i);
    }
    else if (f.charAt(i) == 'a') {
            ++i;
            a = new AST ('a', null, null);
            return a;
         }
         else throw new ErreurDeSyntaxe(i);
  }

  static void erreur (String s) {
    System.err.println ("Erreur fatale: " + s);
    System.exit (1);
  }

  static int evaluer(AST x, int v) {
  // \esc{Evaluation, voir page \pageref{prog:evaluation}} 

    if (x.op == 'a' )
        return v;
    else if (x.op == '+' )
        return (evaluer(x.filsG, v) + evaluer (x.filsD, v));
    else if (x.op == '-' ) 
        return( evaluer(x.filsG, v) - evaluer (x.filsD, v));
    else if (x.op == '*') 
        return (evaluer(x.filsG, v) * evaluer (x.filsD, v));
    else {
        erreur("expression invalide");
        return 0;
    }
  }

  public static void main (String args[]) {

    if (args.length == 2) {
        f = args[0];
        try {
          System.out.println (
            evaluer (expression(), 
                     Integer.parseInt(args[1])));
        }
        catch (ErreurDeSyntaxe i) {
            erreur ("Erreur au caracte`re nume'ro " + i);
        }
    } else
        erreur ("mauvais nombre de parame`tres");
  }
}

class ErreurDeSyntaxe extends Exception {
  int position;

  public ErreurDeSyntaxe (int i) {
    position = i;
  }
}


/*
// \esc{Analyse descendante re'cursive, voir page \pageref{prog:descendante-rec}} 

  int AnalyseRecursive (Mot f, Mot u) {
    int i, pos;
    char x, y;
    Mot v;
    int b;

    pos = 1;
    b = 0;
    while (f.charAt(pos) == u[pos]) 
        ++pos;
    if (f.charAt(pos) == '$' && u[pos] == '+') {
        printf("analyse re\?'ussie \n");
        b = 1;
    }
    else if (Auxiliaire(y)) {
         i = 1;
         while ( (!b) && (i <= nbregle[y -'A'])) {
             v = Remplacer (u,  regle[y-'A'][i], pos);
             b = AnalyseRecursive (v, f);
             if (b) 
                printf ("regle %d du nonterminal %c \n", i, y);
             else ++i;
         }
   }
   return b;
}

  AST ArbSyntPref() {
  // \esc{Analyse LL(1), voir page \pageref{prog:ll1}}

    AST a, b, c;
    char x;

    if (f.charAt(pos) == 'a') {
        a = NouvelArbre( 'a', null, null);
        ++pos;
        }
    else if (f.charAt(pos) == '(') && ((f.charAt(pos + 1) == '+') ||
                                 (f.charAt(pos + 1) == '*')) {
         x = f.charAt(pos + 1);
         pos = pos +2;
         b = ArbSyntPref();
         c = ArbSyntPref();
         a = NouvelArbre(x, b, c);
         if (f.charAt(pos) == ')' ) ++pos;
             else erreur(pos);
         }
    else erreur(pos);
  }

  */
