anchor.diff:  chars([C|Cs]) -> [C|chars(Cs)];
   chars([]) -> [].
   
  -%% Block Comment:
  -%%  Provide a sensible error when people attempt to include nested
  -%%  comments because currently the parser cannot process them without
  -%%  a rebuild. But simply exploding on a '#|' is not going to be that
  -%%  helpful.
  -
  -block_comment(TokenChars) ->
  -    %% Check we're not opening another comment block.
  -    case string:str(TokenChars, "#|") of
  -        0 -> skip_token; %% No nesting found
  -        _ -> {error, "illegal nested block comment"}
  -    end.
  -
   hex_char(C) when C >= $0, C =< $9 -> true;
   hex_char(C) when C >= $a, C =< $f -> true;
   hex_char(C) when C >= $A, C =< $F -> true;
  
positive.code: 
  Rules.
  %% Bracketed Comments using #| foo |#
  #\|[^\|]*\|+([^#\|][^\|]*\|+)*# : block_comment(string:substr(TokenChars, 3)).
  %% Separators
  #[bB]\(         :    {token,{'#B(',TokenLine}}.
  #[mM]\(         :    {token,{'#M(',TokenLine}}.
  #\(             :    {token,{'#(',TokenLine}}.
  #`              :    {token,{'#`',TokenLine}}.
  #;              :    {token,{'#;',TokenLine}}.
  #,              :    {token,{'#,',TokenLine}}.
  #,@             :    {token,{'#,@',TokenLine}}.
  '               :    {token,{'\'',TokenLine}}.
  `               :    {token,{'`',TokenLine}}.
  ,               :    {token,{',',TokenLine}}.
  ,@              :    {token,{',@',TokenLine}}.
  \.              :    {token,{'.',TokenLine}}.
  [][()}{]        :    {token,{list_to_atom(TokenChars),TokenLine}}.
  %% Characters
  #\\(x{H}+|.)    :    char_token(string:substr(TokenChars, 3), TokenLine).
  %% String
  "(\\x{H}+;|\\.|[^"\\])*" :
              %% Strip quotes.
              S = string:substr(TokenChars, 2, TokenLen - 2),
              {token,{string,TokenLine,chars(S)}}.
  %% Binary string
  #"(\\x{H}+;|\\.|[^"\\])*" :
              %% Strip quotes.
              S = string:substr(TokenChars, 3, TokenLen - 3),
              Bin = unicode:characters_to_binary(chars(S), utf8, utf8),
              {token,{binary,TokenLine,Bin}}.
  %% Symbols
  \|(\\x{H}+;|\\.|[^|\\])*\| :
              %% Strip quotes.
              S = string:substr(TokenChars, 2, TokenLen - 2),
              symbol_token(chars(S), TokenLine).
  %% Funs
  #'{SSYM}{SYM}*/{D}+    :
              %% Strip sharpsign single-quote.
              FunStr = string:substr(TokenChars,3),
              {token,{'#\'',TokenLine,FunStr}}.
  %% Based numbers
  #[bB]{B}+    :    base_token(string:substr(TokenChars, 3), 2, TokenLine).
  #[oO]{O}+    :    base_token(string:substr(TokenChars, 3), 8, TokenLine).
  #[dD]{D}+    :    base_token(string:substr(TokenChars, 3), 10, TokenLine).
  #[xX]{H}+    :    base_token(string:substr(TokenChars, 3), 16, TokenLine).
  #([0]?[2-9]|[12][0-9]|3[0-6])[rR]{B36}+ :
      %% Have to scan all possible digit chars and fail if wrong.
      {Base,[_|Ds]} = base1(string:substr(TokenChars, 2), 10, 0),
      base_token(Ds, Base, TokenLine).
  
  %% Atoms
  [+-]?{D}+        :
      case catch {ok,list_to_integer(TokenChars)} of
          {ok,I} -> {token,{number,TokenLine,I}};
          _ -> {error,"illegal integer"}
      end.
  [+-]?{D}+\.{D}+([eE][+-]?{D}+)? :
      case catch {ok,list_to_float(TokenChars)} of
          {ok,F} -> {token,{number,TokenLine,F}};
          _ -> {error,"illegal float"}
      end.
  {SSYM}{SYM}*    :
      symbol_token(TokenChars, TokenLine).
  {WS}+        :    skip_token.
  
  Erlang code.
  %% Copyright (c) 2008-2013 Robert Virding
  
negative.code: base1([C|Cs], Base, SoFar) when C >= $a, C =< $z, C < Base + $a - 10 ->
      Next = SoFar * Base + (C - $a + 10),
      base1(Cs, Base, Next);
  base1([C|Cs], Base, SoFar) when C >= $A, C =< $Z, C < Base + $A - 10 ->
      Next = SoFar * Base + (C - $A + 10),
      base1(Cs, Base, Next);
  