let token_to_string = function
| SPACE(n) -> "SPACE(" ^ string_of_int n ^ ")"
| COLON -> "COLON"
| NEWLINE -> "NEWLINE"
| THIS -> "THIS"
| ARRAY -> "ARRAY"
| REFINABLE -> "REFINABLE"
| AND -> "AND"
| OR -> "OR"
| XOR -> "XOR"
| NAND -> "NAND"
| NOR -> "NOR"
| NOT -> "NOT"
| EQ -> "EQ"
| NEQ -> "NEQ"
| LT -> "LT"
| LEQ -> "LEQ"
| GT -> "GT"
| GEQ -> "GEQ"
| LBRACKET -> "LBRACKET"
| RBRACKET -> "RBRACKET"
| LPAREN -> "LPAREN"
| RPAREN -> "RPAREN"
| LBRACE -> "LBRACE"
| RBRACE -> "RBRACE"
| SEMI -> "SEMI"
| COMMA -> "COMMA"
| PLUS -> "PLUS"
| MINUS -> "MINUS"
| TIMES -> "TIMES"
| DIVIDE -> "DIVIDE"
| MOD -> "MOD"
| POWER -> "POWER"
| PLUSA -> "PLUSA"
| MINUSA -> "MINUSA"
| TIMESA -> "TIMESA"
| DIVIDEA -> "DIVIDEA"
| MODA -> "MODA"
| POWERA -> "POWERA"
| IF -> "IF"
| ELSE -> "ELSE"
| ELSIF -> "ELSIF"
| WHILE -> "WHILE"
| RETURN -> "RETURN"
| CLASS -> "CLASS"
| EXTEND -> "EXTEND"
| SUPER -> "SUPER"
| INIT -> "INIT"
| NULL -> "NULL"
| VOID -> "VOID"
| REFINE -> "REFINE"
| REFINES -> "REFINES"
| TO -> "TO"
| PRIVATE -> "PRIVATE"
| PUBLIC -> "PUBLIC"
| PROTECTED -> "PROTECTED"
| DOT -> "DOT"
| MAIN -> "MAIN"
| NEW -> "NEW"
| ASSIGN -> "ASSIGN"
| ID(vid) -> Printf.sprintf "ID(%s)" vid
| TYPE(tid) -> Printf.sprintf "TYPE(%s)" tid
| BLIT(bool) -> Printf.sprintf "BLIT(%B)" bool
| ILIT(inum) -> Printf.sprintf "ILIT(%d)" inum
| FLIT(fnum) -> Printf.sprintf "FLIT(%f)" fnum
| SLIT(str) -> Printf.sprintf "SLIT(\"%s\")" (str)
| EOF -> "EOF"