Index: trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 516)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchAction.java	(revision 517)
@@ -85,18 +85,22 @@
     		}
     	}
-    	Collection<OsmPrimitive> sel = Main.ds.getSelected();
-    	SearchCompiler.Match matcher = SearchCompiler.compile(search, caseSensitive);
-    	for (OsmPrimitive osm : Main.ds.allNonDeletedPrimitives()) {
-    		if (mode == SearchMode.replace) {
-    			if (matcher.match(osm))
-    				sel.add(osm);
-    			else
-    				sel.remove(osm);
-    		} else if (mode == SearchMode.add && !osm.selected && matcher.match(osm))
-    			sel.add(osm);
-    		else if (mode == SearchMode.remove && osm.selected && matcher.match(osm))
-    			sel.remove(osm);
-    	}
-    	Main.ds.setSelected(sel);
+		try {
+			Collection<OsmPrimitive> sel = Main.ds.getSelected();
+			SearchCompiler.Match matcher = SearchCompiler.compile(search, caseSensitive);
+			for (OsmPrimitive osm : Main.ds.allNonDeletedPrimitives()) {
+				if (mode == SearchMode.replace) {
+					if (matcher.match(osm))
+						sel.add(osm);
+					else
+						sel.remove(osm);
+				} else if (mode == SearchMode.add && !osm.selected && matcher.match(osm))
+					sel.add(osm);
+				else if (mode == SearchMode.remove && osm.selected && matcher.match(osm))
+					sel.remove(osm);
+			}
+			Main.ds.setSelected(sel);
+		} catch (SearchCompiler.ParseError e) {
+			JOptionPane.showMessageDialog(Main.parent, e.getMessage());
+		}
     }
 }
Index: trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java
===================================================================
--- trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 516)
+++ trunk/src/org/openstreetmap/josm/actions/search/SearchCompiler.java	(revision 517)
@@ -165,6 +165,13 @@
 		@Override public String toString() {return "incomplete";}
 	}
+
+	public static class ParseError extends Exception {
+		public ParseError(String msg) {
+			super(msg);
+		}
+	}
 	
-	public static Match compile(String searchStr, boolean caseSensitive) {
+	public static Match compile(String searchStr, boolean caseSensitive)
+			throws ParseError {
 		return new SearchCompiler(caseSensitive,
 				new PushbackTokenizer(
@@ -173,13 +180,13 @@
 	}
 
-	public Match parse() {
+	public Match parse() throws ParseError {
 		Match m = parseJuxta();
 		if (!tokenizer.readIfEqual(null)) {
-			throw new RuntimeException("Unexpected token: " + tokenizer.nextToken());
+			throw new ParseError("Unexpected token: " + tokenizer.nextToken());
 		}
 		return m;
 	}
 
-	private Match parseJuxta() {
+	private Match parseJuxta() throws ParseError {
 		Match juxta = new Always();
 
@@ -192,10 +199,10 @@
 	}
 
-	private Match parseOr() {
+	private Match parseOr() throws ParseError {
 		Match a = parseNot();
 		if (tokenizer.readIfEqual("|")) {
 			Match b = parseNot();
 			if (a == null || b == null) {
-				throw new RuntimeException("Missing arguments for or.");
+				throw new ParseError("Missing arguments for or.");
 			}
 			return new Or(a, b);
@@ -204,9 +211,9 @@
 	}
 
-	private Match parseNot() {
+	private Match parseNot() throws ParseError {
 		if (tokenizer.readIfEqual("-")) {
 			Match m = parseParens();
 			if (m == null) {
-				throw new RuntimeException("Missing argument for not.");
+				throw new ParseError("Missing argument for not.");
 			}
 			return new Not(m);
@@ -215,9 +222,9 @@
 	}
 
-	private Match parseParens() {
+	private Match parseParens() throws ParseError {
 		if (tokenizer.readIfEqual("(")) {
 			Match m = parseJuxta();
 			if (!tokenizer.readIfEqual(")")) {
-				throw new RuntimeException("Expected closing paren");
+				throw new ParseError("Expected closing paren");
 			}
 			return m;
