anchor.diff:  	;
   
   valueExpr throws XPathException
  -:
  -	pathExpr (BANG^ pathExpr)*
  +{ Boolean inFunctionBodyState = lexer.inFunctionBody; }
  +:
  +	pathExpr (
  +	    BANG^
  +	    {
  +	        // simple map operator might add new document context
  +	        lexer.inFunctionBody = false;
  +        }
  +	    pathExpr
  +	    {
  +	        // reset state
  +	        lexer.inFunctionBody = inFunctionBodyState;
  +        }
  +    )*
   	|
   	extensionExpr
   	;
  
positive.code: 	relativePathExpr
  	|
  	( SLASH relativePathExpr )
  	=> SLASH relPath:relativePathExpr
  	{ #pathExpr= #(#[ABSOLUTE_SLASH, "AbsoluteSlash"], #relPath); }
  	// lone slash
  	|
  	SLASH
  	{ #pathExpr= #[ABSOLUTE_SLASH, "AbsoluteSlash"]; }
  	|
  	DSLASH relPath2:relativePathExpr
  	{ #pathExpr= #(#[ABSOLUTE_DSLASH, "AbsoluteSlashSlash"], #relPath2); }
  	;
  
  relativePathExpr throws XPathException
  
negative.code: :
      ( LCURLY RCURLY ) => l:LCURLY^ RCURLY!
      { #functionBody= #(#l, #(#[PARENTHESIZED, "Parenthesized"], null)); }
      | LCURLY^
      { lexer.inFunctionBody = true; }
      expr
      { lexer.inFunctionBody = false; }
      RCURLY!
      ;
  
  returnType throws XPathException:
  