elparser 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +14 -6
- data/lib/elparser/parser.tab.rb +45 -48
- data/lib/elparser/parser.y +2 -2
- data/lib/elparser/version.rb +1 -1
- data/lib/elparser.rb +17 -4
- data/test/test-elparser.rb +29 -10
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c46cda5b6979d0d53eb8871d00f31c8fd00488e2
|
4
|
+
data.tar.gz: a25c9a3a14e70d18fa006a99ac26be7bb0830dd9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef81f3be2cfd6d718ea7274f8455a9d819afca7d3368a3821bef185747e6f7c7f12452d724831888af3ae8599913afb2ac17d8662445e0f8c1a6d996dd220cae
|
7
|
+
data.tar.gz: c55ee9e094eb10d004514167a1a3ebb361d60bdf754eb0bc9fe9cbf8a8915b5adfdc08c33aa6e8101193d96d142c092b624ca1df618eb98165c52cef78fa586c
|
data/README.md
CHANGED
@@ -12,7 +12,7 @@ require 'elparser'
|
|
12
12
|
parser = Elparser::Parser.new
|
13
13
|
|
14
14
|
# list and literals
|
15
|
-
obj1 = parser.
|
15
|
+
obj1 = parser.parse1("(1 2.3 a \"b\" () (c 'd))")
|
16
16
|
|
17
17
|
p obj1.to_ruby
|
18
18
|
# => [1, 2.3, :a, "b", nil, [:c, [:d]]]
|
@@ -61,11 +61,13 @@ Or install it yourself as:
|
|
61
61
|
|
62
62
|
The class `Elparser::Parser` is parser for emacs-lisp S-expression.
|
63
63
|
The user program creates an instance of the class and parses the S-exp
|
64
|
-
string with `
|
64
|
+
string with `parse1` method. If the source string has multiple
|
65
|
+
S-expressions, one can use `parse` method.
|
65
66
|
|
66
|
-
If the `
|
67
|
-
returns a `SExp` object which is AST of S-exp. Invoking
|
68
|
-
method of the `SExp` object, one can obtain a ruby object.
|
67
|
+
If the `Parser#parse1` method succeed in parsing the given S-exp
|
68
|
+
string, it returns a `SExp` object which is AST of S-exp. Invoking
|
69
|
+
`to_ruby` method of the `SExp` object, one can obtain a ruby object.
|
70
|
+
`Parser#parse` method returns an array of `SExp` objects.
|
69
71
|
|
70
72
|
The `SExp` objects are instances of `SExpXXX` classes: `SExpNumber`,
|
71
73
|
`SExpString`, `SExpSymbol`, `SExpNil`, `SExpCons`, `SExpList`,
|
@@ -78,7 +80,9 @@ a `Hash` object can be obtained.
|
|
78
80
|
### Encoder
|
79
81
|
|
80
82
|
The module method `Elparser::encode` encodes the ruby objects into
|
81
|
-
elisp S-expressions.
|
83
|
+
elisp S-expressions. The another method `Elparser::encode_multi`
|
84
|
+
receives an array of ruby objects and returns a S-expression string in
|
85
|
+
which multiple S-expressions are concatenated.
|
82
86
|
|
83
87
|
If an object which is not defined in serialization rules is given,
|
84
88
|
this method raises the exception `StandardError` with some messages.
|
@@ -129,3 +133,7 @@ such S-expressions with creating instances of `SExpCons` and
|
|
129
133
|
| hash | `{"a" => "b", "c" => "d"}` | `(("a" . "b") ("c" . "d"))` |
|
130
134
|
| hash | `{:a => [1,2,3], :b => {:c => [4,5,6]}}` | `((a 1 2 3) (b (c 4 5 6)))` |
|
131
135
|
|
136
|
+
## License
|
137
|
+
|
138
|
+
Copyright (c) 2015 SAKURAI Masashi
|
139
|
+
Released under the MIT license
|
data/lib/elparser/parser.tab.rb
CHANGED
@@ -10,65 +10,67 @@ module Elparser
|
|
10
10
|
##### State transition tables begin ###
|
11
11
|
|
12
12
|
racc_action_table = [
|
13
|
-
|
14
|
-
|
15
|
-
nil,
|
16
|
-
|
13
|
+
11, 22, 12, 13, 17, 14, 15, 16, 11, 26,
|
14
|
+
12, 13, nil, 14, 15, 16, 11, nil, 12, 13,
|
15
|
+
nil, 14, 15, 16, 11, 20, 12, 13, nil, 14,
|
16
|
+
15, 16, 11, 24, 12, 13, 23, 14, 15, 16,
|
17
|
+
11, nil, 12, 13, nil, 14, 15, 16 ]
|
17
18
|
|
18
19
|
racc_action_check = [
|
19
|
-
0,
|
20
|
-
23, 23, nil, 23, 23, 23,
|
21
|
-
nil,
|
22
|
-
|
20
|
+
0, 17, 0, 0, 1, 0, 0, 0, 23, 25,
|
21
|
+
23, 23, nil, 23, 23, 23, 2, nil, 2, 2,
|
22
|
+
nil, 2, 2, 2, 11, 11, 11, 11, nil, 11,
|
23
|
+
11, 11, 19, 19, 19, 19, 19, 19, 19, 19,
|
24
|
+
14, nil, 14, 14, nil, 14, 14, 14 ]
|
23
25
|
|
24
26
|
racc_action_pointer = [
|
25
|
-
-2, 4,
|
26
|
-
|
27
|
+
-2, 4, 14, nil, nil, nil, nil, nil, nil, nil,
|
28
|
+
nil, 22, nil, nil, 38, nil, nil, 1, nil, 30,
|
27
29
|
nil, nil, nil, 6, nil, 6, nil ]
|
28
30
|
|
29
31
|
racc_action_default = [
|
30
32
|
-19, -19, -1, -2, -3, -4, -5, -6, -7, -8,
|
31
|
-
-19, -12, -13, -19, -17, -18, -19,
|
32
|
-
-16, 27, -
|
33
|
+
-9, -19, -12, -13, -19, -17, -18, -19, -10, -19,
|
34
|
+
-11, -16, 27, -19, -15, -19, -14 ]
|
33
35
|
|
34
36
|
racc_goto_table = [
|
35
|
-
|
36
|
-
|
37
|
-
nil,
|
37
|
+
18, 1, 2, nil, nil, nil, nil, nil, nil, nil,
|
38
|
+
nil, nil, 21, 19, nil, nil, nil, 18, nil, nil,
|
39
|
+
nil, 25 ]
|
38
40
|
|
39
41
|
racc_goto_check = [
|
40
|
-
|
41
|
-
|
42
|
-
nil,
|
42
|
+
3, 1, 2, nil, nil, nil, nil, nil, nil, nil,
|
43
|
+
nil, nil, 3, 2, nil, nil, nil, 3, nil, nil,
|
44
|
+
nil, 3 ]
|
43
45
|
|
44
46
|
racc_goto_pointer = [
|
45
|
-
nil, 1,
|
46
|
-
|
47
|
+
nil, 1, 2, -2, nil, nil, nil, nil, nil, nil,
|
48
|
+
nil ]
|
47
49
|
|
48
50
|
racc_goto_default = [
|
49
|
-
nil, nil, nil, 3, 4, 5, 6, 7, 8,
|
50
|
-
|
51
|
+
nil, nil, nil, 10, 3, 4, 5, 6, 7, 8,
|
52
|
+
9 ]
|
51
53
|
|
52
54
|
racc_reduce_table = [
|
53
55
|
0, 0, :racc_error,
|
54
|
-
1, 11, :
|
55
|
-
1,
|
56
|
-
1,
|
57
|
-
1,
|
58
|
-
1,
|
59
|
-
1,
|
60
|
-
1,
|
61
|
-
1,
|
62
|
-
1,
|
63
|
-
2,
|
64
|
-
2,
|
65
|
-
1,
|
66
|
-
1,
|
67
|
-
5,
|
68
|
-
3,
|
69
|
-
2,
|
70
|
-
1,
|
71
|
-
1,
|
56
|
+
1, 11, :_reduce_none,
|
57
|
+
1, 13, :_reduce_none,
|
58
|
+
1, 13, :_reduce_none,
|
59
|
+
1, 13, :_reduce_none,
|
60
|
+
1, 13, :_reduce_none,
|
61
|
+
1, 13, :_reduce_none,
|
62
|
+
1, 13, :_reduce_none,
|
63
|
+
1, 13, :_reduce_none,
|
64
|
+
1, 12, :_reduce_9,
|
65
|
+
2, 12, :_reduce_10,
|
66
|
+
2, 14, :_reduce_11,
|
67
|
+
1, 15, :_reduce_12,
|
68
|
+
1, 15, :_reduce_13,
|
69
|
+
5, 16, :_reduce_14,
|
70
|
+
3, 19, :_reduce_15,
|
71
|
+
2, 20, :_reduce_16,
|
72
|
+
1, 17, :_reduce_17,
|
73
|
+
1, 18, :_reduce_18 ]
|
72
74
|
|
73
75
|
racc_reduce_n = 19
|
74
76
|
|
@@ -119,6 +121,7 @@ Racc_token_to_s_table = [
|
|
119
121
|
"STRING",
|
120
122
|
"$start",
|
121
123
|
"target",
|
124
|
+
"sexp_seq",
|
122
125
|
"sexp",
|
123
126
|
"nil",
|
124
127
|
"val",
|
@@ -126,8 +129,7 @@ Racc_token_to_s_table = [
|
|
126
129
|
"symbol",
|
127
130
|
"string",
|
128
131
|
"list",
|
129
|
-
"quoted"
|
130
|
-
"sexp_seq" ]
|
132
|
+
"quoted" ]
|
131
133
|
|
132
134
|
Racc_debug_parser = false
|
133
135
|
|
@@ -135,12 +137,7 @@ Racc_debug_parser = false
|
|
135
137
|
|
136
138
|
# reduce 0 omitted
|
137
139
|
|
138
|
-
|
139
|
-
def _reduce_1(val, _values, result)
|
140
|
-
|
141
|
-
result
|
142
|
-
end
|
143
|
-
.,.,
|
140
|
+
# reduce 1 omitted
|
144
141
|
|
145
142
|
# reduce 2 omitted
|
146
143
|
|
data/lib/elparser/parser.y
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
class Elparser::Parser
|
2
2
|
|
3
3
|
rule
|
4
|
-
target:
|
4
|
+
target: sexp_seq
|
5
5
|
|
6
|
-
sexp: nil | val | cons | symbol | string | list | quoted
|
6
|
+
sexp: nil | val | cons | symbol | string | list | quoted
|
7
7
|
|
8
8
|
sexp_seq: sexp { result = [val[0]] }
|
9
9
|
| sexp_seq sexp { result << val[1] }
|
data/lib/elparser/version.rb
CHANGED
data/lib/elparser.rb
CHANGED
@@ -219,6 +219,11 @@ module Elparser
|
|
219
219
|
# parser class for
|
220
220
|
class Parser
|
221
221
|
|
222
|
+
# parse s-expression string and return one sexp object.
|
223
|
+
def parse1(str)
|
224
|
+
parse(str)[0]
|
225
|
+
end
|
226
|
+
|
222
227
|
# parse s-expression string and return sexp objects.
|
223
228
|
def parse(str)
|
224
229
|
s = StringScanner.new str
|
@@ -236,7 +241,9 @@ module Elparser
|
|
236
241
|
end
|
237
242
|
@tokens.push [false, '$end']
|
238
243
|
|
239
|
-
|
244
|
+
return do_parse.map do |i|
|
245
|
+
normalize(i)
|
246
|
+
end
|
240
247
|
end
|
241
248
|
|
242
249
|
def next_token
|
@@ -262,9 +269,15 @@ module Elparser
|
|
262
269
|
end
|
263
270
|
|
264
271
|
|
265
|
-
#
|
266
|
-
def self.encode(
|
267
|
-
return _encode(
|
272
|
+
# Translate a ruby object to s-expression string.
|
273
|
+
def self.encode(obj)
|
274
|
+
return _encode(obj).to_s
|
275
|
+
end
|
276
|
+
|
277
|
+
# Translate many ruby objects to s-expression string.
|
278
|
+
# The result s-exps are concatenated into one string.
|
279
|
+
def self.encode_multi(objs, sep = "\n")
|
280
|
+
return objs.map {|obj| _encode(obj).to_s }.join(sep)
|
268
281
|
end
|
269
282
|
|
270
283
|
private
|
data/test/test-elparser.rb
CHANGED
@@ -68,11 +68,17 @@ class TestElparser < Test::Unit::TestCase
|
|
68
68
|
})
|
69
69
|
def test_primitive(data)
|
70
70
|
src, expected = data
|
71
|
-
assert_equal expected, @parser.
|
71
|
+
assert_equal expected, @parser.parse1(src)
|
72
72
|
end
|
73
73
|
|
74
74
|
end
|
75
75
|
|
76
|
+
test "Multiple S-exp" do
|
77
|
+
src = "(1 2) (3 4)"
|
78
|
+
exp = [_list(_int(1),_int(2)),_list(_int(3),_int(4))]
|
79
|
+
assert_equal exp, @parser.parse(src)
|
80
|
+
end
|
81
|
+
|
76
82
|
sub_test_case "List Structure" do
|
77
83
|
|
78
84
|
data({
|
@@ -89,7 +95,7 @@ class TestElparser < Test::Unit::TestCase
|
|
89
95
|
})
|
90
96
|
def test_list(data)
|
91
97
|
src, expected = data
|
92
|
-
assert_equal expected, @parser.
|
98
|
+
assert_equal expected, @parser.parse1(src)
|
93
99
|
end
|
94
100
|
|
95
101
|
end
|
@@ -97,13 +103,13 @@ class TestElparser < Test::Unit::TestCase
|
|
97
103
|
sub_test_case "Cons and List operation" do
|
98
104
|
|
99
105
|
def test_cons1
|
100
|
-
v = @parser.
|
106
|
+
v = @parser.parse1("(1 . 2)")
|
101
107
|
assert_equal _int(1), v.car
|
102
108
|
assert_equal _int(2), v.cdr
|
103
109
|
end
|
104
110
|
|
105
111
|
def test_list1
|
106
|
-
v = @parser.
|
112
|
+
v = @parser.parse1("(1 2 3)")
|
107
113
|
assert_equal _int(1), v.car
|
108
114
|
assert_equal _int(2), v.cdr.car
|
109
115
|
assert_equal _int(3), v.cdr.cdr.car
|
@@ -111,14 +117,14 @@ class TestElparser < Test::Unit::TestCase
|
|
111
117
|
end
|
112
118
|
|
113
119
|
def test_dotlist
|
114
|
-
v = @parser.
|
120
|
+
v = @parser.parse1("(1 2 . 3)")
|
115
121
|
assert_equal _int(1), v.car
|
116
122
|
assert_equal _int(2), v.cdr.car
|
117
123
|
assert_equal _int(3), v.cdr.cdr
|
118
124
|
end
|
119
125
|
|
120
126
|
def test_ruby_object
|
121
|
-
v = @parser.
|
127
|
+
v = @parser.parse1("(1 2.1 \"xxx\" www)")
|
122
128
|
ro = v.to_ruby
|
123
129
|
assert_equal ro.size, 4
|
124
130
|
assert_equal ro[0], 1
|
@@ -126,7 +132,7 @@ class TestElparser < Test::Unit::TestCase
|
|
126
132
|
assert_equal ro[2], "xxx"
|
127
133
|
assert_equal ro[3], :www
|
128
134
|
|
129
|
-
v = @parser.
|
135
|
+
v = @parser.parse1("(1 (2 3 (4)))")
|
130
136
|
ro = v.to_ruby
|
131
137
|
assert_equal ro.size, 2
|
132
138
|
assert_equal ro[0], 1
|
@@ -136,7 +142,7 @@ class TestElparser < Test::Unit::TestCase
|
|
136
142
|
end
|
137
143
|
|
138
144
|
def test_alist
|
139
|
-
v = @parser.
|
145
|
+
v = @parser.parse1("( (a . 1) (b . \"xxx\") (c 3 4) (\"d\" . \"e\"))")
|
140
146
|
assert_true v.alist?
|
141
147
|
hash = v.to_h
|
142
148
|
assert_equal hash[:a], 1
|
@@ -144,9 +150,9 @@ class TestElparser < Test::Unit::TestCase
|
|
144
150
|
assert_equal hash[:c], [3,4]
|
145
151
|
assert_equal hash["d"], "e"
|
146
152
|
|
147
|
-
v = @parser.
|
153
|
+
v = @parser.parse1("((a . 1) (b))")
|
148
154
|
assert_true v.alist?
|
149
|
-
v = @parser.
|
155
|
+
v = @parser.parse1("((a . 1) b)")
|
150
156
|
assert_false v.alist?
|
151
157
|
end
|
152
158
|
|
@@ -169,6 +175,19 @@ class TestElparser < Test::Unit::TestCase
|
|
169
175
|
assert_equal(expected, Elparser.encode(src))
|
170
176
|
end
|
171
177
|
|
178
|
+
def test_multiple_lines
|
179
|
+
src = [
|
180
|
+
[:defvar, :abc, 1, "var doc"],
|
181
|
+
[:defun, :cdef, [:'&optional', :a, :b],
|
182
|
+
[:interactive],
|
183
|
+
[:message, "hello world"],
|
184
|
+
],
|
185
|
+
]
|
186
|
+
exp = "(defvar abc 1 \"var doc\")
|
187
|
+
(defun cdef (&optional a b) (interactive) (message \"hello world\"))"
|
188
|
+
assert_equal(exp, Elparser.encode_multi(src))
|
189
|
+
end
|
190
|
+
|
172
191
|
end
|
173
192
|
|
174
193
|
end
|