use of uk.me.parabola.mkgmap.osmstyle.eval.Op in project mkgmap by openstreetmap.
the class ExpressionArranger method arrange.
public Op arrange(Op expr) {
log.debug("IN: " + fmtExpr(expr));
Op op = arrangeTop(expr);
log.debug("OUT: " + fmtExpr(expr));
return op;
}
use of uk.me.parabola.mkgmap.osmstyle.eval.Op in project mkgmap by openstreetmap.
the class ExpressionArranger method reAssociate.
/**
* Fix a chain of AND/OR nodes so that the chain is on the right.
*
* Eg: given (A&B)&(C&D) we return (A&(B&(C&D)))
*/
private void reAssociate(Op op, NodeType kind) {
assert op.isType(kind);
assert kind == OR || kind == AND;
// Rearrange ((A&B)&C) to (A&(B&C)).
while (op.getFirst().isType(kind)) {
Op aAndB = op.getFirst();
Op a = aAndB.getFirst();
Op b = aAndB.getSecond();
Op c = op.getSecond();
assert a != b;
assert a != c;
assert b != c;
BinaryOp and = AbstractOp.createOp(kind).set(b, c);
op.set(a, and);
}
}
use of uk.me.parabola.mkgmap.osmstyle.eval.Op in project mkgmap by openstreetmap.
the class ExpressionArranger method getKeystring.
/**
* Get the key string for this expression.
*
* We use a literal string such as highway=primary to index the rules. If it is not possible to find a key string,
* then the expression is not allowed. This should only happen with expression that could match an element with no
* tags.
*/
public String getKeystring(TokenScanner scanner, Op op) {
Op first = op.getFirst();
Op second = op.getSecond();
String keystring = null;
if (op.isType(EQUALS) && first.isType(FUNCTION) && second.isType(VALUE)) {
keystring = first.getKeyValue() + "=" + second.getKeyValue();
} else if (op.isType(EXISTS)) {
keystring = first.getKeyValue() + "=*";
} else if (op.isType(AND)) {
if (first.isType(EQUALS)) {
keystring = first.getFirst().getKeyValue() + "=" + first.getSecond().getKeyValue();
} else if (first.isType(EXISTS)) {
keystring = first.getFirst().getKeyValue() + "=*";
} else if (first.isType(NOT_EXISTS)) {
throw new SyntaxException(scanner, "Cannot start rule with tag!=*");
}
}
if (keystring == null)
throw new SyntaxException(scanner, "Invalid rule expression: " + op);
return keystring;
}
use of uk.me.parabola.mkgmap.osmstyle.eval.Op in project mkgmap by openstreetmap.
the class ExpressionArranger method isSolved.
/**
* True if this expression is 'solved'. This means that the first term is indexable or it is indexable itself.
*/
public static boolean isSolved(Op op) {
switch(op.getType()) {
case NOT:
return false;
case AND:
return isIndexable(op.getFirst());
case OR:
Op or = op;
boolean valid = true;
do {
if (!isAndIndexable(or.getFirst()))
valid = false;
or = or.getSecond();
} while (or.isType(OR));
if (!isAndIndexable(or))
valid = false;
return valid;
default:
return isIndexable(op);
}
}
use of uk.me.parabola.mkgmap.osmstyle.eval.Op in project mkgmap by openstreetmap.
the class RuleFileReader method loadFile.
/**
* Load a rules file. This should be used when calling recursively when including
* files.
*/
private void loadFile(StyleFileLoader loader, String name) throws FileNotFoundException {
Reader r = loader.open(name);
TokenScanner scanner = new TokenScanner(name, r);
scanner.setExtraWordChars("-:.");
ExpressionReader expressionReader = new ExpressionReader(scanner, kind);
ActionReader actionReader = new ActionReader(scanner);
// Read all the rules in the file.
scanner.skipSpace();
while (!scanner.isEndOfFile()) {
if (checkCommand(loader, scanner, expressionReader))
continue;
if (scanner.isEndOfFile())
break;
Op expr = expressionReader.readConditions(ifStack);
expr = arranger.arrange(expr);
ActionList actionList = actionReader.readActions();
checkIfStack(actionList);
if (performChecks && this.kind == FeatureKind.RELATION) {
String actionsString = actionList.getList().toString();
if (actionsString.contains("set mkgmap:stylefilter") || actionsString.contains("add mkgmap:stylefilter")) {
log.error("Style file", name, "should not set or add the special tag mkgmap:stylefilter:", actionsString);
}
}
List<GType> types = new ArrayList<>();
while (scanner.checkToken("[")) {
GType type = typeReader.readType(scanner, performChecks, overlays);
types.add(type);
scanner.skipSpace();
}
// If there is an action list, then we don't need a type
if (types.isEmpty() && actionList.isEmpty())
throw new SyntaxException(scanner, "No type definition given");
if (types.isEmpty())
saveRule(scanner, expr, actionList, null);
if (types.size() >= 2 && actionList.isModifyingTags()) {
throw new SyntaxException(scanner, "Combination of multiple type definitions with tag modifying action is not yet supported.");
}
for (int i = 0; i < types.size(); i++) {
GType type = types.get(i);
if (i + 1 < types.size()) {
type.setContinueSearch(true);
}
// No need to create a deep copy of expr
saveRule(scanner, expr, actionList, type);
actionList = new ActionList(Collections.emptyList(), Collections.emptySet());
}
}
rules.addUsedTags(expressionReader.getUsedTags());
rules.addUsedTags(actionReader.getUsedTags());
}
Aggregations