let descan = function
    | COLON -> ":"
    | NEWLINE -> "\n"
    | SPACE(n) -> String.make n ' '
    | REFINABLE -> "refinable"
    | AND -> "and"
    | OR -> "or"
    | XOR -> "xor"
    | NAND -> "nand"
    | NOR -> "nor"
    | NOT -> "not"
    | EQ -> "="
    | NEQ -> "=/="
    | LT -> "<"
    | LEQ -> "<="
    | GT -> ">"
    | GEQ -> ">="
    | ARRAY -> "[]"
    | LBRACKET -> "["
    | RBRACKET -> "]"
    | LPAREN -> "("
    | RPAREN -> ")"
    | LBRACE -> "{"
    | RBRACE -> "}"
    | SEMI -> ";"
    | COMMA -> ","
    | PLUS -> "+"
    | MINUS -> "-"
    | TIMES -> "*"
    | DIVIDE -> "/"
    | MOD -> "%"
    | POWER -> "^"
    | PLUSA -> "+="
    | MINUSA -> "-="
    | TIMESA -> "*="
    | DIVIDEA -> "/="
    | MODA -> "%="
    | POWERA -> "^="
    | IF -> "if"
    | ELSE -> "else"
    | ELSIF -> "elsif"
    | WHILE -> "while"
    | RETURN -> "return"
    | CLASS -> "class"
    | EXTEND -> "extends"
    | SUPER -> "super"
    | INIT -> "init"
    | NULL -> "null"
    | VOID -> "void"
    | THIS -> "this"
    | REFINE -> "refine"
    | REFINES -> "refinement"
    | TO -> "to"
    | PRIVATE -> "private"
    | PUBLIC -> "public"
    | PROTECTED -> "protected"
    | DOT -> "."
    | MAIN -> "main"
    | NEW -> "new"
    | ASSIGN -> ":="
    | ID(var) -> var
    | TYPE(typ) -> typ
    | BLIT(b) -> if b then "true" else "false"
    | ILIT(i) -> string_of_int(i)
    | FLIT(f) -> string_of_float(f)
    | SLIT(s) -> Format.sprintf "\"%s\"" s
    | EOF -> "eof"