package sorts;
import java.util.ArrayList;
import parser.ASTandCondition;
import parser.ASTcondition;
import parser.ASTorCondition;
import parser.ASTunaryCondition;
import parser.SimpleNode;
import parser.SparcTranslatorTreeConstants;
/**
* Condition parser
*
*/
enum TermType {
integer, identifier, functionalSymbol;
}
enum Relation {
EQUAL("="), GREATEROREQUAL(">="), GREATER(">"), SMALLER("<"), SMALLEROREQUAL(
"<="), NOTEQUAL("!=");
private String image;
Relation(String image) {
this.image = image;
}
public String toString() {
return image;
}
}
public class Condition {
/**
* Constructor, parses condition into class fields
*
* @param conditionString
* string to parse
*/
public Condition() {
}
/**
* Check condition on arguments
*
* @param cond
* AST node specifying the condition
* @param arguments
* @return true if the condition is satisfied and false otherwise
*/
public boolean check(ASTcondition cond, ArrayList<String> arguments) {
return checkCondition((ASTorCondition) cond.jjtGetChild(0), arguments);
}
/**
* Check condition (disjunction) on arguments
*
* @param cond
* AST node specifying the condition
* @param arguments
* @return true if the condition is satisfied and false otherwise
*/
private boolean checkCondition(ASTorCondition orCondition,
ArrayList<String> arguments) {
for (int i = 0; i < orCondition.jjtGetNumChildren(); i++) {
if (checkCondition((ASTandCondition) orCondition.jjtGetChild(i),
arguments)) {
return true;
}
}
return false;
}
/**
* Check condition (conjunction) on arguments
*
* @param cond
* AST node specifying the condition
* @param arguments
* @return true if the condition is satisfied and false otherwise
*/
private boolean checkCondition(ASTandCondition andCondition,
ArrayList<String> arguments) {
for (int i = 0; i < andCondition.jjtGetNumChildren(); i++) {
if (!checkCondition(
(ASTunaryCondition) andCondition.jjtGetChild(i), arguments)) {
return false;
}
}
return true;
}
/**
* Retrieve type of the term
*
* @param s
* string containint the term
*/
private TermType getTermType(String s) {
if (s.indexOf(')') != -1) {
return TermType.functionalSymbol;
} else {
for (int i = 0; i < s.length(); i++) {
if (!Character.isDigit(s.charAt(i))) {
return TermType.identifier;
}
}
return TermType.integer;
}
}
/**
* Check condition (relation or general condition) on arguments
*
* @param cond
* AST node specifying the condition
* @param arguments
* @return true if the condition is satisfied and false otherwise
*/
public boolean checkCondition(ASTunaryCondition unaryCond,
ArrayList<String> arguments) {
if (unaryCond.jjtGetNumChildren() == 1
&& ((SimpleNode) unaryCond.jjtGetChild(0)).getId() == SparcTranslatorTreeConstants.JJTCONDITION) {
if(unaryCond.image != null && unaryCond.image.trim().equals("not("))
return !check((ASTcondition) unaryCond.jjtGetChild(0), arguments);
else
return check((ASTcondition) unaryCond.jjtGetChild(0), arguments);
}
String[] relationArray = unaryCond.image.split(" ");
int arg1 = Integer.parseInt(relationArray[0]);
int arg2 = Integer.parseInt(relationArray[2]);
String relationString = relationArray[1];
Relation relation = null;
// parse relation
if (relationString.toString().equals("<")) {
relation = Relation.SMALLER;
} else if (relationString.toString().equals(">")) {
relation = Relation.GREATER;
} else if (relationString.toString().equals("!=")) {
relation = Relation.NOTEQUAL;
} else if (relationString.toString().equals(">=")) {
relation = Relation.GREATEROREQUAL;
} else if (relationString.toString().equals("<=")) {
relation = Relation.SMALLEROREQUAL;
} else if (relationString.toString().equals("=")) {
relation = Relation.EQUAL;
}
String argument1 = arguments.get(arg1);
String argument2 = arguments.get(arg2);
TermType type1 = getTermType(argument1);
TermType type2 = getTermType(argument2);
if (type1 != type2) {
if (relation != Relation.NOTEQUAL) {
return false;
} else {
return true;
}
}
else
switch (type1) {
case integer:
return checkIntegerRelation(relation,
Integer.parseInt(argument1),
Integer.parseInt(argument2));
case identifier:
return checkStringRelation(relation, argument1, argument2);
case functionalSymbol:
return checkFunctionalRelation(relation, argument1, argument2);
default:
return false;
}
}
private boolean checkFunctionalRelation(Relation relation, String f1,
String f2) {
switch (relation) {
case NOTEQUAL:
return f1.compareTo(f2) != 0;
case EQUAL:
return f1.compareTo(f2) == 0;
default:
return false;
}
}
private boolean checkIntegerRelation(Relation relation, int o1, int o2) {
switch (relation) {
case SMALLER:
return o1 < o2;
case GREATER:
return o1 > o2;
case NOTEQUAL:
return o1 != o2;
case GREATEROREQUAL:
return o1 >= o2;
case SMALLEROREQUAL:
return o1 <= o2;
case EQUAL:
return o1 == o2;
default:
return false;
}
}
private boolean checkStringRelation(Relation relation, String s1, String s2) {
switch (relation) {
case SMALLER:
return s1.compareTo(s2) < 0;
case GREATER:
return s1.compareTo(s2) > 0;
case NOTEQUAL:
return s1.compareTo(s2) != 0;
case GREATEROREQUAL:
return s1.compareTo(s2) >= 0;
case SMALLEROREQUAL:
return s1.compareTo(s2) <= 0;
case EQUAL:
return s1.compareTo(s2) == 0;
default:
return false;
}
}
}