Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consume boolean tokens #1

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 31 additions & 25 deletions sml-json.sml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,12 @@ sig
val error_handle : string * int * string -> json_data
end

functor JSONParser (Callbacks : JSON_CALLBACKS) =
functor JSONParser (Callbacks : JSON_CALLBACKS) :
sig
type json_data;
val parse : string -> json_data;
end
=
struct
type json_data = Callbacks.json_data

Expand All @@ -51,43 +56,43 @@ struct
do (inputData := String.extract (!inputData, 1, NONE))

fun peek () = String.sub (!inputData,0)
fun take () =
String.sub (!inputData,0) before
fun take () =
String.sub (!inputData,0) before
inputData := String.extract (!inputData, 1, NONE)

fun matches s = (ws(); String.isPrefix s (!inputData))
fun consume s =
if matches s then
if matches s then
(inputData := String.extract (!inputData, size s, NONE);
inputPosition := !inputPosition + size s)
else
else
raise JSONParseError ("Expected '"^s^"'", !inputPosition)

fun parseObject () =
if not (matches "{") then
if not (matches "{") then
raise JSONParseError ("Expected '{'", !inputPosition)
else
else
(consume "{"; ws ();
if matches "}" then Callbacks.json_object [] before consume "}"
else
(Callbacks.json_object (parseMembers ())
else
(Callbacks.json_object (parseMembers ())
before (ws (); consume "}")))

and parseMembers () =
parsePair () ::
parsePair () ::
(if matches "," then (consume ","; parseMembers ()) else [])

and parsePair () =
Callbacks.json_pair (parseString (),
(ws(); consume ":"; parseValue ()))

and parseArray () =
if not (matches "[") then
if not (matches "[") then
raise JSONParseError ("Expected '['", !inputPosition)
else
else
(consume "[";
if matches "]" then
Callbacks.json_array [] before consume "]"
Callbacks.json_array [] before consume "]"
else
Callbacks.json_array (parseElements ()) before (ws (); consume "]"))

Expand All @@ -99,8 +104,11 @@ struct
Callbacks.json_value (
if matches "\"" then Callbacks.json_string (parseString ()) else
if matches "-" orelse isDigit () then parseNumber () else
if matches "true" then Callbacks.json_bool true else
if matches "false" then Callbacks.json_bool false else
if matches "true" then
(consume "true"; Callbacks.json_bool true)
else if matches "false" then
(consume "false"; Callbacks.json_bool false)
else
if matches "null" then Callbacks.json_null () else
if matches "[" then parseArray () else
if matches "{" then parseObject () else
Expand All @@ -111,7 +119,7 @@ struct
consume ("\"") ;
parseChars () before consume "\"")

and parseChars () =
and parseChars () =
let
fun pickChars s =
if peek () = #"\"" (* " *) then s else
Expand All @@ -124,7 +132,7 @@ struct
let
val i = parseInt ()
in
if peek () = #"e" orelse peek () = #"E" then
if peek () = #"e" orelse peek () = #"E" then
Callbacks.json_int (valOf (Int.fromString (i^parseExp())))
else if peek () = #"." then
let
Expand All @@ -150,7 +158,7 @@ struct
f ^ parseDigits ()
end

and parseDigits () =
and parseDigits () =
let
val r = ref ""
in
Expand All @@ -165,10 +173,10 @@ struct

and parseExp () =
let
val _ =
val _ =
if peek () = #"e" orelse
peek () = #"E" then take ()
else
else
raise JSONParseError ("Invalid number", !inputPosition)

val f = if peek () = #"-" then (take (); "~")
Expand All @@ -178,10 +186,10 @@ struct
"e" ^ f ^ parseDigits ()
end

fun parse s =
fun parse s =
(inputData := s ;
inputPosition := 0 ;
parseObject ()) handle JSONParseError (m,p) =>
parseObject ()) handle JSONParseError (m,p) =>
Callbacks.error_handle (m,p,!inputData)
end

Expand All @@ -190,7 +198,7 @@ struct
type json_data = string

fun json_object l =
"{\n " ^
"{\n " ^
String.concatWith "\n " l ^
"}\n"
fun json_pair (k,v) = k ^": "^v
Expand All @@ -205,5 +213,3 @@ struct
fun error_handle (msg,pos,data) =
raise Fail ("Error: " ^ msg ^ " near " ^ Int.toString pos)
end