kpeg 0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,322 @@
1
+ require 'kpeg/compiled_parser'
2
+
3
+ class KPeg::StringEscape < KPeg::CompiledParser
4
+
5
+
6
+ attr_reader :text
7
+
8
+
9
+
10
+ # segment = (< /[\w ]+/ > { text } | "\\" { "\\\\" } | "\n" { "\\n" } | "\t" { "\\t" } | "\b" { "\\b" } | "\"" { "\\\"" } | < . > { text })
11
+ def _segment
12
+
13
+ _save = self.pos
14
+ while true # choice
15
+
16
+ _save1 = self.pos
17
+ while true # sequence
18
+ _text_start = self.pos
19
+ _tmp = scan(/\A(?-mix:[\w ]+)/)
20
+ if _tmp
21
+ text = get_text(_text_start)
22
+ end
23
+ unless _tmp
24
+ self.pos = _save1
25
+ break
26
+ end
27
+ @result = begin; text ; end
28
+ _tmp = true
29
+ unless _tmp
30
+ self.pos = _save1
31
+ end
32
+ break
33
+ end # end sequence
34
+
35
+ break if _tmp
36
+ self.pos = _save
37
+
38
+ _save2 = self.pos
39
+ while true # sequence
40
+ _tmp = match_string("\\")
41
+ unless _tmp
42
+ self.pos = _save2
43
+ break
44
+ end
45
+ @result = begin; "\\\\" ; end
46
+ _tmp = true
47
+ unless _tmp
48
+ self.pos = _save2
49
+ end
50
+ break
51
+ end # end sequence
52
+
53
+ break if _tmp
54
+ self.pos = _save
55
+
56
+ _save3 = self.pos
57
+ while true # sequence
58
+ _tmp = match_string("\n")
59
+ unless _tmp
60
+ self.pos = _save3
61
+ break
62
+ end
63
+ @result = begin; "\\n" ; end
64
+ _tmp = true
65
+ unless _tmp
66
+ self.pos = _save3
67
+ end
68
+ break
69
+ end # end sequence
70
+
71
+ break if _tmp
72
+ self.pos = _save
73
+
74
+ _save4 = self.pos
75
+ while true # sequence
76
+ _tmp = match_string("\t")
77
+ unless _tmp
78
+ self.pos = _save4
79
+ break
80
+ end
81
+ @result = begin; "\\t" ; end
82
+ _tmp = true
83
+ unless _tmp
84
+ self.pos = _save4
85
+ end
86
+ break
87
+ end # end sequence
88
+
89
+ break if _tmp
90
+ self.pos = _save
91
+
92
+ _save5 = self.pos
93
+ while true # sequence
94
+ _tmp = match_string("\b")
95
+ unless _tmp
96
+ self.pos = _save5
97
+ break
98
+ end
99
+ @result = begin; "\\b" ; end
100
+ _tmp = true
101
+ unless _tmp
102
+ self.pos = _save5
103
+ end
104
+ break
105
+ end # end sequence
106
+
107
+ break if _tmp
108
+ self.pos = _save
109
+
110
+ _save6 = self.pos
111
+ while true # sequence
112
+ _tmp = match_string("\"")
113
+ unless _tmp
114
+ self.pos = _save6
115
+ break
116
+ end
117
+ @result = begin; "\\\"" ; end
118
+ _tmp = true
119
+ unless _tmp
120
+ self.pos = _save6
121
+ end
122
+ break
123
+ end # end sequence
124
+
125
+ break if _tmp
126
+ self.pos = _save
127
+
128
+ _save7 = self.pos
129
+ while true # sequence
130
+ _text_start = self.pos
131
+ _tmp = get_byte
132
+ if _tmp
133
+ text = get_text(_text_start)
134
+ end
135
+ unless _tmp
136
+ self.pos = _save7
137
+ break
138
+ end
139
+ @result = begin; text ; end
140
+ _tmp = true
141
+ unless _tmp
142
+ self.pos = _save7
143
+ end
144
+ break
145
+ end # end sequence
146
+
147
+ break if _tmp
148
+ self.pos = _save
149
+ break
150
+ end # end choice
151
+
152
+ set_failed_rule :_segment unless _tmp
153
+ return _tmp
154
+ end
155
+
156
+ # segments = (segment:s segments:r { "#{s}#{r}" } | segment)
157
+ def _segments
158
+
159
+ _save = self.pos
160
+ while true # choice
161
+
162
+ _save1 = self.pos
163
+ while true # sequence
164
+ _tmp = apply(:_segment)
165
+ s = @result
166
+ unless _tmp
167
+ self.pos = _save1
168
+ break
169
+ end
170
+ _tmp = apply(:_segments)
171
+ r = @result
172
+ unless _tmp
173
+ self.pos = _save1
174
+ break
175
+ end
176
+ @result = begin; "#{s}#{r}" ; end
177
+ _tmp = true
178
+ unless _tmp
179
+ self.pos = _save1
180
+ end
181
+ break
182
+ end # end sequence
183
+
184
+ break if _tmp
185
+ self.pos = _save
186
+ _tmp = apply(:_segment)
187
+ break if _tmp
188
+ self.pos = _save
189
+ break
190
+ end # end choice
191
+
192
+ set_failed_rule :_segments unless _tmp
193
+ return _tmp
194
+ end
195
+
196
+ # root = segments:s { @text = s }
197
+ def _root
198
+
199
+ _save = self.pos
200
+ while true # sequence
201
+ _tmp = apply(:_segments)
202
+ s = @result
203
+ unless _tmp
204
+ self.pos = _save
205
+ break
206
+ end
207
+ @result = begin; @text = s ; end
208
+ _tmp = true
209
+ unless _tmp
210
+ self.pos = _save
211
+ end
212
+ break
213
+ end # end sequence
214
+
215
+ set_failed_rule :_root unless _tmp
216
+ return _tmp
217
+ end
218
+
219
+ # embed_seg = ("#" { "\\#" } | segment)
220
+ def _embed_seg
221
+
222
+ _save = self.pos
223
+ while true # choice
224
+
225
+ _save1 = self.pos
226
+ while true # sequence
227
+ _tmp = match_string("#")
228
+ unless _tmp
229
+ self.pos = _save1
230
+ break
231
+ end
232
+ @result = begin; "\\#" ; end
233
+ _tmp = true
234
+ unless _tmp
235
+ self.pos = _save1
236
+ end
237
+ break
238
+ end # end sequence
239
+
240
+ break if _tmp
241
+ self.pos = _save
242
+ _tmp = apply(:_segment)
243
+ break if _tmp
244
+ self.pos = _save
245
+ break
246
+ end # end choice
247
+
248
+ set_failed_rule :_embed_seg unless _tmp
249
+ return _tmp
250
+ end
251
+
252
+ # embed_segs = (embed_seg:s embed_segs:r { "#{s}#{r}" } | embed_seg)
253
+ def _embed_segs
254
+
255
+ _save = self.pos
256
+ while true # choice
257
+
258
+ _save1 = self.pos
259
+ while true # sequence
260
+ _tmp = apply(:_embed_seg)
261
+ s = @result
262
+ unless _tmp
263
+ self.pos = _save1
264
+ break
265
+ end
266
+ _tmp = apply(:_embed_segs)
267
+ r = @result
268
+ unless _tmp
269
+ self.pos = _save1
270
+ break
271
+ end
272
+ @result = begin; "#{s}#{r}" ; end
273
+ _tmp = true
274
+ unless _tmp
275
+ self.pos = _save1
276
+ end
277
+ break
278
+ end # end sequence
279
+
280
+ break if _tmp
281
+ self.pos = _save
282
+ _tmp = apply(:_embed_seg)
283
+ break if _tmp
284
+ self.pos = _save
285
+ break
286
+ end # end choice
287
+
288
+ set_failed_rule :_embed_segs unless _tmp
289
+ return _tmp
290
+ end
291
+
292
+ # embed = embed_segs:s { @text = s }
293
+ def _embed
294
+
295
+ _save = self.pos
296
+ while true # sequence
297
+ _tmp = apply(:_embed_segs)
298
+ s = @result
299
+ unless _tmp
300
+ self.pos = _save
301
+ break
302
+ end
303
+ @result = begin; @text = s ; end
304
+ _tmp = true
305
+ unless _tmp
306
+ self.pos = _save
307
+ end
308
+ break
309
+ end # end sequence
310
+
311
+ set_failed_rule :_embed unless _tmp
312
+ return _tmp
313
+ end
314
+
315
+ Rules = {}
316
+ Rules[:_segment] = rule_info("segment", "(< /[\\w ]+/ > { text } | \"\\\\\" { \"\\\\\\\\\" } | \"\\n\" { \"\\\\n\" } | \"\\t\" { \"\\\\t\" } | \"\\b\" { \"\\\\b\" } | \"\\\"\" { \"\\\\\\\"\" } | < . > { text })")
317
+ Rules[:_segments] = rule_info("segments", "(segment:s segments:r { \"\#{s}\#{r}\" } | segment)")
318
+ Rules[:_root] = rule_info("root", "segments:s { @text = s }")
319
+ Rules[:_embed_seg] = rule_info("embed_seg", "(\"\#\" { \"\\\\\#\" } | segment)")
320
+ Rules[:_embed_segs] = rule_info("embed_segs", "(embed_seg:s embed_segs:r { \"\#{s}\#{r}\" } | embed_seg)")
321
+ Rules[:_embed] = rule_info("embed", "embed_segs:s { @text = s }")
322
+ end
@@ -0,0 +1,3 @@
1
+ module KPeg
2
+ VERSION = "0.7"
3
+ end
@@ -0,0 +1,112 @@
1
+ require 'kpeg'
2
+ require 'kpeg/format_parser'
3
+ require 'kpeg/grammar_renderer'
4
+ require 'kpeg/code_generator'
5
+ require 'stringio'
6
+ require 'test/unit'
7
+
8
+ class TestKPegRoundtrip < Test::Unit::TestCase
9
+ PATH = File.expand_path("../../lib/kpeg/format.kpeg", __FILE__)
10
+ def test_roundtrip
11
+ data = File.read(PATH)
12
+
13
+ pr = KPeg::FormatParser.new data
14
+ assert pr.parse, "Couldn't parse with builtin parser"
15
+
16
+ io = StringIO.new
17
+ gr = KPeg::GrammarRenderer.new(pr.g)
18
+ gr.render io
19
+
20
+ cg1 = KPeg::CodeGenerator.new("Test1", pr.g, false)
21
+ pr2 = cg1.make(io.string)
22
+ g2 = KPeg::Grammar.new
23
+ pr2.instance_variable_set(:@g, g2)
24
+
25
+ assert pr2.parse, "Couldn't parse with 2nd generation parser"
26
+
27
+ io2 = StringIO.new
28
+ gr2 = KPeg::GrammarRenderer.new(g2)
29
+ gr2.render io2
30
+
31
+ assert_equal io2.string, io.string
32
+
33
+ cg2 = KPeg::CodeGenerator.new("Test2", g2, false)
34
+ pr3 = cg2.make(io2.string)
35
+ g3 = KPeg::Grammar.new
36
+ pr3.instance_variable_set(:@g, g3)
37
+
38
+ assert pr3.parse, "Couldn't parse with 3rd generation parser"
39
+
40
+ io3 = StringIO.new
41
+ gr3 = KPeg::GrammarRenderer.new(g3)
42
+ gr3.render io3
43
+
44
+ assert_equal io3.string, io2.string
45
+
46
+ cg3 = KPeg::CodeGenerator.new("Test3", g3, false)
47
+ pr4 = cg3.make(io3.string)
48
+ g4 = KPeg::Grammar.new
49
+ pr4.instance_variable_set(:@g, g4)
50
+
51
+ assert pr4.parse, "Couldn't parse with 4th generation parser"
52
+
53
+ io4 = StringIO.new
54
+ gr4 = KPeg::GrammarRenderer.new(g4)
55
+ gr4.render io4
56
+
57
+ assert_equal io4.string, io3.string
58
+ end
59
+
60
+ def test_roundtrip_standalone
61
+ data = File.read(PATH)
62
+
63
+ pr = KPeg::FormatParser.new data
64
+ assert pr.parse, "Couldn't parse with builtin parser"
65
+
66
+ io = StringIO.new
67
+ gr = KPeg::GrammarRenderer.new(pr.g)
68
+ gr.render io
69
+
70
+ cg1 = KPeg::CodeGenerator.new("Test1", pr.g, false)
71
+ cg1.standalone = true
72
+ pr2 = cg1.make(io.string)
73
+ g2 = KPeg::Grammar.new
74
+ pr2.instance_variable_set(:@g, g2)
75
+
76
+ assert pr2.parse, "Couldn't parse with 2nd generation parser"
77
+
78
+ io2 = StringIO.new
79
+ gr2 = KPeg::GrammarRenderer.new(g2)
80
+ gr2.render io2
81
+
82
+ assert_equal io2.string, io.string
83
+
84
+ cg2 = KPeg::CodeGenerator.new("Test2", g2, false)
85
+ cg2.standalone = true
86
+ pr3 = cg2.make(io2.string)
87
+ g3 = KPeg::Grammar.new
88
+ pr3.instance_variable_set(:@g, g3)
89
+
90
+ assert pr3.parse, "Couldn't parse with 3rd generation parser"
91
+
92
+ io3 = StringIO.new
93
+ gr3 = KPeg::GrammarRenderer.new(g3)
94
+ gr3.render io3
95
+
96
+ assert_equal io3.string, io2.string
97
+
98
+ cg3 = KPeg::CodeGenerator.new("Test3", g3, false)
99
+ cg3.standalone = true
100
+ pr4 = cg3.make(io3.string)
101
+ g4 = KPeg::Grammar.new
102
+ pr4.instance_variable_set(:@g, g4)
103
+
104
+ assert pr4.parse, "Couldn't parse with 4th generation parser"
105
+
106
+ io4 = StringIO.new
107
+ gr4 = KPeg::GrammarRenderer.new(g4)
108
+ gr4.render io4
109
+
110
+ assert_equal io4.string, io3.string
111
+ end
112
+ end
@@ -0,0 +1,63 @@
1
+ require 'test/unit'
2
+ require 'kpeg'
3
+ require 'kpeg/format_parser'
4
+ require 'kpeg/code_generator'
5
+ require 'stringio'
6
+
7
+ class TestKPegCodeGenerator < Test::Unit::TestCase
8
+ GRAMMAR = <<-'STR'
9
+ Stmt = - Expr:e EOL { @answers << e }
10
+ | ( !EOL . )* EOL { puts "error" }
11
+
12
+ Expr = ID:i ASSIGN Sum:s { @vars[i] = s }
13
+ | Sum:s { s }
14
+
15
+ Sum = Product:l
16
+ ( PLUS Product:r { l += r }
17
+ | MINUS Product:r { l -= r }
18
+ )* { l }
19
+
20
+ Product = Value:l
21
+ ( TIMES Value:r { l *= r }
22
+ | DIVIDE Value:r { l /= r }
23
+ )* { l }
24
+
25
+ Value = NUMBER:i { i }
26
+ | ID:i !ASSIGN { @vars[i] }
27
+ | OPEN Expr:i CLOSE { i }
28
+
29
+ NUMBER = < [0-9]+ > - { text.to_i }
30
+ ID = < [a-z] > - { text }
31
+ ASSIGN = '=' -
32
+ PLUS = '+' -
33
+ MINUS = '-' -
34
+ TIMES = '*' -
35
+ DIVIDE = '/' -
36
+ OPEN = '(' -
37
+ CLOSE = ')' -
38
+
39
+ - = (' ' | '\t')*
40
+ EOL = ('\n' | '\r\n' | '\r' | ';') -
41
+
42
+ root = Stmt+
43
+ STR
44
+
45
+ def test_parse
46
+ parc = KPeg::FormatParser.new(GRAMMAR)
47
+ assert parc.parse, "Unable to parse"
48
+
49
+ gram = parc.grammar
50
+
51
+ # gr = KPeg::GrammarRenderer.new(gram)
52
+ # puts
53
+ # gr.render(STDOUT)
54
+
55
+ cg = KPeg::CodeGenerator.new "TestCalc", gram
56
+
57
+ code = cg.make("i = 3+4; j = i*8; i + j * 2;")
58
+ code.instance_variable_set(:@vars, {})
59
+ code.instance_variable_set(:@answers, [])
60
+ assert_equal true, code.parse
61
+ assert_equal [7,56,119], code.instance_variable_get(:@answers)
62
+ end
63
+ end