blob: ed0fcfbcbdfe0eae75f83cdba223232797823175 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
require "../spec_helper"
include Parcom
# NOTE: WORK IN PROGRESS
alias JSONType = Nil \
| Bool \
| Int64 \
| Float64 \
| String \
| Array(JSONValue) \
| Hash(String, JSONValue)
struct JSONValue
property data : JSONType
def initialize(@data)
end
end
def json_null
Parser.token_sequence("null".chars).map { |_| JSONValue.new(nil) }
end
def json_bool
t = Parser.token_sequence("true".chars).map { |_| true }
f = Parser.token_sequence("false".chars).map { |_| false }
(t | f).map { |b| JSONValue.new(b) }
end
# Only standard decimal ints for now
def json_number
base_num = Parser(Char, Char).satisfy(&.ascii_number?).some.map do |cs|
cs.join.to_i64
end
sign = Parser.token('-').map { |_| -1 }.recover(1)
(sign + base_num).map { |s, n| JSONValue.new(s.to_i64 * n) }
end
def json_value : Parser(Char, JSONValue)
Parser.first_of([
json_null,
json_bool,
json_number,
])
end
describe "example: JSON parsing" do
describe "json_null" do
it "parses the string 'null' and returns nil when successful" do
result = json_null.parse(Tokens.from_string("null"))
result.value.data.should be_nil
result.tokens.empty?.should be_true
expect_raises(ParserFail) { json_null.parse(Tokens.from_string("")) }
end
end
describe "json_bool" do
it "parses the strings 'true' or 'false' and returns bool" do
result = json_bool.parse(Tokens.from_string("true"))
result.value.data.should be_true
result.tokens.empty?.should be_true
result = json_bool.parse(Tokens.from_string("false"))
result.value.data.should be_false
result.tokens.empty?.should be_true
expect_raises(ParserFail) { json_bool.parse(Tokens.from_string("")) }
end
end
describe "json_number" do
it "parses strings of digits and other key characters and converts to number" do
result = json_number.parse(Tokens.from_string("42"))
result.value.data.should eq(42)
result.tokens.empty?.should be_true
result = json_number.parse(Tokens.from_string("-42"))
result.value.data.should eq(-42)
result.tokens.empty?.should be_true
expect_raises(ParserFail) { json_number.parse(Tokens.from_string("")) }
expect_raises(ParserFail) { json_number.parse(Tokens.from_string("foo")) }
end
end
describe "json_value" do
it "parses null" do
result = json_value.parse(Tokens.from_string("null"))
result.value.data.should be_nil
result.tokens.empty?.should be_true
end
it "parses bools" do
result = json_value.parse(Tokens.from_string("true"))
result.value.data.should be_true
result.tokens.empty?.should be_true
result = json_value.parse(Tokens.from_string("false"))
result.value.data.should be_false
result.tokens.empty?.should be_true
end
it "parsers ints" do
result = json_value.parse(Tokens.from_string("42"))
result.value.data.should eq(42)
result.tokens.empty?.should be_true
result = json_value.parse(Tokens.from_string("-42"))
result.value.data.should eq(-42)
result.tokens.empty?.should be_true
end
end
end
|