anchor.diff:  number -> integer : '$1'.
   
   %% Lists
  -list -> '[' ']' :       #empty{line=line('$1')}.
  -list -> '[' expr tail : #cons{line=line('$1'), expr='$2', tail='$3'}.
  +list -> '[' ']' :       #empty{line=?line('$1')}.
  +list -> '[' expr tail : #cons{line=?line('$1'), expr='$2', tail='$3'}.
   
  -tail -> ']' : #empty{line=line('$1')}.
  +tail -> ']' : #empty{line=?line('$1')}.
   tail -> ',' '*' expr ']' : '$3'.
  -tail -> ',' expr tail : #cons{line=line('$1'), expr='$2', tail='$3'}.
  +tail -> ',' expr tail : #cons{line=?line('$1'), expr='$2', tail='$3'}.
   
   %% Tuples
  -tuple -> '(' ')' :               #tuple{line=line('$1'), elements=[]}.
  -tuple -> '(' expr ',' ')' :      #tuple{line=line('$1'), elements='$2'}.
  -tuple -> '(' expr ',' exprs ')': #tuple{line=line('$1'), elements=['$2'|'$4']}.
  +tuple -> '(' ')' :               #tuple{line=?line('$1'), elements=[]}.
  +tuple -> '(' expr ',' ')' :      #tuple{line=?line('$1'), elements='$2'}.
  +tuple -> '(' expr ',' exprs ')': #tuple{line=?line('$1'), elements=['$2'|'$4']}.
   
   %% Maps
  -map -> '{' '}' :             #map{line=line('$1'), elements=[]}.
  -map -> '{' map_entries '}' : #map{line=line('$1'), elements='$2'}.
  +map -> '{' '}' :             #map{line=?line('$1'), elements=[]}.
  +map -> '{' map_entries '}' : #map{line=?line('$1'), elements='$2'}.
   
   map_entries -> add_expr '=>' expr : [{'$1','$3'}]. % FIXME: change add_expr to 1 below match
   map_entries -> add_expr '=>' expr ',' map_entries : [{'$1','$3'}|'$5'].
  
positive.code: 
  expr -> match_expr : '$1'.
  
  match_expr -> add_expr '=' match_expr :   #match{line=line('$2'), left='$1', right='$3'}.
  match_expr -> add_expr : '$1'.
  
  add_expr -> mult_expr add_op add_expr :   #binary_op{line=line('$1'), type=op('$2'), val1='$1', val2='$3'}.
  add_expr -> mult_expr : '$1'.
  
  mult_expr -> pow_expr mult_op mult_expr : #binary_op{line=line('$1'), type=op('$2'), val1='$1', val2='$3'}.
  mult_expr -> pow_expr : '$1'.
  
  pow_expr -> unary_expr pow_op pow_expr :  #binary_op{line=line('$1'), type=op('$2'), val1='$1', val2='$3'}.
  pow_expr -> unary_expr : '$1'.
  
  unary_expr -> unary_op unary_expr :       #unary_op{line=line('$1'), type=op('$1'), val='$2'}.
  unary_expr -> call_expr : '$1'.
  
  call_expr -> call : '$1'.
  
negative.code:       {error, {Line, lists:flatten(io_lib:format("~p ~p", [Message, Token]))}}
    end.
  
  %% Extract operators from op tokens
  op({Op, _Line}) ->
    Op.