rubypeg 0.0.2

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,302 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.])
2
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
3
+ require 'rubypeg'
4
+ require 'textpeg'
5
+ require 'textpeg2rubypeg'
6
+
7
+ describe TextPeg2RubyPeg do
8
+
9
+ def check(input,output)
10
+ ruby = TextPeg2RubyPeg.new
11
+ peg = TextPeg.parse(input)
12
+ peg.visit(ruby)
13
+ ruby.to_ruby.should == output
14
+ end
15
+
16
+ it "creates a class that extends RubyPeg and is named after the first rule" do
17
+ input = <<END
18
+ one = .
19
+ END
20
+ output = <<END
21
+ require 'rubypeg'
22
+
23
+ class One < RubyPeg
24
+
25
+ def root
26
+ one
27
+ end
28
+
29
+ def one
30
+ any_character
31
+ end
32
+
33
+ end
34
+ END
35
+ check input, output
36
+ end
37
+
38
+ it "creates sequences" do
39
+ input = <<END
40
+ one = . . .
41
+ END
42
+ output = <<END
43
+ require 'rubypeg'
44
+
45
+ class One < RubyPeg
46
+
47
+ def root
48
+ one
49
+ end
50
+
51
+ def one
52
+ any_character && any_character && any_character
53
+ end
54
+
55
+ end
56
+ END
57
+ check input, output
58
+ end
59
+
60
+ it "creates alternatives" do
61
+ input = <<END
62
+ one = . | . | .
63
+ END
64
+ output = <<END
65
+ require 'rubypeg'
66
+
67
+ class One < RubyPeg
68
+
69
+ def root
70
+ one
71
+ end
72
+
73
+ def one
74
+ any_character || any_character || any_character
75
+ end
76
+
77
+ end
78
+ END
79
+ check input, output
80
+ end
81
+
82
+ it "creates alternatives and sequences together" do
83
+ input = <<END
84
+ one = (. .) | .
85
+ END
86
+ output = <<END
87
+ require 'rubypeg'
88
+
89
+ class One < RubyPeg
90
+
91
+ def root
92
+ one
93
+ end
94
+
95
+ def one
96
+ (any_character && any_character) || any_character
97
+ end
98
+
99
+ end
100
+ END
101
+ check input, output
102
+ end
103
+
104
+ it "creates nodes" do
105
+ input = <<END
106
+ one := . . .
107
+ END
108
+ output = <<END
109
+ require 'rubypeg'
110
+
111
+ class One < RubyPeg
112
+
113
+ def root
114
+ one
115
+ end
116
+
117
+ def one
118
+ node :one do
119
+ any_character && any_character && any_character
120
+ end
121
+ end
122
+
123
+ end
124
+ END
125
+ check input, output
126
+ end
127
+
128
+ it "creates positive and negative lookaheads and ignores" do
129
+ input = <<END
130
+ one = !. &. `.
131
+ END
132
+ output = <<END
133
+ require 'rubypeg'
134
+
135
+ class One < RubyPeg
136
+
137
+ def root
138
+ one
139
+ end
140
+
141
+ def one
142
+ not_followed_by { any_character } && followed_by { any_character } && ignore { any_character }
143
+ end
144
+
145
+ end
146
+ END
147
+ check input, output
148
+ end
149
+
150
+ it "creates repeated occurrence suffixes" do
151
+ input = <<END
152
+ one = .? .+ .*
153
+ END
154
+ output = <<END
155
+ require 'rubypeg'
156
+
157
+ class One < RubyPeg
158
+
159
+ def root
160
+ one
161
+ end
162
+
163
+ def one
164
+ optional { any_character } && one_or_more { any_character } && any_number_of { any_character }
165
+ end
166
+
167
+ end
168
+ END
169
+ check input, output
170
+ end
171
+
172
+ it "creates terminal strings" do
173
+ input = <<END
174
+ one = "one"
175
+ END
176
+ output = <<END
177
+ require 'rubypeg'
178
+
179
+ class One < RubyPeg
180
+
181
+ def root
182
+ one
183
+ end
184
+
185
+ def one
186
+ terminal("one")
187
+ end
188
+
189
+ end
190
+ END
191
+ check input, output
192
+ end
193
+
194
+ it "creates terminal strings, escaping where relevant" do
195
+ input = <<END
196
+ one = '"'
197
+ END
198
+ output = <<END
199
+ require 'rubypeg'
200
+
201
+ class One < RubyPeg
202
+
203
+ def root
204
+ one
205
+ end
206
+
207
+ def one
208
+ terminal("\\"")
209
+ end
210
+
211
+ end
212
+ END
213
+ check input, output
214
+ end
215
+
216
+ it "creates terminal character ranges" do
217
+ input = <<END
218
+ one = [a-z]
219
+ END
220
+ output = <<END
221
+ require 'rubypeg'
222
+
223
+ class One < RubyPeg
224
+
225
+ def root
226
+ one
227
+ end
228
+
229
+ def one
230
+ terminal(/[a-z]/)
231
+ end
232
+
233
+ end
234
+ END
235
+ check input, output
236
+ end
237
+
238
+ it "creates terminal regular expressions" do
239
+ input = <<END
240
+ one = /one/
241
+ END
242
+ output = <<END
243
+ require 'rubypeg'
244
+
245
+ class One < RubyPeg
246
+
247
+ def root
248
+ one
249
+ end
250
+
251
+ def one
252
+ terminal(/one/)
253
+ end
254
+
255
+ end
256
+ END
257
+ check input, output
258
+ end
259
+
260
+ it "has a helper class method parse_to_ruby(text_peg) that does the parsing and compiling in one shot" do
261
+ input = <<END
262
+ one = /one/
263
+ END
264
+ output = <<END
265
+ require 'rubypeg'
266
+
267
+ class One < RubyPeg
268
+
269
+ def root
270
+ one
271
+ end
272
+
273
+ def one
274
+ terminal(/one/)
275
+ end
276
+
277
+ end
278
+ END
279
+ TextPeg2RubyPeg.parse_to_ruby(input).should == output
280
+ end
281
+
282
+ it "has a helper class method parse_to_loaded_class(text_peg) that parses the text peg, compiles it to ruby and then evaluates it so it is immediately available" do
283
+ parser = TextPeg2RubyPeg.parse_to_loaded_class("one := /one/")
284
+ parser.parse("one").to_ast.should == [:one,"one"]
285
+ end
286
+
287
+ it "has a helper class method parse_file_to_loaded_class(filename) that loads a text peg then parses and compiles it to ruby before evaluating it so that it is immediately available" do
288
+ parser = TextPeg2RubyPeg.parse_file_to_loaded_class(File.join(File.dirname(__FILE__),'../lib/textpeg.txt'))
289
+ parser.parse("one := /one/").to_ast.should == [:text_peg, [:node, [:identifier, "one"], [:sequence, [:terminal_regexp, "one"]]]]
290
+ end
291
+
292
+ it "parses its own grammar" do
293
+ input = IO.readlines(File.join(File.dirname(__FILE__),'../lib/textpeg.txt')).join
294
+ output = IO.readlines(File.join(File.dirname(__FILE__),'../lib/textpeg.rb')).join
295
+ ruby = TextPeg2RubyPeg.new
296
+ peg = TextPeg.parse(input)
297
+ peg.visit(ruby)
298
+ r = ruby.to_ruby
299
+ r.should == output
300
+ end
301
+
302
+ end
@@ -0,0 +1,123 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.])
2
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
3
+ require 'rubypeg'
4
+ require 'textpeg'
5
+
6
+ describe TextPeg do
7
+
8
+ it "parses rules, one per line" do
9
+ input = <<END
10
+ one = .
11
+ two = .
12
+ END
13
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:any_character]]],[:definition,[:identifier,"two"],[:sequence,[:any_character]]]]
14
+ end
15
+
16
+ it "assigns nodes, one per line" do
17
+ input = <<END
18
+ one := .
19
+ two := .
20
+ END
21
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:node,[:identifier,"one"],[:sequence,[:any_character]]],[:node,[:identifier,"two"],[:sequence,[:any_character]]]]
22
+ end
23
+
24
+ it "parses terminal strings in double quotes" do
25
+ input = <<END
26
+ one = "terminal string"
27
+ END
28
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:terminal_string,"terminal string"]]]]
29
+ end
30
+
31
+ it "parses terminal strings in single quotes" do
32
+ input = <<END
33
+ one = 'terminal string'
34
+ END
35
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:terminal_string,"terminal string"]]]]
36
+ end
37
+
38
+ it "parses terminal character matches" do
39
+ input = <<END
40
+ one = [a-z]
41
+ END
42
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:terminal_character_range,"[a-z]"]]]]
43
+ end
44
+
45
+ it "parses terminal regular expression matches" do
46
+ input = <<END
47
+ one = /one/
48
+ END
49
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:terminal_regexp,"one"]]]]
50
+ end
51
+
52
+ it "parses terminal regular expression matches with tricky inners" do
53
+ input = <<END
54
+ one = /\\/one\\/two\\/three/
55
+ END
56
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:terminal_regexp,"\\/one\\/two\\/three"]]]]
57
+ end
58
+
59
+ it "parses any character matches" do
60
+ input = <<END
61
+ one = .
62
+ END
63
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:any_character]]]]
64
+ end
65
+
66
+ it "parses alternatives" do
67
+ input = <<END
68
+ one = "one" | "two" | "three"
69
+ END
70
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:alternatives,[:terminal_string,"one"],[:terminal_string,"two"],[:terminal_string,"three"]]]]
71
+ end
72
+
73
+ it "parses sequences" do
74
+ input = <<END
75
+ one = "one" "two" "three"
76
+ END
77
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:terminal_string,"one"],[:terminal_string,"two"],[:terminal_string,"three"]]]]
78
+
79
+ end
80
+
81
+ it "parses alternatives in sequences" do
82
+ input = <<END
83
+ one = ("one"|"1") "two" ( "three" | "3" )
84
+ END
85
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:bracketed_expression, [:alternatives,[:terminal_string,"one"],[:terminal_string,'1']]],[:terminal_string,"two"],[:bracketed_expression,[:alternatives,[:terminal_string,"three"],[:terminal_string,'3']]]]]]
86
+
87
+ end
88
+
89
+ it "parses sequences in alternatives" do
90
+ input = <<END
91
+ one = ( "one" "two" "three" ) | ("1" "2" "3")
92
+ END
93
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:alternatives,[:bracketed_expression,[:sequence,[:terminal_string,"one"],[:terminal_string,"two"],[:terminal_string,"three"]]],[:bracketed_expression,[:sequence,[:terminal_string,'1'],[:terminal_string,'2'],[:terminal_string,'3']]]]]]
94
+ end
95
+
96
+ it "parses suffix elements" do
97
+ input = <<END
98
+ one = "one"? "two"* "three"+ ("four" | "five")?
99
+ END
100
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:optional,[:terminal_string,"one"]],[:any_number_of,[:terminal_string,"two"]],[:one_or_more,[:terminal_string,"three"]],[:optional,[:bracketed_expression,[:alternatives,[:terminal_string,"four"],[:terminal_string,"five"]]]]]]]
101
+ end
102
+
103
+ it "parses lookaheads" do
104
+ input = <<END
105
+ one = !"one" &"two"
106
+ END
107
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:not_followed_by,[:terminal_string,"one"]],[:followed_by,[:terminal_string,"two"]]]]]
108
+ end
109
+
110
+
111
+ it "parses ignores" do
112
+ input = <<END
113
+ one = `"one" &"two"
114
+ END
115
+ TextPeg.parse(input).to_ast.should == [:text_peg,[:definition,[:identifier,"one"],[:sequence,[:ignored,[:terminal_string,"one"]],[:followed_by,[:terminal_string,"two"]]]]]
116
+ end
117
+
118
+ it "parses its own grammar" do
119
+ input = IO.readlines(File.join(File.dirname(__FILE__),'../lib/textpeg.txt')).join
120
+ o = TextPeg.parse(input)
121
+ o.should_not == nil
122
+ end
123
+ end
@@ -0,0 +1,67 @@
1
+ $:.unshift File.join(File.dirname(__FILE__), *%w[.. lib])
2
+ require 'rubypeg'
3
+
4
+ class SimplePeg < RubyPeg
5
+ def root
6
+ node :root do
7
+ one && two && three
8
+ end
9
+ end
10
+
11
+ def one
12
+ terminal('one')
13
+ end
14
+
15
+ def two
16
+ node :two do
17
+ terminal('2') || terminal('two')
18
+ end
19
+ end
20
+
21
+ def three
22
+ node :three do
23
+ one_or_more { terminal('x') }
24
+ end
25
+ end
26
+ end
27
+
28
+ describe SimplePeg do
29
+
30
+ it "matches one2xxx" do
31
+ SimplePeg.parse("one2xxx").to_ast.should == [:root,'one',[:two,'2'],[:three,'x','x','x']]
32
+ end
33
+ end
34
+
35
+ class EmptyPegBuilder
36
+
37
+ end
38
+
39
+ describe EmptyPegBuilder do
40
+ it "demonstrates the way that terminals are reduced to strings" do
41
+ SimplePeg.parse("one2xxx").visit(EmptyPegBuilder.new).should == ['one','2',['x','x','x']]
42
+ end
43
+ end
44
+
45
+
46
+ class NonTerminalPegBuilder
47
+
48
+ def root(one,two,three)
49
+ "one:#{one},two:#{two.visit(self)},three:#{three.visit(self)}"
50
+ end
51
+
52
+ def two(number)
53
+ number.visit(self).to_i + 1
54
+ end
55
+
56
+ def three(*args)
57
+ args.size
58
+ end
59
+
60
+ end
61
+
62
+ describe EmptyPegBuilder do
63
+ it "demonstrates the way that non terminals optionally call methods on the builder to be converted" do
64
+ SimplePeg.parse("one2xxx").visit(NonTerminalPegBuilder.new).should == "one:one,two:3,three:3"
65
+ end
66
+ end
67
+
metadata ADDED
@@ -0,0 +1,95 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rubypeg
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 2
9
+ version: 0.0.2
10
+ platform: ruby
11
+ authors:
12
+ - Thomas Counsell, Green on Black Ltd
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2010-04-26 00:00:00 +01:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: rubyscriptwriter
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 0
29
+ version: "0"
30
+ type: :runtime
31
+ version_requirements: *id001
32
+ description:
33
+ email: ruby-peg@greenonblack.com
34
+ executables:
35
+ - text-peg2ruby-peg
36
+ extensions: []
37
+
38
+ extra_rdoc_files: []
39
+
40
+ files:
41
+ - README
42
+ - spec/any_character_spec.rb
43
+ - spec/lookahead_spec.rb
44
+ - spec/non_terminal_spec.rb
45
+ - spec/peg_leg_spec.rb
46
+ - spec/repetition_spec.rb
47
+ - spec/sequence_spec.rb
48
+ - spec/terminal_spec.rb
49
+ - spec/text_peg2ruby_peg_spec.rb
50
+ - spec/text_peg_spec.rb
51
+ - spec/visit_spec.rb
52
+ - lib/rubypeg.rb
53
+ - lib/textpeg.rb
54
+ - lib/textpeg.txt
55
+ - lib/textpeg2rubypeg.rb
56
+ - bin/text-peg2ruby-peg
57
+ - examples/arithmetic/arithmetic_peg.rb
58
+ - examples/arithmetic/arithmetic_peg.txt
59
+ - examples/arithmetic/arithmetic_peg_spec.rb
60
+ - examples/arithmetic/calculator.rb
61
+ - examples/arithmetic/calculator_spec.rb
62
+ - examples/excel/excel_peg.txt
63
+ - examples/excel/excel_peg_spec.rb
64
+ has_rdoc: true
65
+ homepage: http://wiki.github.com/tamc/rubypeg/
66
+ licenses: []
67
+
68
+ post_install_message:
69
+ rdoc_options: []
70
+
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ segments:
78
+ - 0
79
+ version: "0"
80
+ required_rubygems_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ requirements: []
88
+
89
+ rubyforge_project:
90
+ rubygems_version: 1.3.6
91
+ signing_key:
92
+ specification_version: 3
93
+ summary: RubyPeg helps you to create readable Parsing Expression Grammars (PEG) in, err, ruby
94
+ test_files: []
95
+