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:
Jean-Sébastien Pédron 2011-09-27 15:08:09 +02:00
parent 734788df4a
commit 34e62e795c
11 changed files with 771 additions and 76 deletions

View File

@ -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 \

View File

@ -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.

View 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
View 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
View 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
View 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).

View File

@ -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{

View 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).

View 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).

View 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).

View 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).