anchor.diff:  
   relation[std::vector<cql3::relation_ptr>& clauses]
       @init{ cql3::expr::oper_t rt; }
  -    : name=cident type=relationType t=term { $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), type, cql3::expr::as_expression(std::move(t)))); }
  +    : name=cident type=relationType t=term { $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), type, std::move(t))); }
   
       | K_TOKEN l=tupleOfIdentifiers type=relationType t=term
  -        { $clauses.emplace_back(::make_shared<cql3::token_relation>(std::move(l), type, cql3::expr::as_expression(std::move(t)))); }
  +        { $clauses.emplace_back(::make_shared<cql3::token_relation>(std::move(l), type, std::move(t))); }
       | name=cident K_IS K_NOT K_NULL {
  -          $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), cql3::expr::oper_t::IS_NOT, cql3::expr::null())); }
  +          $clauses.emplace_back(make_shared<cql3::single_column_relation>(std::move(name), cql3::expr::oper_t::IS_NOT, cql3::expr::null())); }
       | name=cident K_IN marker=inMarker
  -        { $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), cql3::expr::oper_t::IN, cql3::expr::as_expression(std::move(marker)))); }
  +        { $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), cql3::expr::oper_t::IN, std::move(marker))); }
       | name=cident K_IN in_values=singleColumnInValues
  -        { $clauses.emplace_back(cql3::single_column_relation::create_in_relation(std::move(name), boost::copy_range<std::vector<cql3::expr::expression>>(std::move(in_values) | boost::adaptors::transformed(cql3::expr::as_expression)))); }
  +        { $clauses.emplace_back(cql3::single_column_relation::create_in_relation(std::move(name), std::move(in_values))); }
       | name=cident K_CONTAINS { rt = cql3::expr::oper_t::CONTAINS; } (K_KEY { rt = cql3::expr::oper_t::CONTAINS_KEY; })?
  -        t=term { $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), rt, cql3::expr::as_expression(std::move(t)))); }
  -    | name=cident '[' key=term ']' type=relationType t=term { $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), cql3::expr::as_expression(std::move(key)), type, cql3::expr::as_expression(std::move(t)))); }
  +        t=term { $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), rt, std::move(t))); }
  +    | name=cident '[' key=term ']' type=relationType t=term { $clauses.emplace_back(::make_shared<cql3::single_column_relation>(std::move(name), std::move(key), type, std::move(t))); }
       | ids=tupleOfIdentifiers
         ( K_IN
             ( '(' ')'
  
positive.code:         return token->getText();
      }
  
      std::map<sstring, sstring> convert_property_map(shared_ptr<cql3::term::raw> map_term_raw) {
          if (!map_term_raw) {
              return std::map<sstring, sstring>{};
          }
          auto map = std::get<cql3::expr::collection_constructor>(cql3::expr::as_expression(map_term_raw));
          if (map.elements.empty()) {
              return std::map<sstring, sstring>{};
          }
  
negative.code:     | { sign=""; } ('-' {sign = "-"; } )? t=(K_NAN | K_INFINITY) { $constant = cql3::expr::untyped_constant{cql3::expr::untyped_constant::floating_point, sign + $t.text}; }
      ;
  
  mapLiteral returns [cql3::expr::collection_constructor map]
      @init{std::vector<cql3::expr::expression> m;}
      : '{' { }
            ( k1=term ':' v1=term { m.push_back(cql3::expr::tuple_constructor{{std::move(k1), std::move(v1)}}); }
              ( ',' kn=term ':' vn=term { m.push_back(cql3::expr::tuple_constructor{{std::move(kn), std::move(vn)}}); } )*  )?
        '}' { $map = cql3::expr::collection_constructor{cql3::expr::collection_constructor::style_type::map, std::move(m)}; }
      ;
  
  setOrMapLiteral[cql3::expr::expression t] returns [cql3::expr::collection_constructor value]
  	@init{ std::vector<cql3::expr::expression> e; }
      : ':' v=term { e.push_back(cql3::expr::tuple_constructor{{std::move(t), std::move(v)}}); }
            ( ',' kn=term ':' vn=term { e.push_back(cql3::expr::tuple_constructor{{std::move(kn), std::move(vn)}}); } )*
        { $value = cql3::expr::collection_constructor{cql3::expr::collection_constructor::style_type::map, std::move(e)}; }
      | { e.push_back(std::move(t)); }
            ( ',' tn=term { e.push_back(std::move(tn)); } )*
        { $value = cql3::expr::collection_constructor{cql3::expr::collection_constructor::style_type::set, std::move(e)}; }
      ;
  
  collectionLiteral returns [cql3::expr::expression value]
  	@init{ std::vector<cql3::expr::expression> l; }
      : '['
            ( t1=term { l.push_back(std::move(t1)); } ( ',' tn=term { l.push_back(std::move(tn)); } )* )?
        ']' { $value = cql3::expr::collection_constructor{cql3::expr::collection_constructor::style_type::list, std::move(l)}; }
      | '{' t=term v=setOrMapLiteral[t] { $value = std::move(v); } '}'
      // Note that we have an ambiguity between maps and set for "{}". So we force it to a set literal,
      // and deal with it later based on the type of the column (SetLiteral.java).
      | '{' '}' { $value = cql3::expr::collection_constructor{cql3::expr::collection_constructor::style_type::set, {}}; }
      ;
  
  usertypeLiteral returns [cql3::expr::expression ut]
      @init{ cql3::expr::usertype_constructor::elements_map_type m; }
      @after{ $ut = cql3::expr::usertype_constructor{std::move(m)}; }
      // We don't allow empty literals because that conflicts with sets/maps and is currently useless since we don't allow empty user types
      : '{' k1=ident ':' v1=term { m.emplace(std::move(*k1), std::move(v1)); } ( ',' kn=ident ':' vn=term { m.emplace(std::move(*kn), std::move(vn)); } )* '}'
      ;
  
  tupleLiteral returns [cql3::expr::expression tt]
      @init{ std::vector<cql3::expr::expression> l; }
      @after{ $tt = cql3::expr::tuple_constructor{std::move(l)}; }
      : '(' t1=term { l.push_back(std::move(t1)); } ( ',' tn=term { l.push_back(std::move(tn)); } )* ')'
      ;
  
  value returns [cql3::expr::expression value]
      : c=constant           { $value = std::move(c); }
      | l=collectionLiteral  { $value = std::move(l); }
      | u=usertypeLiteral    { $value = std::move(u); }
      | t=tupleLiteral       { $value = std::move(t); }
      | K_NULL               { $value = cql3::expr::null(); }
      | ':' id=ident         { $value = new_bind_variables(id); }
      | QMARK                { $value = new_bind_variables(shared_ptr<cql3::column_identifier>{}); }
      ;
  
  intValue returns [cql3::expr::expression value]
      :
      | t=INTEGER     { $value = cql3::expr::untyped_constant{cql3::expr::untyped_constant::integer, $t.text}; }
      | ':' id=ident  { $value = new_bind_variables(id); }
      | QMARK         { $value = new_bind_variables(shared_ptr<cql3::column_identifier>{}); }
      ;
  
  functionName returns [cql3::functions::function_name s]
  