renamed pretty_printer and added a very basic parser to examples
This commit is contained in:
parent
e9ddde9fb7
commit
a87a59fbff
3 changed files with 82 additions and 3 deletions
79
examples/jsx_parser.erl
Normal file
79
examples/jsx_parser.erl
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
-module(jsx_parser).
|
||||||
|
|
||||||
|
-export([decode/2, event/2]).
|
||||||
|
|
||||||
|
|
||||||
|
%% this is a strict parser, no comments, no naked values and only one key per object. it
|
||||||
|
%% also is not streaming, though it could be modified to parse partial objects/lists.
|
||||||
|
|
||||||
|
decode(JSON, Opts) ->
|
||||||
|
P = jsx:decoder({{jsx_parser, event}, []}, Opts),
|
||||||
|
{{_, Result}, Rest} = P(JSON),
|
||||||
|
case jsx:tail_clean(Rest) of
|
||||||
|
true -> Result
|
||||||
|
; _ -> exit(badarg)
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% erlang representation is dicts for objects and lists for arrays. these are pushed
|
||||||
|
%% onto a stack, the top of which is our current level, deeper levels represent parent
|
||||||
|
%% and grandparent levels in the json structure. keys are also stored on top of the array
|
||||||
|
%% during parsing of their associated values.
|
||||||
|
|
||||||
|
event(start_object, Stack) ->
|
||||||
|
[dict:new()] ++ Stack;
|
||||||
|
event(start_array, Stack) ->
|
||||||
|
[[]] ++ Stack;
|
||||||
|
|
||||||
|
|
||||||
|
event(end_object, [Object, {key, Key}, Parent|Stack]) when is_tuple(Parent) ->
|
||||||
|
[insert(Key, Object, Parent)] ++ Stack;
|
||||||
|
event(end_array, [Array, {key, Key}, Parent|Stack]) when is_tuple(Parent) ->
|
||||||
|
[insert(Key, Array, Parent)] ++ Stack;
|
||||||
|
event(end_object, [Object, Parent|Stack]) when is_list(Parent) ->
|
||||||
|
[[Object] ++ Parent] ++ Stack;
|
||||||
|
event(end_array, [Array, Parent|Stack]) when is_list(Parent) ->
|
||||||
|
[[Array] ++ Parent] ++ Stack;
|
||||||
|
|
||||||
|
%% special cases for closing the root objects
|
||||||
|
event(end_object, [Object]) ->
|
||||||
|
[Object];
|
||||||
|
event(end_array, [Array]) ->
|
||||||
|
[Array];
|
||||||
|
|
||||||
|
event({key, Key}, [Object|Stack]) ->
|
||||||
|
[{key, Key}] ++ [Object] ++ Stack;
|
||||||
|
|
||||||
|
%% this is kind of a dirty hack, but erlang will interpret atoms when applied to (Args)
|
||||||
|
%% as a function. so naming out formatting functions string, number and literal will
|
||||||
|
%% allow the following shortcut
|
||||||
|
|
||||||
|
event({Type, Value}, [{key, Key}, Object|Stack]) ->
|
||||||
|
[insert(Key, ?MODULE:Type(Value), Object)] ++ Stack;
|
||||||
|
event({Type, Value}, [Array|Stack]) when is_list(Array) ->
|
||||||
|
[[?MODULE:Type(Value)] ++ Array] ++ Stack;
|
||||||
|
|
||||||
|
event(eof, [Stack]) ->
|
||||||
|
Stack.
|
||||||
|
|
||||||
|
|
||||||
|
%% we're restricting keys to one occurence per object, as the spec implies.
|
||||||
|
|
||||||
|
insert(Key, Val, Dict) ->
|
||||||
|
case dict:is_key(Key, Dict) of
|
||||||
|
false -> dict:store(Key, Val, Dict)
|
||||||
|
; true -> exit(badarg)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
%% strings, numbers and literals we just return with no post-processing, this is where we
|
||||||
|
%% would deal with them though.
|
||||||
|
|
||||||
|
string(String) ->
|
||||||
|
String.
|
||||||
|
number(Number) ->
|
||||||
|
Number.
|
||||||
|
literal(Literal) ->
|
||||||
|
Literal.
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
-module(pretty_printer).
|
-module(jsx_prettify).
|
||||||
|
|
||||||
-export([print/2, jsx_event/2]).
|
-export([pretty/2, jsx_event/2]).
|
||||||
|
|
||||||
-record(opts, {
|
-record(opts, {
|
||||||
indent = 4
|
indent = 4
|
||||||
}).
|
}).
|
||||||
|
|
||||||
|
|
||||||
print(JSON, Opts) ->
|
pretty(JSON, Opts) ->
|
||||||
Init = init(parse_opts(Opts, #opts{})),
|
Init = init(parse_opts(Opts, #opts{})),
|
||||||
{{_, Result}, Rest} = (jsx:decoder({{pretty_printer, jsx_event}, Init}, []))(JSON),
|
{{_, Result}, Rest} = (jsx:decoder({{pretty_printer, jsx_event}, Init}, []))(JSON),
|
||||||
case jsx:tail_clean(Rest) of
|
case jsx:tail_clean(Rest) of
|
Loading…
Add table
Add a link
Reference in a new issue