/*
* File: UnfinishedCond.java
* Author: Lukas K�nig
* Java version: 6.0
* Generated: 01.08.2008
*
* (c) Lukas K�nig, copyright according to GNU Lesser General Public License
* (LGPL) -> http://www.gnu.org/licenses/lgpl.html
*/
package fmg.fmg8.endlAutomat.script;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.Set;
import java.util.Stack;
import fmg.fmg8.endlAutomat.conditions.CompLeaf;
import fmg.fmg8.endlAutomat.conditions.Condition;
import fmg.fmg8.endlAutomat.conditions.ConstLeaf;
import fmg.fmg8.endlAutomat.conditions.InnerNode;
/**
* @author Lukas K�nig
*
*/
public class UnfinishedCond {
/**
* The possibly unfinished condition.
*/
private Stack<Condition> stack;
/**
* The temporarily stored elements of a comparison.
*
* [ OperandNV | OperandNV ]
*/
private Integer[] miniStack;
/**
* The actually incoming stream of tokens.
*/
private LinkedList<Integer> actualData;
/**
* The Class consisting of the Operands number / variable.
*/
private HashSet<Integer> tcOperandsNV;
/**
* The Class consisting of the Operand const.
*/
private HashSet<Integer> tcOperandConst;
/**
* The Class consisting of the Comparator.
*/
private HashSet<Integer> tcComparator;
/**
* The Class consisting of the Operator.
*/
private HashSet<Integer> tcOperator;
/**
* Constructor.
*/
public UnfinishedCond() {
this.tcOperandsNV = new HashSet<Integer>();
this.tcOperandConst = new HashSet<Integer>();
this.tcComparator = new HashSet<Integer>();
this.tcOperator = new HashSet<Integer>();
this.miniStack = new Integer[2];
this.initMiniStack();
this.stack = new Stack<Condition>();
this.actualData = new LinkedList<Integer>();
this.tcOperandsNV.add(Const.clNum("OperandNumber"));
this.tcOperandsNV.add(Const.clNum("OperandVariable"));
this.tcOperandConst.add(Const.clNum("OperandConstant"));
this.tcComparator.add(Const.clNum("Comparator"));
this.tcOperator.add(Const.clNum("Operator"));
}
/**
* Adds a token to the condition.
*
* @param token The token to add.
*/
public void nextToken(final Integer token) {
Condition cond, condL, condR;
if (this.tokenIsInClasses(token, this.possibleClasses())) {
this.actualData.add(token);
// MiniOperand
if (this.tokenIsInClasses(token, this.tcOperandsNV)) {
if (this.miniStack[0] <= 0) {
this.miniStack[0] = token;
} else {
this.miniStack[1] = token;
}
}
// Comparator
if (this.tokenIsInClasses(token, this.tcComparator)) {
int operand1;
int operand2;
boolean variable1 = this.tokenIsInClass(this.miniStack[0],
Const.clNum("OperandVariable"));
boolean variable2 = this.tokenIsInClass(this.miniStack[1],
Const.clNum("OperandVariable"));
char comparator = this.actualValue(token).charAt(0);
if (variable1) {
operand1 = Integer.parseInt(
this.actualValue(this.miniStack[0]).substring(1));
} else {
operand1 = Integer.parseInt(
this.actualValue(this.miniStack[0]));
}
if (variable2) {
operand2 = Integer.parseInt(
this.actualValue(this.miniStack[1]).substring(1));
} else {
operand2 = Integer.parseInt(
this.actualValue(this.miniStack[1]));
}
cond = new CompLeaf(operand1,
operand2,
variable1,
variable2,
comparator);
this.stack.push(cond);
this.initMiniStack();
}
// Operand
if (this.tokenIsInClasses(token, this.tcOperandConst)) {
char value = this.actualValue(token).charAt(0);
if (value == fmg.fmg8.endlAutomat.Konstanten.FALSE) {
cond = new ConstLeaf(false);
} else {
cond = new ConstLeaf(true);
}
this.stack.push(cond);
}
// Operator
if (this.tokenIsInClasses(token, this.tcOperator)) {
char value = this.actualValue(token).charAt(0);
condR = this.stack.pop();
condL = this.stack.pop();
cond = new InnerNode(condL, condR, value);
this.stack.push(cond);
}
} else {
throw new RuntimeException("The token "
+ token
+ " is invalid after this: "
+ this.actualData);
}
}
/**
* Returns the actual value of the token.
*
* @param tok The token to get.
*
* @return The actual value.
*/
public String actualValue(final Integer tok) {
int tc = this.tokenClass(tok).intValue();
int token = tok.intValue();
if (tc == Const.clNum("OperandNumber")) {
// Number
return "" + token;
}
if (tc == Const.clNum("OperandConstant")) {
// Constant
if (token == Const.CL_BORDERS[tc]) {
return "" + fmg.fmg8.endlAutomat.Konstanten.FALSE;
} else {
return "" + fmg.fmg8.endlAutomat.Konstanten.TRUE;
}
}
if (tc == Const.clNum("OperandVariable")) {
// Variable
return "h"
+ (token
- Const.CL_BORDERS[Const.clNum("OperandVariable")
- 1]);
}
if (tc == Const.clNum("Comparator")) {
// Comparator
if (token == Const.CL_BORDERS[tc]) {
return "" + fmg.fmg8.endlAutomat.Konstanten.GL;
}
if (token == Const.CL_BORDERS[tc] - 1) {
return "" + fmg.fmg8.endlAutomat.Konstanten.UNGF;
}
if (token == Const.CL_BORDERS[tc] - 2) {
return "" + fmg.fmg8.endlAutomat.Konstanten.KLGL;
}
if (token == Const.CL_BORDERS[tc] - 3) {
return "" + fmg.fmg8.endlAutomat.Konstanten.GRGL;
}
if (token == Const.CL_BORDERS[tc] - 4) {
return "" + fmg.fmg8.endlAutomat.Konstanten.KL;
}
if (token == Const.CL_BORDERS[tc] - 5) {
return "" + fmg.fmg8.endlAutomat.Konstanten.GR;
}
if (token == Const.CL_BORDERS[tc] - 6) {
return "" + fmg.fmg8.endlAutomat.Konstanten.NUNGF;
}
if (token == Const.CL_BORDERS[tc] - 7) {
return "" + fmg.fmg8.endlAutomat.Konstanten.UGL;
}
}
if (tc == Const.clNum("Operator")) {
// Operator
if (token == Const.CL_BORDERS[tc]) {
return "" + fmg.fmg8.endlAutomat.Konstanten.ODER;
} else {
return "" + fmg.fmg8.endlAutomat.Konstanten.UND;
}
}
return "" + -1;
}
/**
* Returns the actual token of the value.
*
* @param value The value to get.
*
* @return The actual token.
*/
public Integer actualToken(final String value) {
char beg = value.charAt(0);
// Number
if (beg == '0' || beg == '1' || beg == '2' || beg == '3' || beg == '4'
|| beg == '5' || beg == '6' || beg == '7' || beg == '8'
|| beg == '9') {
return Integer.parseInt(value);
}
// Constant
if (beg == fmg.fmg8.endlAutomat.Konstanten.FALSE) {
return Const.CL_BORDERS[Const.clNum("OperandConstant")];
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.TRUE) {
return Const.CL_BORDERS[Const.clNum("OperandConstant")]
- 1;
}
// Variable
if (beg == fmg.fmg8.endlAutomat.Konstanten.EING) {
return Integer.parseInt(value.substring(1))
+ Const.CL_BORDERS[Const.clNum("OperandVariable")
- 1];
}
// Comparator
if (beg == fmg.fmg8.endlAutomat.Konstanten.GL) {
return Const.CL_BORDERS[Const.clNum("Comparator")];
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.UNGF) {
return Const.CL_BORDERS[Const.clNum("Comparator")] - 1;
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.KLGL) {
return Const.CL_BORDERS[Const.clNum("Comparator")] - 2;
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.GRGL) {
return Const.CL_BORDERS[Const.clNum("Comparator")] - 3;
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.KL) {
return Const.CL_BORDERS[Const.clNum("Comparator")] - 4;
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.GR) {
return Const.CL_BORDERS[Const.clNum("Comparator")] - 5;
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.NUNGF) {
return Const.CL_BORDERS[Const.clNum("Comparator")] - 6;
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.UGL) {
return Const.CL_BORDERS[Const.clNum("Comparator")] - 7;
}
// Operator
if (beg == fmg.fmg8.endlAutomat.Konstanten.UND) {
return Const.CL_BORDERS[Const.clNum("Operator")] - 1;
}
if (beg == fmg.fmg8.endlAutomat.Konstanten.ODER) {
return Const.CL_BORDERS[Const.clNum("Operator")];
}
return -1;
}
/**
* Sets all elements of ministack to 0.
*/
private void initMiniStack() {
for (int i = 0; i < this.miniStack.length; i++) {
this.miniStack[i] = 0;
}
}
/**
* Checks whether a token is in a specified class.
*
* @param token The token to check.
* @param tokenClass The class.
*
* @return Iff the token is in the class.
*/
public boolean tokenIsInClass(final Integer token,
final Integer tokenClass) {
return (tokenClass == 0 && Const.CL_BORDERS[0] >= token)
|| (Const.CL_BORDERS[tokenClass.intValue()] >= token
&& Const.CL_BORDERS[tokenClass.intValue() - 1] < token);
}
/**
* Checks wether a token is in a specified set of classes.
*
* @param token The token to check.
* @param tokenClasses The set of classes.
*
* @return Iff the token belongs to one of the classes.
*/
public boolean tokenIsInClasses(final Integer token,
final Set<Integer> tokenClasses) {
if (tokenClasses == null) {
return false;
}
for (Integer tokClass : tokenClasses) {
if (this.tokenIsInClass(token, tokClass)) {
return true;
}
}
return false;
}
/**
* Returns the tokenclass corresponding to a given token.
*
* @param token The token to link to a class.
*
* @return The tokenclass corresponding to a given token.
*/
public Integer tokenClass(final Integer token) {
for (int i = 0; i < Const.CL_BORDERS.length; i++) {
if (this.tokenIsInClass(token, new Integer(i))) {
return new Integer(i);
}
}
return new Integer(-1);
}
/**
* Returns the name of a tokenClass.
*
* @param tokenClass The tokenClass to get.
* @return The name of a tokenClass.
*/
public String className(final Integer tokenClass) {
return Const.CLASS_NAMES[tokenClass.intValue()];
}
/**
* Returns a list of possible tokenclasses that can be inserted next into
* condition.
*
* @return List of possible tokens.
*/
public Set<Integer> possibleClasses() {
Set<Integer> tokenClasses = new HashSet<Integer>();
Integer miniOp1 = this.miniStack[0];
Integer miniOp2 = this.miniStack[1];
// MiniStack = [OperandNV | OperandNV]
if (miniOp1 > 0 && miniOp2 > 0) {
tokenClasses.addAll(this.tcComparator);
return tokenClasses;
}
// MiniStack = [ OperandNV | 0 ]
if (miniOp1 > 0) {
tokenClasses.addAll(this.tcOperandsNV);
return tokenClasses;
}
// MiniStack = [ 0 | 0 ]
tokenClasses.addAll(this.tcOperandsNV);
tokenClasses.addAll(this.tcOperandConst);
if (this.stack.size() >= 2) {
tokenClasses.addAll(this.tcOperator);
}
return tokenClasses;
}
/**
* @return The condition if the condition is finished, null otherwise.
*/
public Condition finishedCond() {
if (this.miniStack[0] <= 0
&& this.miniStack[1] <= 0
&& this.stack.size() == 1) {
return this.stack.get(0);
} else {
return null;
}
}
/**
* @return String-Output.
*/
@Override
public String toString() {
String s = "";
s += "Stack: [";
for (int i = 0; i < this.stack.size(); i++) {
s += "{" + this.stack.get(i) + "}";
if (i != this.stack.size() - 1) {
s += ", ";
}
}
s += "]\n";
s += "Ministack: ["
+ this.miniStack[0]
+ " ("
+ this.actualValue(this.miniStack[0])
+ "), "
+ this.miniStack[1]
+ " ("
+ this.actualValue(this.miniStack[1])
+ ")]\n";
s += "Data stream: ";
for (int i = 0; i < this.actualData.size(); i++) {
s += this.actualData.get(i)
+ " ("
+ this.actualValue(this.actualData.get(i))
+ "); ";
}
s += "\nFinished Condition: " + this.finishedCond();
return s;
}
}