Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
J
json
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
json
Commits
89a1b024
Commit
89a1b024
authored
Feb 11, 2015
by
Niels
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fixed a major bug in the parser
parent
3f8dc632
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
425 additions
and
360 deletions
+425
-360
json.hpp
src/json.hpp
+376
-345
json.hpp.re2c
src/json.hpp.re2c
+41
-15
unit.cpp
test/unit.cpp
+8
-0
No files found.
src/json.hpp
View file @
89a1b024
...
...
@@ -2477,13 +2477,13 @@ class basic_json
static
const
unsigned
char
yybm
[]
=
{
0
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
192
,
192
,
64
,
64
,
192
,
64
,
64
,
64
,
96
,
96
,
64
,
64
,
96
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
192
,
64
,
0
,
64
,
64
,
64
,
64
,
64
,
96
,
64
,
0
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
96
,
96
,
96
,
96
,
96
,
96
,
96
,
96
,
96
,
96
,
64
,
64
,
64
,
64
,
64
,
64
,
192
,
192
,
192
,
192
,
192
,
192
,
192
,
192
,
192
,
192
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
64
,
...
...
@@ -2519,25 +2519,29 @@ class basic_json
{
if
(
yych
<=
0x00
)
{
goto
json_parser_
3
;
goto
json_parser_
27
;
}
if
(
yych
<=
0x08
)
{
goto
json_parser_5
;
goto
json_parser_29
;
}
if
(
yych
<=
'\t'
)
{
goto
json_parser_3
;
}
goto
json_parser_
7
;
goto
json_parser_
4
;
}
else
{
if
(
yych
==
'\r'
)
{
goto
json_parser_
7
;
goto
json_parser_
3
;
}
if
(
yych
<=
0x1F
)
{
goto
json_parser_
5
;
goto
json_parser_
29
;
}
goto
json_parser_
7
;
goto
json_parser_
3
;
}
}
else
...
...
@@ -2546,29 +2550,29 @@ class basic_json
{
if
(
yych
==
'"'
)
{
goto
json_parser_
8
;
goto
json_parser_
26
;
}
if
(
yych
<=
'+'
)
{
goto
json_parser_
5
;
goto
json_parser_
29
;
}
goto
json_parser_
9
;
goto
json_parser_
14
;
}
else
{
if
(
yych
<=
'-'
)
{
goto
json_parser_
11
;
goto
json_parser_
22
;
}
if
(
yych
<=
'/'
)
{
goto
json_parser_
5
;
goto
json_parser_
29
;
}
if
(
yych
<=
'0'
)
{
goto
json_parser_
12
;
goto
json_parser_
23
;
}
goto
json_parser_
14
;
goto
json_parser_
25
;
}
}
}
...
...
@@ -2580,25 +2584,25 @@ class basic_json
{
if
(
yych
<=
':'
)
{
goto
json_parser_1
5
;
goto
json_parser_1
6
;
}
if
(
yych
==
'['
)
{
goto
json_parser_
17
;
goto
json_parser_
6
;
}
goto
json_parser_
5
;
goto
json_parser_
29
;
}
else
{
if
(
yych
<=
']'
)
{
goto
json_parser_
19
;
goto
json_parser_
8
;
}
if
(
yych
==
'f'
)
{
goto
json_parser_21
;
}
goto
json_parser_
5
;
goto
json_parser_
29
;
}
}
else
...
...
@@ -2607,25 +2611,25 @@ class basic_json
{
if
(
yych
<=
'n'
)
{
goto
json_parser_
22
;
goto
json_parser_
18
;
}
if
(
yych
==
't'
)
{
goto
json_parser_2
3
;
goto
json_parser_2
0
;
}
goto
json_parser_
5
;
goto
json_parser_
29
;
}
else
{
if
(
yych
<=
'{'
)
{
goto
json_parser_
24
;
goto
json_parser_
10
;
}
if
(
yych
==
'}'
)
{
goto
json_parser_
26
;
goto
json_parser_
12
;
}
goto
json_parser_
5
;
goto
json_parser_
29
;
}
}
}
...
...
@@ -2634,339 +2638,162 @@ json_parser_2:
return
scan
();
}
json_parser_3
:
yych
=
*++
m_cursor
;
goto
json_parser_5
;
json_parser_4
:
++
m_cursor
;
yych
=
*
m_cursor
;
json_parser_5
:
if
(
yybm
[
0
+
yych
]
&
32
)
{
return
token_type
::
end_of_input
;
goto
json_parser_4
;
}
json_parser_5
:
++
m_cursor
;
goto
json_parser_2
;
json_parser_6
:
++
m_cursor
;
{
return
token_type
::
parse_error
;
return
token_type
::
begin_array
;
}
json_parser_7
:
yych
=
*++
m_cursor
;
goto
json_parser_62
;
json_parser_8
:
yyaccept
=
0
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
<=
0x00
)
{
goto
json_parser_6
;
}
goto
json_parser_53
;
json_parser_9
:
++
m_cursor
;
{
return
token_type
::
value_separator
;
}
json_parser_11
:
yych
=
*++
m_cursor
;
if
(
yych
<=
'/'
)
{
goto
json_parser_6
;
}
if
(
yych
<=
'0'
)
{
goto
json_parser_51
;
return
token_type
::
end_array
;
}
if
(
yych
<=
'9'
)
json_parser_10
:
++
m_cursor
;
{
goto
json_parser_42
;
return
token_type
::
begin_object
;
}
goto
json_parser_6
;
json_parser_12
:
yyaccept
=
1
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
<=
'D'
)
{
if
(
yych
==
'.'
)
{
goto
json_parser_44
;
}
}
else
{
if
(
yych
<=
'E'
)
{
goto
json_parser_45
;
}
if
(
yych
==
'e'
)
{
goto
json_parser_45
;
}
}
json_parser_13
:
{
return
token_type
::
value_number
;
}
json_parser_14
:
yyaccept
=
1
;
yych
=
*
(
m_marker
=
++
m_cursor
);
goto
json_parser_43
;
json_parser_15
:
++
m_cursor
;
{
return
token_type
::
name_separator
;
return
token_type
::
end_object
;
}
json_parser_1
7
:
json_parser_1
4
:
++
m_cursor
;
{
return
token_type
::
begin_array
;
return
token_type
::
value_separator
;
}
json_parser_1
9
:
json_parser_1
6
:
++
m_cursor
;
{
return
token_type
::
end_array
;
return
token_type
::
name_separator
;
}
json_parser_
21
:
json_parser_
18
:
yyaccept
=
0
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
==
'
a
'
)
if
(
yych
==
'
u
'
)
{
goto
json_parser_
37
;
goto
json_parser_
59
;
}
goto
json_parser_6
;
json_parser_22
:
yyaccept
=
0
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
==
'u'
)
json_parser_19
:
{
goto
json_parser_33
;
return
token_type
::
parse_error
;
}
goto
json_parser_6
;
json_parser_23
:
json_parser_20
:
yyaccept
=
0
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
==
'r'
)
{
goto
json_parser_28
;
}
goto
json_parser_6
;
json_parser_24
:
++
m_cursor
;
{
return
token_type
::
begin_object
;
}
json_parser_26
:
++
m_cursor
;
{
return
token_type
::
end_object
;
}
json_parser_28
:
yych
=
*++
m_cursor
;
if
(
yych
==
'u'
)
{
goto
json_parser_30
;
}
json_parser_29
:
m_cursor
=
m_marker
;
if
(
yyaccept
==
0
)
{
goto
json_parser_6
;
}
else
{
goto
json_parser_13
;
}
json_parser_30
:
yych
=
*++
m_cursor
;
if
(
yych
!=
'e'
)
{
goto
json_parser_29
;
}
++
m_cursor
;
{
return
token_type
::
literal_true
;
}
json_parser_33
:
yych
=
*++
m_cursor
;
if
(
yych
!=
'l'
)
{
goto
json_parser_29
;
}
yych
=
*++
m_cursor
;
if
(
yych
!=
'l'
)
{
goto
json_parser_29
;
}
++
m_cursor
;
{
return
token_type
::
literal_null
;
}
json_parser_37
:
yych
=
*++
m_cursor
;
if
(
yych
!=
'l'
)
{
goto
json_parser_29
;
}
yych
=
*++
m_cursor
;
if
(
yych
!=
's'
)
{
goto
json_parser_29
;
}
yych
=
*++
m_cursor
;
if
(
yych
!=
'e'
)
{
goto
json_parser_29
;
}
++
m_cursor
;
{
return
token_type
::
literal_false
;
}
json_parser_42
:
yyaccept
=
1
;
m_marker
=
++
m_cursor
;
yych
=
*
m_cursor
;
json_parser_43
:
if
(
yybm
[
0
+
yych
]
&
32
)
{
goto
json_parser_42
;
}
if
(
yych
<=
'D'
)
{
if
(
yych
!=
'.'
)
{
goto
json_parser_13
;
}
goto
json_parser_55
;
}
else
goto
json_parser_19
;
json_parser_21
:
yyaccept
=
0
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
==
'a'
)
{
if
(
yych
<=
'E'
)
{
goto
json_parser_45
;
}
if
(
yych
==
'e'
)
{
goto
json_parser_45
;
}
goto
json_parser_13
;
goto
json_parser_50
;
}
json_parser_44
:
goto
json_parser_19
;
json_parser_22
:
yych
=
*++
m_cursor
;
if
(
yych
<=
'/'
)
{
goto
json_parser_
2
9
;
goto
json_parser_
1
9
;
}
if
(
yych
<=
'
9
'
)
if
(
yych
<=
'
0
'
)
{
goto
json_parser_49
;
}
goto
json_parser_29
;
json_parser_45
:
yych
=
*++
m_cursor
;
if
(
yych
<=
','
)
{
if
(
yych
!=
'+'
)
{
goto
json_parser_29
;
}
}
else
{
if
(
yych
<=
'-'
)
{
goto
json_parser_46
;
}
if
(
yych
<=
'/'
)
{
goto
json_parser_29
;
}
if
(
yych
<=
'9'
)
{
goto
json_parser_47
;
}
goto
json_parser_29
;
}
json_parser_46
:
yych
=
*++
m_cursor
;
if
(
yych
<=
'/'
)
{
goto
json_parser_29
;
}
if
(
yych
>=
':'
)
{
goto
json_parser_29
;
}
json_parser_47
:
++
m_cursor
;
yych
=
*
m_cursor
;
if
(
yych
<=
'/'
)
{
goto
json_parser_13
;
}
if
(
yych
<=
'9'
)
{
goto
json_parser_4
7
;
goto
json_parser_4
0
;
}
goto
json_parser_1
3
;
json_parser_
49
:
goto
json_parser_1
9
;
json_parser_
23
:
yyaccept
=
1
;
m_marker
=
++
m_cursor
;
yych
=
*
m_cursor
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
<=
'D'
)
{
if
(
yych
<=
'/'
)
{
goto
json_parser_13
;
}
if
(
yych
<=
'9'
)
if
(
yych
==
'.'
)
{
goto
json_parser_4
9
;
goto
json_parser_4
2
;
}
goto
json_parser_13
;
}
else
{
if
(
yych
<=
'E'
)
{
goto
json_parser_4
5
;
goto
json_parser_4
3
;
}
if
(
yych
==
'e'
)
{
goto
json_parser_4
5
;
goto
json_parser_4
3
;
}
goto
json_parser_13
;
}
json_parser_51
:
json_parser_24
:
{
return
token_type
::
value_number
;
}
json_parser_25
:
yyaccept
=
1
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
<=
'D'
)
goto
json_parser_41
;
json_parser_26
:
yyaccept
=
0
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
<=
0x00
)
{
if
(
yych
==
'.'
)
{
goto
json_parser_44
;
}
goto
json_parser_13
;
goto
json_parser_19
;
}
else
goto
json_parser_31
;
json_parser_27
:
++
m_cursor
;
{
if
(
yych
<=
'E'
)
{
goto
json_parser_45
;
}
if
(
yych
==
'e'
)
{
goto
json_parser_45
;
}
goto
json_parser_13
;
return
token_type
::
end_of_input
;
}
json_parser_52
:
json_parser_29
:
yych
=
*++
m_cursor
;
goto
json_parser_19
;
json_parser_30
:
++
m_cursor
;
yych
=
*
m_cursor
;
json_parser_
53
:
json_parser_
31
:
if
(
yybm
[
0
+
yych
]
&
64
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
if
(
yych
<=
0x00
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
<=
'"'
)
{
goto
json_parser_55
;
goto
json_parser_34
;
}
goto
json_parser_33
;
json_parser_32
:
m_cursor
=
m_marker
;
if
(
yyaccept
==
0
)
{
goto
json_parser_19
;
}
else
{
goto
json_parser_24
;
}
json_parser_33
:
++
m_cursor
;
yych
=
*
m_cursor
;
if
(
yych
<=
'e'
)
...
...
@@ -2975,13 +2802,13 @@ json_parser_53:
{
if
(
yych
==
'"'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
if
(
yych
<=
'.'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
goto
json_parser_
52
;
goto
json_parser_
30
;
}
else
{
...
...
@@ -2989,17 +2816,17 @@ json_parser_53:
{
if
(
yych
<=
'['
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
goto
json_parser_
52
;
goto
json_parser_
30
;
}
else
{
if
(
yych
==
'b'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
goto
json_parser_
29
;
goto
json_parser_
32
;
}
}
}
...
...
@@ -3009,13 +2836,13 @@ json_parser_53:
{
if
(
yych
<=
'f'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
if
(
yych
==
'n'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
goto
json_parser_
29
;
goto
json_parser_
32
;
}
else
{
...
...
@@ -3023,156 +2850,334 @@ json_parser_53:
{
if
(
yych
<=
'r'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
goto
json_parser_
29
;
goto
json_parser_
32
;
}
else
{
if
(
yych
<=
't'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
if
(
yych
<=
'u'
)
{
goto
json_parser_
57
;
goto
json_parser_
36
;
}
goto
json_parser_
29
;
goto
json_parser_
32
;
}
}
}
json_parser_
55
:
json_parser_
34
:
++
m_cursor
;
{
return
token_type
::
value_string
;
}
json_parser_
57
:
json_parser_
36
:
++
m_cursor
;
yych
=
*
m_cursor
;
if
(
yych
<=
'@'
)
{
if
(
yych
<=
'/'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
>=
':'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
}
else
{
if
(
yych
<=
'F'
)
{
goto
json_parser_
58
;
goto
json_parser_
37
;
}
if
(
yych
<=
'`'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
>=
'g'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
}
json_parser_
58
:
json_parser_
37
:
++
m_cursor
;
yych
=
*
m_cursor
;
if
(
yych
<=
'@'
)
{
if
(
yych
<=
'/'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
>=
':'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
}
else
{
if
(
yych
<=
'F'
)
{
goto
json_parser_
59
;
goto
json_parser_
38
;
}
if
(
yych
<=
'`'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
>=
'g'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
}
json_parser_
59
:
json_parser_
38
:
++
m_cursor
;
yych
=
*
m_cursor
;
if
(
yych
<=
'@'
)
{
if
(
yych
<=
'/'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
>=
':'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
}
else
{
if
(
yych
<=
'F'
)
{
goto
json_parser_
60
;
goto
json_parser_
39
;
}
if
(
yych
<=
'`'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
>=
'g'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
}
json_parser_
60
:
json_parser_
39
:
++
m_cursor
;
yych
=
*
m_cursor
;
if
(
yych
<=
'@'
)
{
if
(
yych
<=
'/'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
<=
'9'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
goto
json_parser_
29
;
goto
json_parser_
32
;
}
else
{
if
(
yych
<=
'F'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
if
(
yych
<=
'`'
)
{
goto
json_parser_
29
;
goto
json_parser_
32
;
}
if
(
yych
<=
'f'
)
{
goto
json_parser_
52
;
goto
json_parser_
30
;
}
goto
json_parser_
29
;
goto
json_parser_
32
;
}
json_parser_61
:
++
m_cursor
;
json_parser_40
:
yyaccept
=
1
;
m_marker
=
++
m_cursor
;
yych
=
*
m_cursor
;
json_parser_
62
:
json_parser_
41
:
if
(
yybm
[
0
+
yych
]
&
128
)
{
goto
json_parser_61
;
goto
json_parser_40
;
}
if
(
yych
<=
'D'
)
{
if
(
yych
!=
'.'
)
{
goto
json_parser_24
;
}
}
else
{
if
(
yych
<=
'E'
)
{
goto
json_parser_43
;
}
if
(
yych
==
'e'
)
{
goto
json_parser_43
;
}
goto
json_parser_24
;
}
json_parser_42
:
yych
=
*++
m_cursor
;
if
(
yych
<=
'/'
)
{
goto
json_parser_32
;
}
if
(
yych
<=
'9'
)
{
goto
json_parser_47
;
}
goto
json_parser_32
;
json_parser_43
:
yych
=
*++
m_cursor
;
if
(
yych
<=
','
)
{
if
(
yych
!=
'+'
)
{
goto
json_parser_32
;
}
}
else
{
if
(
yych
<=
'-'
)
{
goto
json_parser_44
;
}
if
(
yych
<=
'/'
)
{
goto
json_parser_32
;
}
if
(
yych
<=
'9'
)
{
goto
json_parser_45
;
}
goto
json_parser_32
;
}
json_parser_44
:
yych
=
*++
m_cursor
;
if
(
yych
<=
'/'
)
{
goto
json_parser_32
;
}
if
(
yych
>=
':'
)
{
goto
json_parser_32
;
}
json_parser_45
:
++
m_cursor
;
yych
=
*
m_cursor
;
if
(
yych
<=
'/'
)
{
goto
json_parser_24
;
}
if
(
yych
<=
'9'
)
{
goto
json_parser_45
;
}
goto
json_parser_24
;
json_parser_47
:
yyaccept
=
1
;
m_marker
=
++
m_cursor
;
yych
=
*
m_cursor
;
if
(
yych
<=
'D'
)
{
if
(
yych
<=
'/'
)
{
goto
json_parser_24
;
}
if
(
yych
<=
'9'
)
{
goto
json_parser_47
;
}
goto
json_parser_24
;
}
else
{
if
(
yych
<=
'E'
)
{
goto
json_parser_43
;
}
if
(
yych
==
'e'
)
{
goto
json_parser_43
;
}
goto
json_parser_24
;
}
json_parser_49
:
yyaccept
=
1
;
yych
=
*
(
m_marker
=
++
m_cursor
);
if
(
yych
<=
'D'
)
{
if
(
yych
==
'.'
)
{
goto
json_parser_42
;
}
goto
json_parser_24
;
}
else
{
if
(
yych
<=
'E'
)
{
goto
json_parser_43
;
}
if
(
yych
==
'e'
)
{
goto
json_parser_43
;
}
goto
json_parser_24
;
}
json_parser_50
:
yych
=
*++
m_cursor
;
if
(
yych
!=
'l'
)
{
goto
json_parser_32
;
}
yych
=
*++
m_cursor
;
if
(
yych
!=
's'
)
{
goto
json_parser_32
;
}
yych
=
*++
m_cursor
;
if
(
yych
!=
'e'
)
{
goto
json_parser_32
;
}
++
m_cursor
;
{
return
token_type
::
literal_false
;
}
json_parser_55
:
yych
=
*++
m_cursor
;
if
(
yych
!=
'u'
)
{
goto
json_parser_32
;
}
yych
=
*++
m_cursor
;
if
(
yych
!=
'e'
)
{
goto
json_parser_32
;
}
++
m_cursor
;
{
return
token_type
::
literal_true
;
}
json_parser_59
:
yych
=
*++
m_cursor
;
if
(
yych
!=
'l'
)
{
goto
json_parser_32
;
}
yych
=
*++
m_cursor
;
if
(
yych
!=
'l'
)
{
goto
json_parser_32
;
}
++
m_cursor
;
{
return
token_type
::
literal_null
;
}
goto
json_parser_2
;
}
}
...
...
@@ -3261,8 +3266,20 @@ json_parser_62:
get_token
();
}
/// public parser interface
inline
basic_json
parse
()
{
basic_json
result
=
parse_internal
();
expect
(
lexer
::
token_type
::
end_of_input
);
return
result
;
}
private
:
/// the actual parser
inline
basic_json
parse_internal
()
{
switch
(
last_token
)
{
case
(
lexer
:
:
token_type
::
begin_object
)
:
...
...
@@ -3276,12 +3293,19 @@ json_parser_62:
// closing } -> we are done
if
(
last_token
==
lexer
::
token_type
::
end_object
)
{
get_token
();
return
result
;
}
// otherwise: parse key-value pairs
do
{
// ugly, but could be fixed with loop reorganization
if
(
last_token
==
lexer
::
token_type
::
value_separator
)
{
get_token
();
}
// store key
expect
(
lexer
::
token_type
::
value_string
);
const
auto
key
=
m_lexer
.
get_string
();
...
...
@@ -3292,16 +3316,13 @@ json_parser_62:
// parse value
get_token
();
result
[
key
]
=
parse
();
// read next character
get_token
();
result
[
key
]
=
parse_internal
();
}
while
(
last_token
==
lexer
::
token_type
::
value_separator
and
get_token
()
==
last_token
);
while
(
last_token
==
lexer
::
token_type
::
value_separator
);
// closing }
expect
(
lexer
::
token_type
::
end_object
);
get_token
();
return
result
;
}
...
...
@@ -3317,44 +3338,53 @@ json_parser_62:
// closing ] -> we are done
if
(
last_token
==
lexer
::
token_type
::
end_array
)
{
get_token
();
return
result
;
}
// otherwise: parse values
do
{
// parse value
result
.
push_back
(
parse
());
// ugly, but could be fixed with loop reorganization
if
(
last_token
==
lexer
::
token_type
::
value_separator
)
{
get_token
();
}
//
read next character
get_token
(
);
//
parse value
result
.
push_back
(
parse_internal
()
);
}
while
(
last_token
==
lexer
::
token_type
::
value_separator
and
get_token
()
==
last_token
);
while
(
last_token
==
lexer
::
token_type
::
value_separator
);
// closing ]
expect
(
lexer
::
token_type
::
end_array
);
get_token
();
return
result
;
}
case
(
lexer
:
:
token_type
::
literal_null
)
:
{
get_token
();
return
basic_json
(
nullptr
);
}
case
(
lexer
:
:
token_type
::
value_string
)
:
{
return
basic_json
(
m_lexer
.
get_string
());
const
auto
s
=
m_lexer
.
get_string
();
get_token
();
return
basic_json
(
s
);
}
case
(
lexer
:
:
token_type
::
literal_true
)
:
{
get_token
();
return
basic_json
(
true
);
}
case
(
lexer
:
:
token_type
::
literal_false
)
:
{
get_token
();
return
basic_json
(
false
);
}
...
...
@@ -3368,6 +3398,8 @@ json_parser_62:
m_lexer
.
get_string_value
()
+
" is not a number"
);
}
get_token
();
// check if conversion loses precision
const
auto
int_val
=
static_cast
<
number_integer_t
>
(
float_val
);
if
(
float_val
==
int_val
)
...
...
@@ -3393,7 +3425,6 @@ json_parser_62:
}
}
private
:
/// get next token from lexer
inline
typename
lexer
::
token_type
get_token
()
{
...
...
src/json.hpp.re2c
View file @
89a1b024
...
...
@@ -2524,7 +2524,7 @@ class basic_json
'\000' { return token_type::end_of_input; }
// anything else is an error
*
{ return token_type::parse_error; }
.
{ return token_type::parse_error; }
*/
}
...
...
@@ -2612,8 +2612,20 @@ class basic_json
get_token();
}
/// public parser interface
inline basic_json parse()
{
basic_json result = parse_internal();
expect(lexer::token_type::end_of_input);
return result;
}
private:
/// the actual parser
inline basic_json parse_internal()
{
switch (last_token)
{
case (lexer::token_type::begin_object):
...
...
@@ -2627,12 +2639,19 @@ class basic_json
// closing } -> we are done
if (last_token == lexer::token_type::end_object)
{
get_token();
return result;
}
// otherwise: parse key-value pairs
do
{
// ugly, but could be fixed with loop reorganization
if (last_token == lexer::token_type::value_separator)
{
get_token();
}
// store key
expect(lexer::token_type::value_string);
const auto key = m_lexer.get_string();
...
...
@@ -2643,16 +2662,13 @@ class basic_json
// parse value
get_token();
result[key] = parse();
// read next character
get_token();
result[key] = parse_internal();
}
while (last_token == lexer::token_type::value_separator
and get_token() == last_token);
while (last_token == lexer::token_type::value_separator);
// closing }
expect(lexer::token_type::end_object);
get_token();
return result;
}
...
...
@@ -2668,44 +2684,53 @@ class basic_json
// closing ] -> we are done
if (last_token == lexer::token_type::end_array)
{
get_token();
return result;
}
// otherwise: parse values
do
{
// parse value
result.push_back(parse());
// ugly, but could be fixed with loop reorganization
if (last_token == lexer::token_type::value_separator)
{
get_token();
}
//
read next character
get_token(
);
//
parse value
result.push_back(parse_internal()
);
}
while (last_token == lexer::token_type::value_separator
and get_token() == last_token);
while (last_token == lexer::token_type::value_separator);
// closing ]
expect(lexer::token_type::end_array);
get_token();
return result;
}
case (lexer::token_type::literal_null):
{
get_token();
return basic_json(nullptr);
}
case (lexer::token_type::value_string):
{
return basic_json(m_lexer.get_string());
const auto s = m_lexer.get_string();
get_token();
return basic_json(s);
}
case (lexer::token_type::literal_true):
{
get_token();
return basic_json(true);
}
case (lexer::token_type::literal_false):
{
get_token();
return basic_json(false);
}
...
...
@@ -2719,6 +2744,8 @@ class basic_json
m_lexer.get_string_value() + " is not a number");
}
get_token();
// check if conversion loses precision
const auto int_val = static_cast<number_integer_t>(float_val);
if (float_val == int_val)
...
...
@@ -2744,7 +2771,6 @@ class basic_json
}
}
private:
/// get next token from lexer
inline typename lexer::token_type get_token()
{
...
...
test/unit.cpp
View file @
89a1b024
...
...
@@ -5052,7 +5052,15 @@ TEST_CASE("parser class")
CHECK_THROWS_AS
(
json
::
parser
(
"--"
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"-0."
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"-."
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"-:"
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"0.:"
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"e."
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"1e."
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"1e/"
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"1e:"
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"1E."
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"1E/"
).
parse
(),
std
::
invalid_argument
);
CHECK_THROWS_AS
(
json
::
parser
(
"1E:"
).
parse
(),
std
::
invalid_argument
);
// unexpected end of null
CHECK_THROWS_AS
(
json
::
parser
(
"n"
).
parse
(),
std
::
invalid_argument
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment