2009-05-08 8 views
1

J'utilise cette grammaire pour calculer des expressions mathématiques:JavaCC - Parse expressions mathématiques dans une structure de classe

// Konfiguration (JavaCC-Manual konsultieren) 
options { 
    STATIC = true; // alle Parser-operationen sind static 
    // verwende zwei Token um zu entscheiden, was passieren soll 
    LOOKAHEAD = 2; 
} 

// hier beginnt unsere Parser Klasse ("MathParse") 
PARSER_BEGIN(MathParse) 
// hier kann ganz normaler Java-Code verwendet werden 
public class MathParse { 
    public static void main(String[] args) { 
     // auch ein statischer Parser muss initiiert werden 
     // - allerdings nur einmal 
     MathParse parser = new MathParse(System.in); 
     try { 
      System.out.println(parser.parse()); 
     } catch(ParseException e) { 
      e.printStackTrace(); 
     } 
    } 

    // die Parser-Methoden werden automatisch hinzugefügt 
} 
PARSER_END(MathParse) 

// Diese Zeichen ignorieren wir 
// SKIP : { $regex$ } 
SKIP : { " " | "\t" } 

// Jetzt definieren wir unsere Token 

// TOKEN : { < $tokenname$ : $regex$ >} 
// "NUMBER" entspricht einer unbegrenzten Anzahl (min. 1) an Zahlen 
// (von 0 bis 9) 
TOKEN : { < NUMBER : (["0"-"9"])+ ("." (["0"-"9"])+)? > } 
TOKEN : { < EOL : "\n" > } 

// Und fröhlich weiter mit der tatsächlichen Syntax 
double parse() : { 
    double value; 
} 
{ 
    value=expr() 
    (<EOF> | <EOL>)  { return value; } 
} 

double expr() : { 
    double x; 
    double y; 
} 
{ 
    x=term() 
    (
     "+" y=expr() { x += y; } 
    | 
     "-" y=expr() { x -= y; } 
    )* 
    { return x; } 
} 

double term() : { 
    double x; 
    double y; 
} 
{ 
    x=value() 
    (
     "*" y=term() { x *= y; } 
     | 
     "/" y=term() { x /= y; } 
    )* 
    { return x; } 
} 

double value() : { 
    double value; 
} 
{ 
    "-" value=number() { return -value; } 
    | 
    value=number()  { return value; } 
} 

double number() : { 
    Token t; 
    double value; 
} 
{ 
    t=<NUMBER>  { return Double.parseDouble(t.image); } 
    | 
    "(" value=expr() ")" { return value; } 
} 

Cela fonctionne très bien. Mais maintenant je ne veux pas obtenir un nombre comme résultat, mais une structure de classe représentant le terme. Je pensais à quelque chose comme ceci:

public abstract class Expression { 
    public abstract double calculate(); 
} 

public class NumberExpression extends Expression { 
    public double Value; 

    public NumberExpression(double value) { 
     this.Value = value; 
    } 

    public double calculate() { 
     return this.Value; 
    } 
} 

public class ComplexExpression extends Expression { 
    public Operator Operator; 
    public Vector SubExpressions; 

    public double calculate() { 
     double result = ((Expression)this.SubExpressions.elementAt(0)).calculate(); 

     for (int i = 1; i < this.SubExpressions.size(); ++i) 
      result = this.Operator.calculate(result, ((Expression)this.SubExpressions.elementAt(i)).calculate()); 

     return result; 
    } 
} 

public abstract class Operator { 
    public abstract String getOperator(); 
    public abstract double calculate(double x, double y); 
} 

Je ne suis pas grand-chose à voir avec Java ou JavaCC, alors pouvez-vous me dire comment écrire une grammaire pour cela? PS: J'utilise Java ME.

+0

Je ne comprends pas, voulez-vous un analyseur pour générer le deuxième morceau de code? –

Répondre

2

eWolf,

Essayez d'utiliser JJTree qui est un préprocesseur pour JavaCC et introduit automatiquement le code Java qui crée la syntaxe abstraite des arbres pour l'entrée analysable.

Visitez simplement le https://javacc.dev.java.net/ et trouvez le manuel JJTree.