mirror of
https://github.com/valitydev/yamerl.git
synced 2024-11-06 10:55:16 +00:00
Complete node modules for all standard types
The modules "yaml_node_bool" and "yaml_node_int" are renamed to "yaml_node_ext_bool" and "yaml_node_ext_int", because they do not implement what is written in the YAML 1.2 specification but the ones from the types repository (http://yaml.org/type/). New modules are added to implement the officiel YAML 1.2 types and the JSON types (defined in this same specification). Note that these new modules are untested material.
This commit is contained in:
parent
734788df4a
commit
34e62e795c
@ -9,8 +9,15 @@ dist_erlsrc_DATA = yaml_app.erl \
|
|||||||
yaml_node_map.erl \
|
yaml_node_map.erl \
|
||||||
yaml_node_str.erl \
|
yaml_node_str.erl \
|
||||||
yaml_node_null.erl \
|
yaml_node_null.erl \
|
||||||
|
yaml_node_json_null.erl \
|
||||||
yaml_node_bool.erl \
|
yaml_node_bool.erl \
|
||||||
|
yaml_node_json_bool.erl \
|
||||||
yaml_node_int.erl \
|
yaml_node_int.erl \
|
||||||
|
yaml_node_json_int.erl \
|
||||||
|
yaml_node_ext_int.erl \
|
||||||
|
yaml_node_float.erl \
|
||||||
|
yaml_node_json_float.erl \
|
||||||
|
yaml_node_ext_float.erl \
|
||||||
yaml_node_size.erl \
|
yaml_node_size.erl \
|
||||||
yaml_node_timestamp.erl \
|
yaml_node_timestamp.erl \
|
||||||
yaml_node_ipaddr.erl \
|
yaml_node_ipaddr.erl \
|
||||||
|
@ -15,16 +15,10 @@
|
|||||||
-define(TAG, "tag:yaml.org,2002:bool").
|
-define(TAG, "tag:yaml.org,2002:bool").
|
||||||
|
|
||||||
-define(IS_TRUE(S),
|
-define(IS_TRUE(S),
|
||||||
S == "true" orelse S == "True" orelse S == "TRUE" orelse
|
S == "true" orelse S == "True" orelse S == "TRUE").
|
||||||
S == "y" orelse S == "Y" orelse
|
|
||||||
S == "yes" orelse S == "Yes" orelse S == "YES" orelse
|
|
||||||
S == "on" orelse S == "On" orelse S == "ON").
|
|
||||||
|
|
||||||
-define(IS_FALSE(S),
|
-define(IS_FALSE(S),
|
||||||
S == "false" orelse S == "False" orelse S == "FALSE" orelse
|
S == "false" orelse S == "False" orelse S == "FALSE").
|
||||||
S == "n" orelse S == "N" orelse
|
|
||||||
S == "no" orelse S == "No" orelse S == "NO" orelse
|
|
||||||
S == "off" orelse S == "Off" orelse S == "OFF").
|
|
||||||
|
|
||||||
%% -------------------------------------------------------------------
|
%% -------------------------------------------------------------------
|
||||||
%% Public API.
|
%% Public API.
|
||||||
|
70
src/yaml_node_ext_bool.erl
Normal file
70
src/yaml_node_ext_bool.erl
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
-module(yaml_node_ext_bool).
|
||||||
|
|
||||||
|
-include("yaml_tokens.hrl").
|
||||||
|
-include("yaml_nodes.hrl").
|
||||||
|
-include("internal/yaml_constr.hrl").
|
||||||
|
|
||||||
|
%% Public API.
|
||||||
|
-export([
|
||||||
|
tags/0,
|
||||||
|
try_construct_token/3,
|
||||||
|
construct_token/3,
|
||||||
|
node_pres/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(TAG, "tag:yaml.org,2002:bool").
|
||||||
|
|
||||||
|
-define(IS_TRUE(S),
|
||||||
|
S == "true" orelse S == "True" orelse S == "TRUE" orelse
|
||||||
|
S == "y" orelse S == "Y" orelse
|
||||||
|
S == "yes" orelse S == "Yes" orelse S == "YES" orelse
|
||||||
|
S == "on" orelse S == "On" orelse S == "ON").
|
||||||
|
|
||||||
|
-define(IS_FALSE(S),
|
||||||
|
S == "false" orelse S == "False" orelse S == "FALSE" orelse
|
||||||
|
S == "n" orelse S == "N" orelse
|
||||||
|
S == "no" orelse S == "No" orelse S == "NO" orelse
|
||||||
|
S == "off" orelse S == "Off" orelse S == "OFF").
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Public API.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
tags() -> [?TAG].
|
||||||
|
|
||||||
|
try_construct_token(Repr, Node,
|
||||||
|
#yaml_scalar{tag = #yaml_tag{uri = {non_specific, "?"}},
|
||||||
|
text = Text} = Token) when ?IS_TRUE(Text) orelse ?IS_FALSE(Text) ->
|
||||||
|
construct_token(Repr, Node, Token);
|
||||||
|
try_construct_token(_, _, _) ->
|
||||||
|
unrecognized.
|
||||||
|
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text}) when ?IS_TRUE(Text) ->
|
||||||
|
{finished, true};
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text}) when ?IS_FALSE(Text) ->
|
||||||
|
{finished, false};
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) when ?IS_TRUE(Text) ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_bool{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = true
|
||||||
|
},
|
||||||
|
{finished, Node};
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) when ?IS_FALSE(Text) ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_bool{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = false
|
||||||
|
},
|
||||||
|
{finished, Node}.
|
||||||
|
|
||||||
|
node_pres(Node) ->
|
||||||
|
?NODE_PRES(Node).
|
124
src/yaml_node_ext_float.erl
Normal file
124
src/yaml_node_ext_float.erl
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
-module(yaml_node_ext_float).
|
||||||
|
|
||||||
|
-include("yaml_errors.hrl").
|
||||||
|
-include("yaml_tokens.hrl").
|
||||||
|
-include("yaml_nodes.hrl").
|
||||||
|
-include("internal/yaml_constr.hrl").
|
||||||
|
|
||||||
|
%% Public API.
|
||||||
|
-export([
|
||||||
|
tags/0,
|
||||||
|
try_construct_token/3,
|
||||||
|
construct_token/3,
|
||||||
|
node_pres/1,
|
||||||
|
string_to_float/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(TAG, "tag:yaml.org,2002:float").
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Public API.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
tags() -> [?TAG].
|
||||||
|
|
||||||
|
try_construct_token(Repr, Node,
|
||||||
|
#yaml_scalar{tag = #yaml_tag{uri = {non_specific, "?"}}} = Token) ->
|
||||||
|
try
|
||||||
|
construct_token(Repr, Node, Token)
|
||||||
|
catch
|
||||||
|
_:#yaml_parsing_error{name = not_an_float} ->
|
||||||
|
unrecognized
|
||||||
|
end;
|
||||||
|
try_construct_token(_, _, _) ->
|
||||||
|
unrecognized.
|
||||||
|
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_float(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
{finished, Int}
|
||||||
|
end;
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_float(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_int{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = Int
|
||||||
|
},
|
||||||
|
{finished, Node}
|
||||||
|
end;
|
||||||
|
|
||||||
|
construct_token(_, _, Token) ->
|
||||||
|
exception(Token).
|
||||||
|
|
||||||
|
node_pres(Node) ->
|
||||||
|
?NODE_PRES(Node).
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Internal functions.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
string_to_float(".nan") -> 'nan';
|
||||||
|
string_to_float(".Nan") -> 'nan';
|
||||||
|
string_to_float(".NAN") -> 'nan';
|
||||||
|
string_to_float(".inf") -> '+inf';
|
||||||
|
string_to_float(".Inf") -> '+inf';
|
||||||
|
string_to_float(".INF") -> '+inf';
|
||||||
|
string_to_float("+.inf") -> '+inf';
|
||||||
|
string_to_float("+.Inf") -> '+inf';
|
||||||
|
string_to_float("+.INF") -> '+inf';
|
||||||
|
string_to_float("-.inf") -> '-inf';
|
||||||
|
string_to_float("-.Inf") -> '-inf';
|
||||||
|
string_to_float("-.INF") -> '-inf';
|
||||||
|
string_to_float([$+ | Text]) -> string_to_float2(Text);
|
||||||
|
string_to_float([$- | Text]) -> -string_to_float2(Text);
|
||||||
|
string_to_float(Text) -> string_to_float2(Text).
|
||||||
|
|
||||||
|
string_to_float2(Text) ->
|
||||||
|
%% Try base 10.
|
||||||
|
O1 = [{capture, none}],
|
||||||
|
case re:run(Text, "([0-9][0-9_]*)?\.[0-9.]*([eE][-+][0-9]+)?", O1) of
|
||||||
|
match ->
|
||||||
|
string_to_float3(Text);
|
||||||
|
nomatch ->
|
||||||
|
%% Try base 60.
|
||||||
|
O2 = [{capture, all_but_first, list}],
|
||||||
|
case re:run(Text, "([0-9][0-9_]*)(:[0-5]?[0-9])+\.([0-9_]*)", O2) of
|
||||||
|
{match, [P1, P2, Dec]} ->
|
||||||
|
case yaml_node_ext_int:base60_to_integer(P1 ++ P2, 0, 0) of
|
||||||
|
error ->
|
||||||
|
error;
|
||||||
|
Int ->
|
||||||
|
string_to_float3(
|
||||||
|
erlang:integer_to_list(Int) ++ "." ++ Dec)
|
||||||
|
end;
|
||||||
|
nomatch ->
|
||||||
|
error
|
||||||
|
end
|
||||||
|
end.
|
||||||
|
|
||||||
|
string_to_float3(Text) ->
|
||||||
|
try
|
||||||
|
erlang:list_to_float(Text)
|
||||||
|
catch
|
||||||
|
error:badarg -> error
|
||||||
|
end.
|
||||||
|
|
||||||
|
exception(Token) ->
|
||||||
|
Error = #yaml_parsing_error{
|
||||||
|
name = not_a_float,
|
||||||
|
token = Token,
|
||||||
|
text = "Invalid float",
|
||||||
|
line = ?TOKEN_LINE(Token),
|
||||||
|
column = ?TOKEN_COLUMN(Token)
|
||||||
|
},
|
||||||
|
throw(Error).
|
162
src/yaml_node_ext_int.erl
Normal file
162
src/yaml_node_ext_int.erl
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
-module(yaml_node_ext_int).
|
||||||
|
|
||||||
|
-include("yaml_errors.hrl").
|
||||||
|
-include("yaml_tokens.hrl").
|
||||||
|
-include("yaml_nodes.hrl").
|
||||||
|
-include("internal/yaml_constr.hrl").
|
||||||
|
|
||||||
|
%% Public API.
|
||||||
|
-export([
|
||||||
|
tags/0,
|
||||||
|
try_construct_token/3,
|
||||||
|
construct_token/3,
|
||||||
|
node_pres/1,
|
||||||
|
string_to_integer/1,
|
||||||
|
base2_to_integer/2,
|
||||||
|
base8_to_integer/2,
|
||||||
|
base10_to_integer/2,
|
||||||
|
base16_to_integer/2,
|
||||||
|
base60_to_integer/3
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(TAG, "tag:yaml.org,2002:int").
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Public API.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
tags() -> [?TAG].
|
||||||
|
|
||||||
|
try_construct_token(Repr, Node,
|
||||||
|
#yaml_scalar{tag = #yaml_tag{uri = {non_specific, "?"}}} = Token) ->
|
||||||
|
try
|
||||||
|
construct_token(Repr, Node, Token)
|
||||||
|
catch
|
||||||
|
_:#yaml_parsing_error{name = not_an_integer} ->
|
||||||
|
unrecognized
|
||||||
|
end;
|
||||||
|
try_construct_token(_, _, _) ->
|
||||||
|
unrecognized.
|
||||||
|
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_integer(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
{finished, Int}
|
||||||
|
end;
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_integer(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_int{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = Int
|
||||||
|
},
|
||||||
|
{finished, Node}
|
||||||
|
end;
|
||||||
|
|
||||||
|
construct_token(_, _, Token) ->
|
||||||
|
exception(Token).
|
||||||
|
|
||||||
|
node_pres(Node) ->
|
||||||
|
?NODE_PRES(Node).
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Internal functions.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% Sign.
|
||||||
|
string_to_integer([$+ | Text]) -> string_to_integer2(Text);
|
||||||
|
string_to_integer([$- | Text]) -> -string_to_integer2(Text);
|
||||||
|
string_to_integer(Text) -> string_to_integer2(Text).
|
||||||
|
|
||||||
|
%% Base.
|
||||||
|
string_to_integer2("0b" ++ Text) ->
|
||||||
|
base2_to_integer(Text, 0);
|
||||||
|
string_to_integer2("0x" ++ Text) ->
|
||||||
|
base16_to_integer(Text, 0);
|
||||||
|
string_to_integer2("0o" ++ Text) ->
|
||||||
|
base8_to_integer(Text, 0);
|
||||||
|
string_to_integer2("0" ++ Text) ->
|
||||||
|
base8_to_integer(Text, 0);
|
||||||
|
string_to_integer2(Text) ->
|
||||||
|
Opts = [{capture, none}],
|
||||||
|
case re:run(Text, "[1-9][0-9_]*(?::[0-5]?[0-9])+", Opts) of
|
||||||
|
match -> base60_to_integer(Text, 0, 0);
|
||||||
|
nomatch -> base10_to_integer(Text, 0)
|
||||||
|
end.
|
||||||
|
|
||||||
|
%% Parsing.
|
||||||
|
base10_to_integer([C | Rest], Int) when C >= $0 andalso C =< $9 ->
|
||||||
|
Int1 = (Int * 10) + (C - $0),
|
||||||
|
base10_to_integer(Rest, Int1);
|
||||||
|
base10_to_integer([$_ | Rest], Int) ->
|
||||||
|
base10_to_integer(Rest, Int);
|
||||||
|
base10_to_integer([], Int) ->
|
||||||
|
Int;
|
||||||
|
base10_to_integer(_, _) ->
|
||||||
|
error.
|
||||||
|
|
||||||
|
base2_to_integer([C | Rest], Int) when C == $0 orelse C == $1 ->
|
||||||
|
Int1 = (Int * 2) + (C - $0),
|
||||||
|
base2_to_integer(Rest, Int1);
|
||||||
|
base2_to_integer([$_ | Rest], Int) ->
|
||||||
|
base2_to_integer(Rest, Int);
|
||||||
|
base2_to_integer([], Int) ->
|
||||||
|
Int;
|
||||||
|
base2_to_integer(_, _) ->
|
||||||
|
error.
|
||||||
|
|
||||||
|
base8_to_integer([C | Rest], Int) when C >= $0 andalso C =< $7 ->
|
||||||
|
Int1 = (Int * 8) + (C - $0),
|
||||||
|
base8_to_integer(Rest, Int1);
|
||||||
|
base8_to_integer([$_ | Rest], Int) ->
|
||||||
|
base8_to_integer(Rest, Int);
|
||||||
|
base8_to_integer([], Int) ->
|
||||||
|
Int;
|
||||||
|
base8_to_integer(_, _) ->
|
||||||
|
error.
|
||||||
|
|
||||||
|
base16_to_integer([C | Rest], Int) when C >= $0 andalso C =< $9 ->
|
||||||
|
Int1 = (Int * 16) + (C - $0),
|
||||||
|
base16_to_integer(Rest, Int1);
|
||||||
|
base16_to_integer([C | Rest], Int) when C >= $a andalso C =< $f ->
|
||||||
|
Int1 = (Int * 16) + (C - $a + 10),
|
||||||
|
base16_to_integer(Rest, Int1);
|
||||||
|
base16_to_integer([C | Rest], Int) when C >= $A andalso C =< $F ->
|
||||||
|
Int1 = (Int * 16) + (C - $A + 10),
|
||||||
|
base16_to_integer(Rest, Int1);
|
||||||
|
base16_to_integer([$_ | Rest], Int) ->
|
||||||
|
base16_to_integer(Rest, Int);
|
||||||
|
base16_to_integer([], Int) ->
|
||||||
|
Int;
|
||||||
|
base16_to_integer(_, _) ->
|
||||||
|
error.
|
||||||
|
|
||||||
|
base60_to_integer([C | Rest], Current, Int) when C >= $0 andalso C =< $9 ->
|
||||||
|
Current1 = (Current * 10) + (C - $0),
|
||||||
|
base60_to_integer(Rest, Current1, Int);
|
||||||
|
base60_to_integer([$: | Rest], Current, Int) ->
|
||||||
|
Int1 = (Int * 60) + Current,
|
||||||
|
base60_to_integer(Rest, 0, Int1);
|
||||||
|
base60_to_integer([$_ | Rest], Current, Int) ->
|
||||||
|
base60_to_integer(Rest, Current, Int);
|
||||||
|
base60_to_integer([], Current, Int) ->
|
||||||
|
(Int * 60) + Current.
|
||||||
|
|
||||||
|
exception(Token) ->
|
||||||
|
Error = #yaml_parsing_error{
|
||||||
|
name = not_an_integer,
|
||||||
|
token = Token,
|
||||||
|
text = "Invalid integer",
|
||||||
|
line = ?TOKEN_LINE(Token),
|
||||||
|
column = ?TOKEN_COLUMN(Token)
|
||||||
|
},
|
||||||
|
throw(Error).
|
108
src/yaml_node_float.erl
Normal file
108
src/yaml_node_float.erl
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
-module(yaml_node_float).
|
||||||
|
|
||||||
|
-include("yaml_errors.hrl").
|
||||||
|
-include("yaml_tokens.hrl").
|
||||||
|
-include("yaml_nodes.hrl").
|
||||||
|
-include("internal/yaml_constr.hrl").
|
||||||
|
|
||||||
|
%% Public API.
|
||||||
|
-export([
|
||||||
|
tags/0,
|
||||||
|
try_construct_token/3,
|
||||||
|
construct_token/3,
|
||||||
|
node_pres/1,
|
||||||
|
string_to_float/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(TAG, "tag:yaml.org,2002:float").
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Public API.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
tags() -> [?TAG].
|
||||||
|
|
||||||
|
try_construct_token(Repr, Node,
|
||||||
|
#yaml_scalar{tag = #yaml_tag{uri = {non_specific, "?"}}} = Token) ->
|
||||||
|
try
|
||||||
|
construct_token(Repr, Node, Token)
|
||||||
|
catch
|
||||||
|
_:#yaml_parsing_error{name = not_an_float} ->
|
||||||
|
unrecognized
|
||||||
|
end;
|
||||||
|
try_construct_token(_, _, _) ->
|
||||||
|
unrecognized.
|
||||||
|
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_float(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
{finished, Int}
|
||||||
|
end;
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_float(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_int{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = Int
|
||||||
|
},
|
||||||
|
{finished, Node}
|
||||||
|
end;
|
||||||
|
|
||||||
|
construct_token(_, _, Token) ->
|
||||||
|
exception(Token).
|
||||||
|
|
||||||
|
node_pres(Node) ->
|
||||||
|
?NODE_PRES(Node).
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Internal functions.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
string_to_float(".nan") -> 'nan';
|
||||||
|
string_to_float(".Nan") -> 'nan';
|
||||||
|
string_to_float(".NAN") -> 'nan';
|
||||||
|
string_to_float(".inf") -> '+inf';
|
||||||
|
string_to_float(".Inf") -> '+inf';
|
||||||
|
string_to_float(".INF") -> '+inf';
|
||||||
|
string_to_float("+.inf") -> '+inf';
|
||||||
|
string_to_float("+.Inf") -> '+inf';
|
||||||
|
string_to_float("+.INF") -> '+inf';
|
||||||
|
string_to_float("-.inf") -> '-inf';
|
||||||
|
string_to_float("-.Inf") -> '-inf';
|
||||||
|
string_to_float("-.INF") -> '-inf';
|
||||||
|
string_to_float([$+ | Text]) -> string_to_float2(Text);
|
||||||
|
string_to_float([$- | Text]) -> -string_to_float2(Text);
|
||||||
|
string_to_float(Text) -> string_to_float2(Text).
|
||||||
|
|
||||||
|
string_to_float2(Text) ->
|
||||||
|
Opts = [{capture, none}],
|
||||||
|
case re:run(Text, "(\.[0-9]+|[0-9]+(\.[0-9]*)?)([eE][-+]?[0-9]+)?", Opts) of
|
||||||
|
match -> string_to_float3(Text);
|
||||||
|
nomatch -> error
|
||||||
|
end.
|
||||||
|
|
||||||
|
string_to_float3(Text) ->
|
||||||
|
try
|
||||||
|
erlang:list_to_float(Text)
|
||||||
|
catch
|
||||||
|
error:badarg -> error
|
||||||
|
end.
|
||||||
|
|
||||||
|
exception(Token) ->
|
||||||
|
Error = #yaml_parsing_error{
|
||||||
|
name = not_a_float,
|
||||||
|
token = Token,
|
||||||
|
text = "Invalid float",
|
||||||
|
line = ?TOKEN_LINE(Token),
|
||||||
|
column = ?TOKEN_COLUMN(Token)
|
||||||
|
},
|
||||||
|
throw(Error).
|
@ -73,77 +73,12 @@ string_to_integer([$- | Text]) -> -string_to_integer2(Text);
|
|||||||
string_to_integer(Text) -> string_to_integer2(Text).
|
string_to_integer(Text) -> string_to_integer2(Text).
|
||||||
|
|
||||||
%% Base.
|
%% Base.
|
||||||
string_to_integer2("0b" ++ Text) ->
|
|
||||||
base2_to_integer(Text, 0);
|
|
||||||
string_to_integer2("0x" ++ Text) ->
|
string_to_integer2("0x" ++ Text) ->
|
||||||
base16_to_integer(Text, 0);
|
yaml_node_ext_int:base16_to_integer(Text, 0);
|
||||||
string_to_integer2("0o" ++ Text) ->
|
string_to_integer2("0o" ++ Text) ->
|
||||||
base8_to_integer(Text, 0);
|
yaml_node_ext_int:base8_to_integer(Text, 0);
|
||||||
string_to_integer2("0" ++ Text) ->
|
|
||||||
base8_to_integer(Text, 0);
|
|
||||||
string_to_integer2(Text) ->
|
string_to_integer2(Text) ->
|
||||||
case re:run(Text, "[1-9][0-9_]*(?::[0-5]?[0-9])+") of
|
yaml_node_ext_int:base10_to_integer(Text, 0).
|
||||||
{match, _} -> base60_to_integer(Text, 0, 0);
|
|
||||||
nomatch -> base10_to_integer(Text, 0)
|
|
||||||
end.
|
|
||||||
|
|
||||||
%% Parsing.
|
|
||||||
base10_to_integer([C | Rest], Int) when C >= $0 andalso C =< $9 ->
|
|
||||||
Int1 = (Int * 10) + (C - $0),
|
|
||||||
base10_to_integer(Rest, Int1);
|
|
||||||
base10_to_integer([$_ | Rest], Int) ->
|
|
||||||
base10_to_integer(Rest, Int);
|
|
||||||
base10_to_integer([], Int) ->
|
|
||||||
Int;
|
|
||||||
base10_to_integer(_, _) ->
|
|
||||||
error.
|
|
||||||
|
|
||||||
base2_to_integer([C | Rest], Int) when C == $0 orelse C == $1 ->
|
|
||||||
Int1 = (Int * 2) + (C - $0),
|
|
||||||
base2_to_integer(Rest, Int1);
|
|
||||||
base2_to_integer([$_ | Rest], Int) ->
|
|
||||||
base2_to_integer(Rest, Int);
|
|
||||||
base2_to_integer([], Int) ->
|
|
||||||
Int;
|
|
||||||
base2_to_integer(_, _) ->
|
|
||||||
error.
|
|
||||||
|
|
||||||
base8_to_integer([C | Rest], Int) when C >= $0 andalso C =< $7 ->
|
|
||||||
Int1 = (Int * 8) + (C - $0),
|
|
||||||
base8_to_integer(Rest, Int1);
|
|
||||||
base8_to_integer([$_ | Rest], Int) ->
|
|
||||||
base8_to_integer(Rest, Int);
|
|
||||||
base8_to_integer([], Int) ->
|
|
||||||
Int;
|
|
||||||
base8_to_integer(_, _) ->
|
|
||||||
error.
|
|
||||||
|
|
||||||
base16_to_integer([C | Rest], Int) when C >= $0 andalso C =< $9 ->
|
|
||||||
Int1 = (Int * 16) + (C - $0),
|
|
||||||
base16_to_integer(Rest, Int1);
|
|
||||||
base16_to_integer([C | Rest], Int) when C >= $a andalso C =< $f ->
|
|
||||||
Int1 = (Int * 16) + (C - $a + 10),
|
|
||||||
base16_to_integer(Rest, Int1);
|
|
||||||
base16_to_integer([C | Rest], Int) when C >= $A andalso C =< $F ->
|
|
||||||
Int1 = (Int * 16) + (C - $A + 10),
|
|
||||||
base16_to_integer(Rest, Int1);
|
|
||||||
base16_to_integer([$_ | Rest], Int) ->
|
|
||||||
base16_to_integer(Rest, Int);
|
|
||||||
base16_to_integer([], Int) ->
|
|
||||||
Int;
|
|
||||||
base16_to_integer(_, _) ->
|
|
||||||
error.
|
|
||||||
|
|
||||||
base60_to_integer([C | Rest], Current, Int) when C >= $0 andalso C =< $9 ->
|
|
||||||
Current1 = (Current * 10) + (C - $0),
|
|
||||||
base60_to_integer(Rest, Current1, Int);
|
|
||||||
base60_to_integer([$: | Rest], Current, Int) ->
|
|
||||||
Int1 = (Int * 60) + Current,
|
|
||||||
base60_to_integer(Rest, 0, Int1);
|
|
||||||
base60_to_integer([$_ | Rest], Current, Int) ->
|
|
||||||
base60_to_integer(Rest, Current, Int);
|
|
||||||
base60_to_integer([], Current, Int) ->
|
|
||||||
(Int * 60) + Current.
|
|
||||||
|
|
||||||
exception(Token) ->
|
exception(Token) ->
|
||||||
Error = #yaml_parsing_error{
|
Error = #yaml_parsing_error{
|
||||||
|
64
src/yaml_node_json_bool.erl
Normal file
64
src/yaml_node_json_bool.erl
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
-module(yaml_node_json_bool).
|
||||||
|
|
||||||
|
-include("yaml_tokens.hrl").
|
||||||
|
-include("yaml_nodes.hrl").
|
||||||
|
-include("internal/yaml_constr.hrl").
|
||||||
|
|
||||||
|
%% Public API.
|
||||||
|
-export([
|
||||||
|
tags/0,
|
||||||
|
try_construct_token/3,
|
||||||
|
construct_token/3,
|
||||||
|
node_pres/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(TAG, "tag:yaml.org,2002:bool").
|
||||||
|
|
||||||
|
-define(IS_TRUE(S),
|
||||||
|
S == "true").
|
||||||
|
|
||||||
|
-define(IS_FALSE(S),
|
||||||
|
S == "false").
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Public API.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
tags() -> [?TAG].
|
||||||
|
|
||||||
|
try_construct_token(Repr, Node,
|
||||||
|
#yaml_scalar{tag = #yaml_tag{uri = {non_specific, "?"}},
|
||||||
|
text = Text} = Token) when ?IS_TRUE(Text) orelse ?IS_FALSE(Text) ->
|
||||||
|
construct_token(Repr, Node, Token);
|
||||||
|
try_construct_token(_, _, _) ->
|
||||||
|
unrecognized.
|
||||||
|
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text}) when ?IS_TRUE(Text) ->
|
||||||
|
{finished, true};
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text}) when ?IS_FALSE(Text) ->
|
||||||
|
{finished, false};
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) when ?IS_TRUE(Text) ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_bool{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = true
|
||||||
|
},
|
||||||
|
{finished, Node};
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) when ?IS_FALSE(Text) ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_bool{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = false
|
||||||
|
},
|
||||||
|
{finished, Node}.
|
||||||
|
|
||||||
|
node_pres(Node) ->
|
||||||
|
?NODE_PRES(Node).
|
99
src/yaml_node_json_float.erl
Normal file
99
src/yaml_node_json_float.erl
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
-module(yaml_node_json_float).
|
||||||
|
|
||||||
|
-include("yaml_errors.hrl").
|
||||||
|
-include("yaml_tokens.hrl").
|
||||||
|
-include("yaml_nodes.hrl").
|
||||||
|
-include("internal/yaml_constr.hrl").
|
||||||
|
|
||||||
|
%% Public API.
|
||||||
|
-export([
|
||||||
|
tags/0,
|
||||||
|
try_construct_token/3,
|
||||||
|
construct_token/3,
|
||||||
|
node_pres/1,
|
||||||
|
string_to_float/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(TAG, "tag:yaml.org,2002:float").
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Public API.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
tags() -> [?TAG].
|
||||||
|
|
||||||
|
try_construct_token(Repr, Node,
|
||||||
|
#yaml_scalar{tag = #yaml_tag{uri = {non_specific, "?"}}} = Token) ->
|
||||||
|
try
|
||||||
|
construct_token(Repr, Node, Token)
|
||||||
|
catch
|
||||||
|
_:#yaml_parsing_error{name = not_an_float} ->
|
||||||
|
unrecognized
|
||||||
|
end;
|
||||||
|
try_construct_token(_, _, _) ->
|
||||||
|
unrecognized.
|
||||||
|
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_float(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
{finished, Int}
|
||||||
|
end;
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_float(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_int{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = Int
|
||||||
|
},
|
||||||
|
{finished, Node}
|
||||||
|
end;
|
||||||
|
|
||||||
|
construct_token(_, _, Token) ->
|
||||||
|
exception(Token).
|
||||||
|
|
||||||
|
node_pres(Node) ->
|
||||||
|
?NODE_PRES(Node).
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Internal functions.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
string_to_float("0") -> 0.0;
|
||||||
|
string_to_float(".nan") -> 'nan';
|
||||||
|
string_to_float(".inf") -> '+inf';
|
||||||
|
string_to_float("-.inf") -> '-inf';
|
||||||
|
string_to_float([$- | Text]) -> -string_to_float2(Text);
|
||||||
|
string_to_float(Text) -> string_to_float2(Text).
|
||||||
|
|
||||||
|
string_to_float2(Text) ->
|
||||||
|
Opts = [{capture, none}],
|
||||||
|
case re:run(Text, "(0|[1-9][0-9]*)(\.[0-9]*)?([eE][-+]?[0-9]+)?", Opts) of
|
||||||
|
match -> string_to_float3(Text);
|
||||||
|
nomatch -> error
|
||||||
|
end.
|
||||||
|
|
||||||
|
string_to_float3(Text) ->
|
||||||
|
try
|
||||||
|
erlang:list_to_float(Text)
|
||||||
|
catch
|
||||||
|
error:badarg -> error
|
||||||
|
end.
|
||||||
|
|
||||||
|
exception(Token) ->
|
||||||
|
Error = #yaml_parsing_error{
|
||||||
|
name = not_a_float,
|
||||||
|
token = Token,
|
||||||
|
text = "Invalid float",
|
||||||
|
line = ?TOKEN_LINE(Token),
|
||||||
|
column = ?TOKEN_COLUMN(Token)
|
||||||
|
},
|
||||||
|
throw(Error).
|
88
src/yaml_node_json_int.erl
Normal file
88
src/yaml_node_json_int.erl
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
-module(yaml_node_json_int).
|
||||||
|
|
||||||
|
-include("yaml_errors.hrl").
|
||||||
|
-include("yaml_tokens.hrl").
|
||||||
|
-include("yaml_nodes.hrl").
|
||||||
|
-include("internal/yaml_constr.hrl").
|
||||||
|
|
||||||
|
%% Public API.
|
||||||
|
-export([
|
||||||
|
tags/0,
|
||||||
|
try_construct_token/3,
|
||||||
|
construct_token/3,
|
||||||
|
node_pres/1,
|
||||||
|
string_to_integer/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(TAG, "tag:yaml.org,2002:int").
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Public API.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
tags() -> [?TAG].
|
||||||
|
|
||||||
|
try_construct_token(Repr, Node,
|
||||||
|
#yaml_scalar{tag = #yaml_tag{uri = {non_specific, "?"}}} = Token) ->
|
||||||
|
try
|
||||||
|
construct_token(Repr, Node, Token)
|
||||||
|
catch
|
||||||
|
_:#yaml_parsing_error{name = not_an_integer} ->
|
||||||
|
unrecognized
|
||||||
|
end;
|
||||||
|
try_construct_token(_, _, _) ->
|
||||||
|
unrecognized.
|
||||||
|
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_integer(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
{finished, Int}
|
||||||
|
end;
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{text = Text} = Token) ->
|
||||||
|
case string_to_integer(Text) of
|
||||||
|
error ->
|
||||||
|
exception(Token);
|
||||||
|
Int ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_int{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres,
|
||||||
|
value = Int
|
||||||
|
},
|
||||||
|
{finished, Node}
|
||||||
|
end;
|
||||||
|
|
||||||
|
construct_token(_, _, Token) ->
|
||||||
|
exception(Token).
|
||||||
|
|
||||||
|
node_pres(Node) ->
|
||||||
|
?NODE_PRES(Node).
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Internal functions.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
%% Zero and sign.
|
||||||
|
string_to_integer("0") ->
|
||||||
|
0;
|
||||||
|
string_to_integer([$-, C | Text]) when C >= $1 andalso C =< $9 ->
|
||||||
|
-yaml_node_ext_int:base10_to_integer(Text, C - $0);
|
||||||
|
string_to_integer([C | Text]) when C >= $1 andalso C =< $9 ->
|
||||||
|
yaml_node_ext_int:base10_to_integer(Text, C - $0);
|
||||||
|
string_to_integer(_) ->
|
||||||
|
error.
|
||||||
|
|
||||||
|
exception(Token) ->
|
||||||
|
Error = #yaml_parsing_error{
|
||||||
|
name = not_an_integer,
|
||||||
|
token = Token,
|
||||||
|
text = "Invalid integer",
|
||||||
|
line = ?TOKEN_LINE(Token),
|
||||||
|
column = ?TOKEN_COLUMN(Token)
|
||||||
|
},
|
||||||
|
throw(Error).
|
44
src/yaml_node_json_null.erl
Normal file
44
src/yaml_node_json_null.erl
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
-module(yaml_node_json_null).
|
||||||
|
|
||||||
|
-include("yaml_tokens.hrl").
|
||||||
|
-include("yaml_nodes.hrl").
|
||||||
|
-include("internal/yaml_constr.hrl").
|
||||||
|
|
||||||
|
%% Public API.
|
||||||
|
-export([
|
||||||
|
tags/0,
|
||||||
|
try_construct_token/3,
|
||||||
|
construct_token/3,
|
||||||
|
node_pres/1
|
||||||
|
]).
|
||||||
|
|
||||||
|
-define(TAG, "tag:yaml.org,2002:null").
|
||||||
|
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
%% Public API.
|
||||||
|
%% -------------------------------------------------------------------
|
||||||
|
|
||||||
|
tags() -> [?TAG].
|
||||||
|
|
||||||
|
try_construct_token(Repr, Node,
|
||||||
|
#yaml_scalar{tag = #yaml_tag{uri = {non_specific, "?"}},
|
||||||
|
text = "null"} = Token) ->
|
||||||
|
construct_token(Repr, Node, Token);
|
||||||
|
try_construct_token(_, _, _) ->
|
||||||
|
unrecognized.
|
||||||
|
|
||||||
|
construct_token(#yaml_constr{simple_structs = true},
|
||||||
|
undefined, #yaml_scalar{}) ->
|
||||||
|
{finished, null};
|
||||||
|
construct_token(#yaml_constr{simple_structs = false},
|
||||||
|
undefined, #yaml_scalar{} = Token) ->
|
||||||
|
Pres = yaml_constr:get_pres_details(Token),
|
||||||
|
Node = #yaml_null{
|
||||||
|
module = ?MODULE,
|
||||||
|
tag = ?TAG,
|
||||||
|
pres = Pres
|
||||||
|
},
|
||||||
|
{finished, Node}.
|
||||||
|
|
||||||
|
node_pres(Node) ->
|
||||||
|
?NODE_PRES(Node).
|
Loading…
Reference in New Issue
Block a user