anchor.diff:    }
   
     MapExpression _map(Expression first, LineScannerState start) {
  -    var pairs = [new Pair(first, _spaceListOrExpression())];
  +    var pairs = [new Pair(first, _expressionUntilComma())];
   
       while (scanner.scanChar($comma)) {
         whitespace();
         if (!_lookingAtExpression()) break;
   
  -      var key = _spaceListOrExpression();
  +      var key = _expressionUntilComma();
         scanner.expectChar($colon);
         whitespace();
  -      var value = _spaceListOrExpression();
  +      var value = _expressionUntilComma();
         pairs.add(new Pair(key, value));
       }
   
       scanner.expectChar($rparen);
       return new MapExpression(pairs, scanner.spanFrom(start));
  +  }
  +
  +  Expression _hashExpression() {
  +    assert(scanner.peekChar() == $hash);
  +    return scanner.peekChar(1) == $lbrace ? _identifierLike() : _hexColorOrID();
  +  }
  +
  +  Expression _plusExpression() {
  +    assert(scanner.peekChar() == $plus);
  +    var next = scanner.peekChar(1);
  +    return isDigit(next) || next == $dot ? _number() : _unaryOperation();
  +  }
  +
  +  Expression _minusExpression() {
  +    assert(scanner.peekChar() == $minus);
  +    var next = scanner.peekChar(1);
  +    if (isDigit(next) || next == $dot) return _number();
  +    if (_lookingAtInterpolatedIdentifier()) return _identifierLike();
  +    return _unaryOperation();
     }
   
     UnaryOperationExpression _unaryOperation() {
  
positive.code:         return interpolatedString();
  
        case $hash:
          if (scanner.peekChar(1) == $lbrace) return _identifierLike();
          return _hexColorOrID();
  
        case $plus:
          var next = scanner.peekChar(1);
          if (isDigit(next) || next == $dot) return _number();
  
          return _unaryOperation();
  
        case $minus:
          var next = scanner.peekChar(1);
          if (isDigit(next) || next == $dot) return _number();
          if (_lookingAtInterpolatedIdentifier()) return _identifierLike();
  
          return _unaryOperation();
  
        default:
          if (first == null) scanner.error("Expected expression.");
  
          if (isNameStart(first) || first == $backslash) {
            return _identifierLike();
          }
          if (isDigit(first)) return _number();
  
          scanner.error("Expected expression");
          throw "Unreachable";
      }
    }
  
    Expression _parentheses() {
  
negative.code:     expectIdentifier("from");
      whitespace();
      bool exclusive;
      var from = _expression(
          until: () {
            if (!lookingAtIdentifier()) return false;
            if (scanIdentifier("to")) {
              exclusive = true;
              return true;
            } else if (scanIdentifier("through")) {
              exclusive = false;
              return true;
            } else {
              return false;
            }
          },
          untilName: '"to" or "through"');
  
      whitespace();
      var to = _expression();
  