next up previous contents index
Nächste Seite: E. YACS API-Dokumentation Aufwärts: Diplom Vorherige Seite: C. Constraint-Lösungsstrategien   Inhalt   Index

D. Grammatik der Constraint-Ausdrücke

In diesem Anhang ist die Parser-Grammatik der von YACS per JLex/Java CUP interpretierbaren Constraint-Ausdrücke dokumentiert (vgl. Abschnitt 7.5 ff.). Zuerst wird die vom Parser zum Einlesen von gültigen Zeichen benötigte Datei scanner.lex für die lexikalische Analyse durch JLex aufgeführt (vgl. Berk, 2000). Sie befindet sich im Package yacs.parser:


package yacs.parser;

import java_cup.runtime.Symbol;

%%

%cup
%public

ALPHA=[A-Za-z]
DIGIT=[0-9]

%%

";"                             {return new Symbol(sym.SEMI);}
","                             {return new Symbol(sym.COMMA);}
"="                             {return new Symbol(sym.EQUAL);}
"!="                            {return new Symbol(sym.NOT_EQUAL);}
">"                             {return new Symbol(sym.GREATER);}
"<"                             {return new Symbol(sym.LOWER);}
">="                            {return new Symbol(sym.GREATER_EQUAL);}
"<="                            {return new Symbol(sym.LOWER_EQUAL);}
"+"                             {return new Symbol(sym.PLUS);}
"-"                             {return new Symbol(sym.MINUS);}
"*"                             {return new Symbol(sym.TIMES);}
"/"                             {return new Symbol(sym.DIVIDE);}
"("                             {return new Symbol(sym.LPAREN);}
")"                             {return new Symbol(sym.RPAREN);}
"["                             {return new Symbol(sym.LBRACKET);}
"]"                             {return new Symbol(sym.RBRACKET);}
{DIGIT}+                        {return new Symbol(sym.NUMBER,
                                                   new Integer(yytext()));}
{DIGIT}+"."{DIGIT}+             {return new Symbol(sym.FLOAT,
                                                   new Double(yytext()));}
{ALPHA}({ALPHA}|{DIGIT}|_|".")* {return new Symbol(sym.VARIABLE, yytext());}
[ \t\r\n\f\b]                   {/* ignore white space. */}
.                               {System.err.println("Illegal character: "
                                                    +yytext());}

Von Scanner erfasste Zeichen werden an den Parser weitergegeben und anhand der Java-CUP-Grammatik in der Datei parser.cup ausgewertet (vgl. Hudson, 1999). Diese Datei befindet sich ebenfalls im Package yacs.parser und hat den folgenden Inhalt:


package yacs.parser;

import java.util.HashMap;

import yacs.domain.*;

import java_cup.runtime.*;

action code {:
  /* this is where the action code goes */

  /** der erzeugte Ausdruck */
  public Expression expression;

  /** HashtMap zum "Wiederfinden" der generierten Variablen */
  public HashMap actionVariablesMap = new HashMap();

  /** temporaere Variable zum Zwischenspeichern */
  public Variable tmpVariable;

:};

parser code {:
 /* this is where the parser code goes */

  /** HashtMap zum Zwischenspeichern der bereits vorhandenen Variablen */
  public HashMap parserVariablesMap = new HashMap();

 /**
  * Hinzufuegen bereits vorhandener Variablen. Anstatt neue Variablen
  * zu erzeugen, werden so die Referenzen bestehender Objekte
  * verwendet.
  * @param variablesMap HashMap
  */
  public void addVariablesMap(HashMap variablesMap) {
    this.parserVariablesMap.putAll(variablesMap);
  }

 /**
  * Gibt den gescannten und geparsten Ausdruck als Expression zurueck.
  * @return Expression
  */
  public Expression expression() {
    return action_obj.expression;
  }

:};

init with {:

  // Die in "parser" bereits befindlichen Variablenreferenzen in das
  // "action_obj" uebertragen. Dies muss hier separat geschehen, da
  // erst waehrend der "init"-Phase das "action_obj" instantiiert ist.
  action_obj.actionVariablesMap.putAll(this.parserVariablesMap);

:};

