46 lines
905 B
OCaml
46 lines
905 B
OCaml
type t =
|
|
| Int of int
|
|
| Ident of string
|
|
| Plus
|
|
| Minus
|
|
| Asterisk
|
|
| Slash
|
|
| Carret
|
|
| Percent
|
|
| LParen
|
|
| RParen
|
|
|
|
let tokens = ref [
|
|
"+", Plus;
|
|
"-", Minus;
|
|
"*", Asterisk;
|
|
"/", Slash;
|
|
"^", Carret;
|
|
"%", Percent;
|
|
"(", LParen;
|
|
")", RParen;
|
|
]
|
|
|
|
let expect_token str tok seq =
|
|
let rec aux ts seq =
|
|
match ts (), seq () with
|
|
| Seq.Nil, _ -> Some seq
|
|
| Seq.Cons _, Seq.Nil -> None
|
|
| Seq.Cons (a, ts), Seq.Cons (b, seq) ->
|
|
if a = b then aux ts seq else None
|
|
in
|
|
let str = String.to_seq str in
|
|
aux str seq |> Option.map (fun s -> tok, s)
|
|
|
|
let find_token seq =
|
|
!tokens |> List.find_map
|
|
(fun (s, t) -> expect_token s t seq)
|
|
|
|
let to_string = function
|
|
| Int n -> string_of_int n
|
|
| Ident s -> s
|
|
| t ->
|
|
begin match List.find_opt (fun (_, tok) -> t = tok) !tokens with
|
|
| None -> failwith "Token.to_string"
|
|
| Some (s, _) -> s
|
|
end
|