Hi

During the conversation with Kay earlier I realised that it is
easily possible to make rules with only complex expressions work.

Currently a rule such as the following would give an error:

  tagname ~ 'blue.*' [ 0x1 ...]
  tagname < 10       [ 0x1 ...]

They can be converted automatically to a form that will work eg:

  tagname=* & tagname~'blue.*' [ 0x1 ...]

The attached patch does this.

..Steve
Index: src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java	(revision 2273)
+++ src/uk/me/parabola/mkgmap/osmstyle/RuleFileReader.java	(revision )
@@ -26,10 +26,12 @@
 import uk.me.parabola.mkgmap.osmstyle.actions.ActionReader;
 import uk.me.parabola.mkgmap.osmstyle.eval.AndOp;
 import uk.me.parabola.mkgmap.osmstyle.eval.BinaryOp;
+import uk.me.parabola.mkgmap.osmstyle.eval.ExistsOp;
 import uk.me.parabola.mkgmap.osmstyle.eval.ExpressionReader;
 import uk.me.parabola.mkgmap.osmstyle.eval.LinkedOp;
 import uk.me.parabola.mkgmap.osmstyle.eval.Op;
 import uk.me.parabola.mkgmap.osmstyle.eval.OrOp;
+import uk.me.parabola.mkgmap.osmstyle.eval.ValueOp;
 import uk.me.parabola.mkgmap.reader.osm.GType;
 import uk.me.parabola.mkgmap.reader.osm.Rule;
 import uk.me.parabola.mkgmap.scan.SyntaxException;
@@ -347,7 +349,15 @@
 			saveRestOfOr(actions, gt, second, op1);
 			return;
 		} else {
-			throw new SyntaxException(scanner, "Invalid operation '" + op.getType() + "' at top level");
+			// We can make every other binary op work by converting to AND(EXISTS, op)
+			Op existsOp = new ExistsOp();
+			existsOp.setFirst(new ValueOp(op.getFirst().value()));
+
+			AndOp andOp = new AndOp();
+			andOp.setFirst(existsOp);
+			andOp.setSecond(op);
+			optimiseAndSaveBinaryOp(andOp, actions, gt);
+			return;
 		}
 
 		createAndSaveRule(keystring, op, actions, gt);
Index: test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
--- test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java	(revision 2273)
+++ test/uk/me/parabola/mkgmap/osmstyle/RuleFileReaderTest.java	(revision )
@@ -326,6 +326,43 @@
 	}
 
 	/**
+	 * Some operations could not originally be used by themselves but now they are converted
+	 * into expressions that can be handled automatically. The following few tests verify this.
+	 */
+	@Test
+	public void testRegexAtTop() {
+		RuleSet rs = makeRuleSet("QUOTA ~ ' [05]00\\.0+' [0x2]");
+		Element el = new Way(1);
+		el.addTag("QUOTA", " 500.0");
+
+		GType type = getFirstType(rs, el);
+		assertNotNull(type);
+		assertEquals(2, type.getType());
+	}
+
+	@Test
+	public void testNEAtTop() {
+		RuleSet rs = makeRuleSet("QUOTA != 'fred' [0x2]");
+		Element el = new Way(1);
+		el.addTag("QUOTA", "tom");
+
+		GType type = getFirstType(rs, el);
+		assertNotNull(type);
+		assertEquals(2, type.getType());
+	}
+
+	@Test
+	public void testNumberOpAtTop() {
+		RuleSet rs = makeRuleSet("QUOTA > 10 [0x1] QUOTA < 6 [0x2]");
+		Element el = new Way(1);
+		el.addTag("QUOTA", "2");
+
+		GType type = getFirstType(rs, el);
+		assertNotNull(type);
+		assertEquals(2, type.getType());
+	}
+
+	/**
 	 * This simply is to make sure that actions that affect their own
 	 * conditions do not hang. There are no defined semantics for this.
 	 */
_______________________________________________
mkgmap-dev mailing list
[email protected]
http://www.mkgmap.org.uk/mailman/listinfo/mkgmap-dev

Reply via email to