/* Terminals (tokens returned by the scanner). */
terminal          UMINUS, SEMI, LPAREN, RPAREN, COMMA, LBRACKET, RBRACKET;
terminal          PLUS, MINUS, TIMES, DIVIDE;
terminal          EQUAL, NOT_EQUAL, GREATER, LOWER, GREATER_EQUAL, LOWER_EQUAL;
terminal Integer  NUMBER;
terminal Double   FLOAT;
terminal String   VARIABLE;

/* Non Terminals */
non terminal             expr_all;
non terminal Expression  expr_list, expr, expr_part;

/* Precedences */
precedence left EQUAL, NOT_EQUAL, GREATER, LOWER, GREATER_EQUAL, LOWER_EQUAL;
precedence left PLUS, MINUS;
precedence left TIMES, DIVIDE;
precedence left UMINUS;

/* The grammar */

expr_all   ::= expr_list:e
               {:
                System.out.println(" => "+e.toString());
                this.expression = e;
               :}
             ;

expr_list  ::= expr:e
               {: RESULT = e; :}
             | expr_list:l expr:r
               {: RESULT = new BinaryOperator(sym.SEMI, ";", l, r); :}
             ;

expr       ::= expr_part:l EQUAL expr_part:r SEMI
               {: RESULT = new BinaryOperator(sym.EQUAL, "=", l, r); :}
             | expr_part:l NOT_EQUAL expr_part:r SEMI
               {: RESULT = new BinaryOperator(sym.NOT_EQUAL, "!=", l, r); :}
             | expr_part:l GREATER expr_part:r SEMI
               {: RESULT = new BinaryOperator(sym.GREATER, ">", l, r); :}
             | expr_part:l LOWER expr_part:r SEMI
               {: RESULT = new BinaryOperator(sym.LOWER, "<", l, r); :}
             | expr_part:l GREATER_EQUAL expr_part:r SEMI
               {: RESULT = new BinaryOperator(sym.GREATER_EQUAL, ">=", l, r); :}
             | expr_part:l LOWER_EQUAL expr_part:r SEMI
               {: RESULT = new BinaryOperator(sym.LOWER_EQUAL, "<=", l, r); :}
             ;

expr_part  ::= NUMBER:n
               {: RESULT = new Constant(n); :}
             | LBRACKET FLOAT:lo COMMA FLOAT:hi RBRACKET
               {: RESULT = new Constant(lo, hi); :}
             | LBRACKET NUMBER:lo COMMA NUMBER:hi RBRACKET
               {: RESULT = new Constant(lo.doubleValue(), hi.doubleValue()); :}
             | LBRACKET FLOAT:lo COMMA NUMBER:hi RBRACKET
               {: RESULT = new Constant(lo.doubleValue(), hi.doubleValue()); :}
             | LBRACKET NUMBER:lo COMMA FLOAT:hi RBRACKET
               {: RESULT = new Constant(lo.doubleValue(), hi.doubleValue()); :}
             | VARIABLE:v
               {: tmpVariable = (Variable)actionVariablesMap.get(v);
                  if (tmpVariable == null) {
                    // Variable mit leerer Domaene instantiieren:
                    tmpVariable = new Variable(v, new Domain());
                    actionVariablesMap.put(v, tmpVariable);
                  }
                  RESULT = tmpVariable;
               :}
             | expr_part:l PLUS expr_part:r
               {: RESULT = new BinaryOperator(sym.PLUS, "+", l, r); :}
             | expr_part:l MINUS expr_part:r
               {: RESULT = new BinaryOperator(sym.MINUS, "-", l, r); :}
             | expr_part:l TIMES expr_part:r
               {: RESULT = new BinaryOperator(sym.TIMES, "*", l, r); :}
             | expr_part:l DIVIDE expr_part:r
               {: RESULT = new BinaryOperator(sym.DIVIDE, "/", l, r); :}
             | MINUS expr_part:e
               {: RESULT = new UnaryOperator(sym.UMINUS, "-", e); :}
               %prec UMINUS
             | LPAREN expr_part:e RPAREN
               {: RESULT = e; :}
             ;


next up previous contents index
Nächste Seite: E. YACS API-Dokumentation Aufwärts: Diplom Vorherige Seite: C. Constraint-Lösungsstrategien   Inhalt   Index