use of uk.me.parabola.mkgmap.scan.SyntaxException in project mkgmap by openstreetmap.
the class ActionReader method readAccessValue.
/**
* Read a tag/value pair. If the action is executed then the tag name
* will possibly be modified or set. If that is the case then we will
* have to make sure that we are executing rules for that tag.
*
* @param modify If true the tag value can be modified. If it is not set
* then a tag can only be added; if it already exists, then it will not
* be changed.
* @param changeableTags Tags that could be changed by the action. This is
* an output parameter, any such tags should be added to this set.
* @return The new add tag action.
*/
private AddAccessAction readAccessValue(boolean modify, Set<String> changeableTags) {
AddAccessAction action = null;
do {
if (!inActionCmd())
throw new SyntaxException(scanner, "unexpected end of access list");
String val = scanner.nextWord();
if (!VALID_ACCESS.contains(val) && !val.contains("$"))
throw new SyntaxException(scanner, "expected yes/no for set/addaccess, got '" + val + "'");
if (action == null)
action = new AddAccessAction(val, modify);
else
action.add(val);
// value will be. Otherwise save the full tag=value
if (val.contains("$")) {
changeableTags.addAll(ACCESS_TAGS.keySet());
} else {
for (String accessTag : ACCESS_TAGS.keySet()) changeableTags.add(accessTag + "=" + val);
}
} while (hasMoreWords());
usedTags.addAll(action.getUsedTags());
return action;
}
use of uk.me.parabola.mkgmap.scan.SyntaxException in project mkgmap by openstreetmap.
the class ExpressionReader method saveFunction.
/**
* Lookup a function by its name and check that it is allowed for the kind of features that we
* are reading.
*
* @param functionName A name to look up.
*/
private void saveFunction(String functionName) {
StyleFunction function = FunctionFactory.createFunction(functionName);
if (function == null)
throw new SyntaxException(String.format("No function with name '%s()'", functionName));
// TODO: supportsWay split into supportsPoly{line,gon}, or one function supports(kind)
boolean supported = false;
switch(kind) {
case POINT:
if (function.supportsNode())
supported = true;
break;
case POLYLINE:
if (function.supportsWay())
supported = true;
break;
case POLYGON:
if (function.supportsWay())
supported = true;
break;
case RELATION:
if (function.supportsRelation())
supported = true;
break;
case ALL:
if (function.supportsNode() || function.supportsWay() || function.supportsRelation())
supported = true;
break;
}
if (!supported)
throw new SyntaxException(String.format("Function '%s()' not supported for %s", functionName, kind));
stack.push(function);
}
use of uk.me.parabola.mkgmap.scan.SyntaxException in project mkgmap by openstreetmap.
the class ExpressionReader method readConditions.
/**
* Read the conditions. They are terminated by a '[' or '{' character
* or by end of file.
* @param ifStack expressions of enclosing if / else
*/
public Op readConditions(Collection<Op[]> ifStack) {
boolean consumedNonBlank = false;
while (!scanner.isEndOfFile()) {
scanner.skipSpace();
if (scanner.checkToken("[") || scanner.checkToken("{") || scanner.checkToken("then"))
break;
consumedNonBlank = true;
WordInfo wordInfo = scanner.nextWordWithInfo();
if (isOperation(wordInfo)) {
saveOp(wordInfo.getText());
} else if (wordInfo.isQuoted()) {
pushValue(wordInfo.getText());
} else if (wordInfo.getText().charAt(0) == '$') {
String tagname = scanner.nextWord();
if (tagname.equals("{")) {
tagname = scanner.nextWord();
scanner.validateNext("}");
}
stack.push(new GetTagFunction(tagname));
} else if (scanner.checkToken("(")) {
// it is a function
// this requires a () after the function name
scanner.validateNext("(");
scanner.validateNext(")");
saveFunction(wordInfo.getText());
} else {
pushValue(wordInfo.getText());
}
}
// Complete building the tree
while (!opStack.isEmpty()) runOp(scanner);
if (consumedNonBlank && !ifStack.isEmpty() && stack.size() <= 1) {
// add expressions from enclosing if /else statements
Op op = null;
if (!stack.isEmpty())
op = stack.pop();
stack.push(appendIfExpr(op, ifStack));
}
// The stack should contain one entry which is the complete tree
if (stack.size() != 1) {
throw new SyntaxException(scanner, "Stack size is " + stack.size() + " (missing or incomplete expression)");
}
assert stack.size() == 1;
Op op = stack.pop();
if (op instanceof ValueOp)
throw new SyntaxException(scanner, "Incomplete expression, just a single symbol: " + op);
return op;
}
use of uk.me.parabola.mkgmap.scan.SyntaxException in project mkgmap by openstreetmap.
the class ExpressionReader method runOp.
/**
* Combine the operation at the top of its stack with its values.
* @param scanner The token scanner; used for line numbers.
*/
private void runOp(TokenScanner scanner) {
Op op = opStack.pop();
log.debug("Running op...", op.getType());
if (op instanceof BinaryOp) {
if (stack.size() < 2) {
throw new SyntaxException(scanner, String.format("Not enough arguments for '%s' operator", op.getType().toSymbol()));
}
Op arg2 = stack.pop();
Op arg1 = stack.pop();
if (arg1.isType(VALUE))
/*&& arg2.isType(VALUE)*/
arg1 = new GetTagFunction(arg1.getKeyValue());
// Deal with the case where you have: a & b=2. The 'a' is a syntax error in this case.
if (op.isType(OR) || op.isType(AND)) {
if (arg1.isType(VALUE) || arg1.isType(FUNCTION))
throw new SyntaxException(scanner, String.format("Value '%s' is not part of an expression", arg1));
if (arg2.isType(VALUE) || arg2.isType(FUNCTION))
throw new SyntaxException(scanner, String.format("Value '%s' is not part of an expression", arg2));
} else {
// type too.
if (!(arg1.isType(VALUE) || arg1.isType(FUNCTION)) || !(arg2.isType(VALUE) || arg2.isType(FUNCTION))) {
String msg = String.format("Invalid arguments to %s: %s (%s) and %s (%s)", op.getType(), arg1.getType(), arg1, arg2.getType(), arg2);
throw new SyntaxException(scanner, msg);
}
}
BinaryOp binaryOp = (BinaryOp) op;
binaryOp.setFirst(arg1);
binaryOp.setSecond(arg2);
// The combination foo=* is converted to exists(foo).
if (op.isType(EQUALS) && arg2.isType(VALUE) && ((ValueOp) arg2).isValue("*")) {
log.debug("convert to EXISTS");
op = new ExistsOp();
op.setFirst(arg1);
} else if (op.isType(NOT_EQUALS) && arg2.isType(VALUE) && ((ValueOp) arg2).isValue("*")) {
log.debug("convert to NOT EXISTS");
op = new NotExistsOp();
op.setFirst(arg1);
}
} else if (!op.isType(OPEN_PAREN)) {
if (stack.size() < 1)
throw new SyntaxException(scanner, String.format("Missing argument for %s operator", op.getType().toSymbol()));
op.setFirst(stack.pop());
}
Op first = op.getFirst();
if (first == null)
throw new SyntaxException(scanner, "Invalid expression");
if (first.isType(FUNCTION) && first.getKeyValue() != null) {
usedTags.add(first.getKeyValue());
}
stack.push(op);
}
use of uk.me.parabola.mkgmap.scan.SyntaxException in project mkgmap by openstreetmap.
the class UnitConversions method createConversion.
/**
* Create a converter between the units given in the {@code code} argument.
*
* This will be something like m=>ft to convert from meters to feet. If the input is a plain
* value such as 10, then the input is in meters and it is converted to feet. If the
* input already has a unit, eg 10ft, then the conversion will be from that unit to
* the target unit. So in this case, since the input is already in feet, then result is 10.
*
* @param code A specifier from=>to.
*/
public static UnitConversions createConversion(String code) {
Matcher matcher = CODE_RE.matcher(code);
if (!matcher.matches())
throw new SyntaxException(String.format("Unrecognised unit conversion: '%s'", code));
String source = matcher.group(1);
String target = matcher.group(2);
return new UnitConversions(source, target);
}
Aggregations