2022-10-25 03:06:01 +02:00
|
|
|
(******************************************************************************
|
2022-10-12 19:22:58 +02:00
|
|
|
* Defines a generic parser class.
|
|
|
|
******************************************************************************)
|
|
|
|
|
2022-10-25 03:06:01 +02:00
|
|
|
open Vec
|
|
|
|
|
2022-10-12 19:22:58 +02:00
|
|
|
exception ParseError of string
|
|
|
|
|
|
|
|
type token = string
|
2022-10-25 03:06:01 +02:00
|
|
|
type state = { i : int; tokens : token vec }
|
2022-10-12 19:22:58 +02:00
|
|
|
|
2022-10-25 03:06:01 +02:00
|
|
|
class parser (tokens : token vec) =
|
2022-10-12 19:22:58 +02:00
|
|
|
object (self)
|
2022-10-25 03:06:01 +02:00
|
|
|
val mutable tokens = tokens
|
2022-10-12 19:22:58 +02:00
|
|
|
val mutable i = ref 0
|
2022-10-25 03:06:01 +02:00
|
|
|
|
2022-10-12 19:22:58 +02:00
|
|
|
method advance = i := !i + 1
|
2022-10-25 03:06:01 +02:00
|
|
|
method prev : token option = Vec.get (!i - 1) tokens
|
|
|
|
method curr : token option = Vec.get !i tokens
|
|
|
|
method next : token option = Vec.get (!i + 1) tokens
|
2022-10-12 19:22:58 +02:00
|
|
|
|
|
|
|
method consume : token option =
|
|
|
|
match self#curr with
|
|
|
|
| None -> None
|
|
|
|
| Some x as res ->
|
|
|
|
self#advance;
|
|
|
|
res
|
|
|
|
|
|
|
|
method expect (x : token) =
|
|
|
|
match self#curr with
|
|
|
|
| Some y when x = y -> self#advance
|
|
|
|
| _ -> raise (ParseError (Printf.sprintf "Expected %s" x))
|
|
|
|
|
|
|
|
method matches (x : token) : bool =
|
|
|
|
match self#curr with
|
|
|
|
| None -> false
|
|
|
|
| Some y ->
|
|
|
|
if x = y then
|
|
|
|
begin
|
|
|
|
self#advance;
|
|
|
|
true
|
|
|
|
end
|
|
|
|
else false
|
|
|
|
|
2022-10-25 03:06:01 +02:00
|
|
|
method exhausted : bool = !i >= Vec.length tokens
|
2022-10-12 19:22:58 +02:00
|
|
|
method state : state = { i = !i; tokens }
|
|
|
|
end
|