parser.ml 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. open Printf
  2. open Tokenizer
  3. open Location
  4. type value = | Atom of string | List of value list
  5. type located_value = | Atom of string * location | List of located_value list * location
  6. let consume (stream : 'a Stream.t) : 'a option = match Stream.peek stream with
  7. | None -> None
  8. | Some x -> Stream.junk stream; Some x
  9. type parse_result = | Ok of located_value | UnexpectedEof | ValueAfterEnd | UnexpectedClosedParen of location
  10. let rec parse_list (tokens: located_token Stream.t) (lst : located_value list) (start_pos: position): parse_result =
  11. match consume tokens with
  12. Some (x, loc) -> begin
  13. match x with
  14. | Lpar ->
  15. begin
  16. match parse_list tokens [] (start_position loc) with
  17. | Ok res -> parse_list tokens (res :: lst) start_pos
  18. | err -> err
  19. end
  20. | Rpar -> Ok (List ((List.rev lst) , Range (start_pos, end_position loc)))
  21. | Str s -> parse_list tokens ((Atom (s, loc)) :: lst) start_pos
  22. end
  23. | None -> UnexpectedEof
  24. let parse_toplevel (tokens : located_token Stream.t) : parse_result =
  25. let res = match consume tokens with
  26. | None -> UnexpectedEof
  27. | Some ((Str str), loc) -> Ok (Atom (str, loc))
  28. | Some (Lpar, loc) -> parse_list tokens [] (start_position loc)
  29. | Some (Rpar, loc) -> UnexpectedClosedParen loc
  30. in match consume tokens with
  31. | None -> res
  32. | Some (q,w) -> printf "COO %s %s [[]]" (sprintf_token q) (sprintf_location w);ValueAfterEnd
  33. let sprintf_located_value value =
  34. let spaces i = String.make i ' ' in
  35. let rec inner value identiation_level = match value with
  36. | Atom (str, loc) -> sprintf "%s%s: %s\n" (spaces identiation_level) (sprintf_location loc) str
  37. (* zostawwiam to tak i idę spać, do ulepszenia kiedy indziej *)
  38. | List (value, loc) -> sprintf "%s%s: (\n%s%s)\n" (spaces identiation_level) (sprintf_location loc) ( List.fold_left (fun a b -> a ^ b) "" (List.map (function q -> inner q (identiation_level+1)) value)) (spaces identiation_level)
  39. in inner value 0