Index: mapparser.y
===================================================================
--- mapparser.y	(revision 11667)
+++ mapparser.y	(working copy)
@@ -46,7 +46,7 @@
 %left INTERSECTS DISJOINT TOUCHES OVERLAPS CROSSES WITHIN CONTAINS BEYOND DWITHIN
 %left AREA LENGTH COMMIFY ROUND
 %left TOSTRING
-%left YYBUFFER
+%left YYBUFFER DIFFERENCE
 %left '+' '-'
 %left '*' '/' '%'
 %left NEG
@@ -544,6 +544,16 @@
       s->scratch = MS_TRUE;
       $$ = s;
     }
+  | DIFFERENCE '(' shape_exp ',' shape_exp ')' {
+      shapeObj *s;
+      s = msGEOSDifference($3, $5);
+      if(!s) {
+        yyerror(p, "Executing difference failed.");
+        return(-1);
+      }
+      s->scratch = MS_TRUE;
+      $$ = s;
+    }
 ;
 
 string_exp: STRING
@@ -655,6 +665,7 @@
   case MS_TOKEN_FUNCTION_ROUND: token = ROUND; break;
 
   case MS_TOKEN_FUNCTION_BUFFER: token = YYBUFFER; break;
+  case MS_TOKEN_FUNCTION_DIFFERENCE: token = DIFFERENCE; break;
 
   default:
     break;
Index: mapserver.h
===================================================================
--- mapserver.h	(revision 11667)
+++ mapserver.h	(working copy)
@@ -621,7 +621,7 @@
 };
 enum MS_TOKEN_FUNCTION_ENUM { 
   MS_TOKEN_FUNCTION_LENGTH=140, MS_TOKEN_FUNCTION_TOSTRING, MS_TOKEN_FUNCTION_COMMIFY, MS_TOKEN_FUNCTION_AREA, MS_TOKEN_FUNCTION_ROUND, MS_TOKEN_FUNCTION_FROMTEXT, 
-  MS_TOKEN_FUNCTION_BUFFER
+  MS_TOKEN_FUNCTION_BUFFER, MS_TOKEN_FUNCTION_DIFFERENCE
 };
 enum MS_TOKEN_BINDING_ENUM { MS_TOKEN_BINDING_DOUBLE=150, MS_TOKEN_BINDING_INTEGER, MS_TOKEN_BINDING_STRING, MS_TOKEN_BINDING_TIME, MS_TOKEN_BINDING_SHAPE };
 enum MS_PARSE_TYPE_ENUM { MS_PARSE_TYPE_BOOLEAN, MS_PARSE_TYPE_STRING, MS_PARSE_TYPE_SHAPE };
Index: maplexer.l
===================================================================
--- maplexer.l	(revision 11667)
+++ maplexer.l	(working copy)
@@ -184,6 +184,7 @@
 <EXPRESSION_STRING>round                       { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_ROUND); }
 
 <EXPRESSION_STRING>buffer                      { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_BUFFER); }
+<EXPRESSION_STRING>difference                  { MS_LEXER_RETURN_TOKEN(MS_TOKEN_FUNCTION_DIFFERENCE); }
 
 <EXPRESSION_STRING>intersects                  { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_INTERSECTS); }
 <EXPRESSION_STRING>disjoint                    { MS_LEXER_RETURN_TOKEN(MS_TOKEN_COMPARISON_DISJOINT); }
