grammar 0.5 → 0.8

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.
@@ -1,163 +0,0 @@
1
- #!/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'cursor/io'
5
- require 'cursor/indexed'
6
- require 'grammar'
7
- require 'duck'
8
- require 'set'
9
-
10
- class Tcl
11
-
12
- def initialize
13
-
14
- @variables = {}
15
- @procs = {}
16
-
17
- space = Grammar::Element[Set[?\ ,?\t].duck!(:==,:include?)].discard
18
- newline = Grammar::Element[?\n]
19
- command_separator = newline|Grammar::Element[?;]
20
- hex = Grammar::Element[(
21
- Set[]+(?0..?9)+(?a..?f)+(?A..?F)
22
- ).duck!(:==,:include?)]
23
- octal = Grammar::Element[(?0..?7).duck!(:==,:===)]
24
- alphanum = Grammar::Element[(
25
- Set[?_]+(?0..?9)+(?a..?z)+(?A..?Z)
26
- ).duck!(:==,:include?)]
27
-
28
- backslashed = Grammar::Element[?\\].discard+(
29
- Grammar::Element[?a].filter { "\a" } |
30
- Grammar::Element[?b].filter { "\b" } |
31
- Grammar::Element[?f].filter { "\f" } |
32
- Grammar::Element[?n].filter { "\n" } |
33
- Grammar::Element[?r].filter { "\r" } |
34
- Grammar::Element[?t].filter { "\t" } |
35
- Grammar::Element[?v].filter { "\v" } |
36
- Grammar::Element[?x].discard+hex.list1.filter { |n|
37
- eval(%Q("\\x#{n}"))
38
- } |
39
- Grammar::Element[?u].discard+hex.list1 { |n| # don't know what to do with unicode
40
- eval(%Q("\\x#{n}"))
41
- } |
42
- octal.list1.filter { |n|
43
- eval(%Q("\\#{n}"))
44
- } |
45
- (newline.discard+space.list0).filter { " " } |
46
- Grammar::ANY
47
- )
48
-
49
- braced_element = Grammar.new { |braced_element|
50
- Grammar::Element[?\{]+braced_element.list0(Grammar::Element[?\}]) |
51
- Grammar::Element[?\\].discard+(
52
- (newline.discard+space.list0).filter { " " } |
53
- Grammar::NULL.filter { "\\" }
54
- ) |
55
- newline |
56
- Grammar::ANY
57
- }
58
- braced = Grammar::Element[?\{].discard+braced_element.list0(Grammar::Element[?\}].discard)
59
-
60
- element = Grammar.new
61
-
62
- varname = (
63
- alphanum |
64
- Grammar::Element[?\:]*(2..+1.0/0)
65
- ).list1
66
- index = Grammar::Element[?\(]+element.list1(Grammar::Element[?\)])
67
- variable = (Grammar::Element[?\$].discard + (
68
- varname.group(String) + index.group(String).optional |
69
- braced.group(String)
70
- )).filter { |var| @variables[var.to_s.to_sym].to_s }
71
-
72
- quoted = Grammar::Element[?\"].discard+element.list1(Grammar::Element[?\"].discard)
73
- comment = (Grammar::Element[?\#]+Grammar::ANY.list0(newline)).discard
74
-
75
- commander = lambda { |terminator|
76
- word_terminator = space.list1|+command_separator|+terminator
77
- word = ((braced|quoted)+word_terminator|element.list1(word_terminator)).
78
- group(String).filter {|x,t| t.concat(x)}
79
- command = space.list0 + (
80
- comment |
81
- word.list0(command_separator.discard|+terminator).
82
- filter(Array) { |com,ret|
83
- com.empty? ? ret : ret.replace(send(*com).to_s)
84
- }
85
- )
86
- command.list0(terminator.discard)
87
- }
88
-
89
- bracketed = Grammar::Element[?[].discard+commander[Grammar::Element[?]]]
90
-
91
- @interpreter = commander[Grammar::EOF]
92
-
93
- element << (backslashed | bracketed | variable | newline | Grammar::ANY)
94
-
95
- end
96
-
97
- def interpret(cursor)
98
- @interpreter.scan(cursor,"",false)
99
- end
100
-
101
- def method_missing(name,*args)
102
- vars,body = *@procs[name]
103
- return "<#{name}#{args.inspect}>" if !body
104
- variables = @variables
105
- @variables = {}
106
- vars.zip(args).each { |var,val| @variables[var.to_sym] = val }
107
- ret = interpret(body.to_cursor)
108
- @variables = variables
109
- ret
110
- end
111
-
112
- def proc(name,args,body)
113
- @procs[name.to_sym] = [args,body]
114
- ""
115
- end
116
-
117
- def set(name,value)
118
- @variables[name.to_sym] = value
119
- end
120
-
121
- def if(condition,body)
122
- # should really use expr to get condition
123
- unless %w(0 false no off).include?(condition.to_s)
124
- interpret(body.to_cursor)
125
- end
126
- # need to handle elsif and else
127
- ""
128
- end
129
-
130
- def sum(*values)
131
- values.inject(0) { |sum, v| sum + eval(v) }
132
- end
133
-
134
- def product(*values)
135
- values.inject(1) { |sum, v| sum * eval(v) }
136
- end
137
-
138
- def subtract(a,b)
139
- eval(a)-eval(b)
140
- end
141
-
142
- def divide(a,b)
143
- eval(a)/eval(b)
144
- end
145
-
146
- def puts(str)
147
- $stdout.print(str,"\n")
148
- ""
149
- end
150
-
151
- def concat(*args)
152
- args.inject("") { |concatenated, arg| concatenated.concat(arg) }
153
- end
154
-
155
- end
156
-
157
- if $0==__FILE__
158
- result = Tcl.new.interpret($stdin.to_cursor)
159
- p result
160
- result
161
- end
162
-
163
-
@@ -1,4 +0,0 @@
1
- "one\n" *
2
- (2+3.0 /4e0*(5E+0+6.0e-0)-07)+
3
- (" eight\t"*nine)
4
-
@@ -1,274 +0,0 @@
1
- #!/bin/env ruby
2
-
3
- require 'rubygems'
4
- require 'test/unit'
5
- require 'test/unit/collector'
6
- require 'cursor/indexed'
7
- require 'grammar'
8
-
9
- module Test
10
- module Unit
11
- class AutoRunner
12
- alias_method(:_options_,:options)
13
- def options
14
- @options = _options_
15
- @options.on('-i', '--iterations=NUMBER', Float,
16
- "Randomly run tests for a number of iterations.") do |iterations|
17
- $random_iterations = iterations
18
- end
19
- @options.on('-s', '--seed=NUMBER', Integer,
20
- "Random seed.") do |seed|
21
- $random_seed = seed.nonzero?
22
- end
23
- @options
24
- end
25
- alias_method(:_run_,:run)
26
- def run
27
- $output_level = @output_level
28
- $random_seed ||= (srand;srand)
29
- srand($random_seed)
30
- _run_
31
- end
32
- end
33
- module Collector
34
- alias_method(:_add_suite_,:add_suite)
35
- def add_suite(destination, suite)
36
- _add_suite_(destination, suite)
37
- if $random_iterations
38
- (class << suite.tests;self;end).class_eval {
39
- def each
40
- n = size
41
- ($random_iterations*n).to_i.times {
42
- yield(slice(rand(n)))
43
- }
44
- end
45
- }
46
- end
47
- destination
48
- end
49
- end
50
- class TestSuite
51
- def run(result, &progress_block)
52
- yield(STARTED, name)
53
- catch(:stop_suite) {
54
- @tests.each { |test|
55
- catch(:invalid_test) {
56
- test.run(result, &progress_block)
57
- }
58
- }
59
- }
60
- yield(FINISHED, name)
61
- end
62
- end
63
- class RandomTestCase < TestCase
64
- def self.suite
65
- suite = super
66
- puts("random_seed: #{$random_seed}") if !suite.tests.empty? and $output_level>=UI::NORMAL
67
- suite
68
- end
69
- undef_method(:default_test) # so that RandomTestCase is empty
70
- def teardown
71
- if not passed?
72
- puts("\nrandom_seed: #{$random_seed}")
73
- throw(:stop_suite)
74
- end
75
- end
76
- end
77
- end
78
- end
79
-
80
-
81
- class Grammar
82
-
83
- class Test < ::Test::Unit::RandomTestCase
84
-
85
- class Grammars
86
- include ::Test::Unit::Assertions
87
- def initialize
88
- @grammar = []
89
- @match = []
90
- @parsed = []
91
- @mismatch = []
92
- @partial_match = []
93
- end
94
- def get
95
- i = rand(@grammar.size.nonzero? || throw(:invalid_test))
96
- return @grammar[i],@match[i],@parsed[i],@mismatch[i],@partial_match[i]
97
- end
98
- def add(grammar,match,parsed,mismatch=nil,partial_match=nil)
99
- puts("#{grammar.inspect} #{match.inspect} #{parsed.inspect} #{mismatch.inspect} #{partial_match.inspect}") if
100
- $output_level>=::Test::Unit::UI::VERBOSE
101
- match.size.times { |i|
102
- assert_equal(parsed[i],grammar.scan(match[i].to_cursor))
103
- }
104
- if mismatch
105
- assert_raise(Grammar::Error){p grammar.scan(mismatch.to_cursor)}
106
- assert_equal(false,grammar.scan(mismatch.to_cursor,[],true))
107
- end
108
- if partial_match
109
- assert_raise(Grammar::Error){grammar.scan(partial_match.to_cursor)}
110
- end
111
- @grammar << grammar
112
- @match << match
113
- @parsed << parsed
114
- @mismatch << mismatch
115
- @partial_match << partial_match
116
- nil
117
- end
118
- end
119
-
120
- def self.suite
121
- suite = super
122
- self.plant
123
- suite
124
- end
125
-
126
- def self.plant
127
- @@grammars = Grammars.new
128
- end
129
-
130
- def test_Sequence
131
- partial = rand(2)==1
132
- value = ["a","bc"][rand(2)]
133
- match = value.dup
134
- if partial
135
- match = [match,match[0,1+rand(value.size)]]
136
- else
137
- match = [match]
138
- end
139
- parsed = match.map{|s|s.unpack("C*")}
140
- @@grammars.add(Grammar::Sequence.new(value,partial),match,parsed,"")
141
- end
142
-
143
- def test_Element
144
- value = [?a,?b][rand(2)]
145
- match = ["" << value]
146
- parsed = [[value]]
147
- @@grammars.add(Grammar::Element.new(value),match,parsed,"")
148
- end
149
-
150
- def test_NULL
151
- @@grammars.add(Grammar::NULL,[""],[[]])
152
- end
153
-
154
- def test_or
155
- grammar1,match1,parsed1,mismatch1,partial1 = @@grammars.get
156
- grammar2,match2,parsed2,mismatch2,partial2 = @@grammars.get
157
- i = rand(match1.size)
158
- match1 = match1[i]
159
- parsed1 = parsed1[i]
160
- i = rand(match2.size)
161
- match2 = match2[i]
162
- parsed2 = parsed2[i]
163
- begin
164
- # match2 shouldn't match grammar1
165
- grammar1.scan(match2.to_cursor,[],true) and throw(:invalid_test)
166
- rescue Grammar::Error
167
- throw(:invalid_test) # partial match
168
- end
169
- @@grammars.add(
170
- grammar1|grammar2,
171
- [match1,match2],
172
- [parsed1,parsed2],
173
- mismatch1==mismatch2 ? mismatch1 : nil,
174
- partial1==partial2 ? partial1 : nil
175
- )
176
- end
177
-
178
- def test_plus
179
- grammar1,match1,parsed1,mismatch1,partial1 = @@grammars.get
180
- grammar2,match2,parsed2,mismatch2,partial2 = @@grammars.get
181
- i = rand(match1.size)
182
- match1 = match1[i]
183
- parsed1 = parsed1[i]
184
- i = rand(match2.size)
185
- match2 = match2[i]
186
- parsed2 = parsed2[i]
187
- # grammar1 shouldn't eat into match2
188
- begin
189
- grammar1.scan((match1+match2).to_cursor)==parsed1 or
190
- throw(:invalid_test)
191
- rescue Grammar::Error
192
- throw(:invalid_test)
193
- end
194
- @@grammars.add(
195
- grammar1+grammar2,
196
- [match1+match2],
197
- [parsed1+parsed2],
198
- mismatch1,
199
- partial1 || (mismatch2 && match1+mismatch2)
200
- )
201
- end
202
-
203
- def test_Grammar
204
- grammar1,match1,parsed1,mismatch1,partial1 = @@grammars.get
205
- grammar2,match2,parsed2,mismatch2,partial2 = @@grammars.get
206
- i = rand(match1.size)
207
- match1 = match1[i]
208
- parsed1 = parsed1[i]
209
- i = rand(match2.size)
210
- match2 = match2[i]
211
- parsed2 = parsed2[i]
212
- !match1.empty? or throw(:invalid_test)
213
- begin
214
- (grammar1.scan((match1+match1).to_cursor)==parsed1 and
215
- grammar1.scan((match1+match2).to_cursor)==parsed1 and
216
- grammar2.scan((match2+match2).to_cursor)==parsed2) or
217
- throw(:invalid_test)
218
- grammar1.scan(match2.to_cursor,[],true) and throw(:invalid_test)
219
- rescue Grammar::Error
220
- throw(:invalid_test)
221
- end
222
- grammar = Grammar.new
223
- grammar << grammar1+(grammar|Grammar::NULL)+grammar2
224
- @@grammars.add(
225
- grammar,
226
- [match1+match2,match1+match1+match1+match2+match2+match2],
227
- [parsed1+parsed2,parsed1+parsed1+parsed1+parsed2+parsed2+parsed2],
228
- mismatch1,
229
- partial1
230
- )
231
- end
232
-
233
- def test_times
234
- grammar1,match1,parsed1,mismatch1,partial1 = @@grammars.get
235
- begin
236
- grammar1.scan("".to_cursor,[],true) and throw(:invalid_test)
237
- rescue Grammar::Error
238
- throw(:invalid_test)
239
- end
240
- min = rand(2)
241
- diff = rand(4)
242
- match = ""
243
- parsed = []
244
- match0 = nil
245
- parsed0 = nil
246
- (min+rand(diff+1)).times {
247
- i = rand(match1.size)
248
- match.concat(match1[i])
249
- parsed.concat(parsed1[i])
250
- if match0
251
- begin
252
- grammar1.scan((match0+match1[i]).to_cursor)==parsed0 or
253
- throw(:invalid_test)
254
- rescue Grammar::Error
255
- throw(:invalid_test)
256
- end
257
- end
258
- match0 = match1[i]
259
- parsed0 = parsed1[i]
260
- }
261
- diff = 1.0/0.0 if diff==3
262
- multiplier = (diff.zero? && rand(2).zero?) ? min : (min..(min+diff))
263
- @@grammars.add(
264
- grammar1*multiplier,
265
- [match],
266
- [parsed],
267
- min.zero? ? nil : mismatch1,
268
- min.zero? ? nil : (partial1 || (min>1 && match1[rand(match1.size)]))
269
- )
270
- end
271
-
272
- end
273
- end
274
-