tenderlove-frex 1.0.1.20090313144615

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,73 @@
1
+ Rex README
2
+ ===========
3
+
4
+ Rex �� Ruby �Τ���Υ�����ʥ����ͥ졼���Ǥ���
5
+ lex �� Ruby �Ǥ��������ޤ���
6
+ Racc �ȤȤ�˻Ȥ��褦���߷פ���Ƥ��ޤ���
7
+
8
+
9
+ ɬ�״Ķ�
10
+ --------
11
+
12
+ * ruby 1.8 �ʹ�
13
+
14
+
15
+ ���󥹥ȡ���
16
+ ------------
17
+
18
+ �ѥå������Υȥåץǥ��쥯�ȥ�Ǽ��Τ褦�����Ϥ��Ƥ���������
19
+ ($ ���̾�桼����# �ϥ롼�ȤΥץ���ץȤǤ�)
20
+
21
+ $ ruby setup.rb config
22
+ $ ruby setup.rb setup
23
+ ($ su)
24
+ # ruby setup.rb install
25
+
26
+ ������̾�Υѥ��� Racc �����󥹥ȡ��뤵��ޤ�����ʬ�ι���
27
+ �ʥǥ��쥯�ȥ�˥��󥹥ȡ��뤷�����Ȥ��ϡ�setup.rb config ��
28
+ �Ƽ索�ץ�����Ĥ��Ƽ¹Ԥ��Ƥ������������ץ����Υꥹ�Ȥ�
29
+
30
+ $ ruby setup.rb --help
31
+
32
+ �Ǹ����ޤ���
33
+
34
+
35
+ �ƥ���
36
+ ------
37
+
38
+ sample/ �ʲ��ˤ����Ĥ� Rex ��ʸˡ�ե�����Υ���ץ뤬�Ѱ�
39
+ ���Ƥ���ޤ����ʲ���¹Ԥ��Ƥ���������
40
+
41
+ $ rex sample1.rex --stub
42
+ $ ruby sample1.rex.rb sample1.c
43
+
44
+ $ rex sample2.rex --stub
45
+ $ ruby sample2.rex.rb sample2.bas
46
+
47
+ $ racc calc3.racc
48
+ $ rex calc3.rex
49
+ $ ruby calc3.tab.rb
50
+
51
+ Rex �ξܤ���ʸˡ�� doc/ �ǥ��쥯�ȥ�ʲ��򸫤Ƥ���������
52
+ �ޤ�������� sample/ �ǥ��쥯�ȥ�ʲ��򸫤Ƥ���������
53
+
54
+
55
+ �饤����
56
+ ----------
57
+
58
+ �饤���󥹤� GNU Lesser General Public License (LGPL) version 2
59
+ �Ǥ����������桼�����񤤤���§�ե�����䡢Racc ������������������
60
+ Ruby ������ץȤϤ����оݳ��Ǥ��������ʥ饤���󥹤����ۤ��Ƥ���������
61
+
62
+
63
+ �Х��ʤ�
64
+ --------
65
+
66
+ Rex ��ȤäƤ��ƥХ��餷�����ݤ����������顢�����Υ��ɥ쥹�ޤ�
67
+ �᡼��򤯤�������
68
+ ���ΤȤ��ϤǤ�������Х���Ƹ��Ǥ���ʸˡ�ե�������դ��Ƥ���������
69
+
70
+
71
+ ARIMA Yasuhiro
72
+ arima.yasuhiro@nifty.com
73
+ http://raa.ruby-lang.org/project/rex/
@@ -0,0 +1,39 @@
1
+ = Frex
2
+
3
+ * http://github.com/aaronp/frex/tree/master
4
+
5
+ == DESCRIPTION
6
+
7
+ Frex is a fork of Rex.
8
+ Rex is a lexical scanner generator.
9
+ It is written in Ruby itself, and generates Ruby program.
10
+ It is designed for use with Racc.
11
+
12
+
13
+ == SYNOPSIS
14
+
15
+ $ frex sample1.rex --stub
16
+ $ ruby sample1.rex.rb sample1.c
17
+
18
+ $ frex sample2.rex --stub
19
+ $ ruby sample2.rex.rb sample2.bas
20
+
21
+ $ racc calc3.racc
22
+ $ frex calc3.rex
23
+ $ ruby calc3.tab.rb
24
+
25
+ == REQUIREMENTS
26
+
27
+ * ruby version 1.8.x or later.
28
+
29
+
30
+ == INSTALL
31
+
32
+ * sudo gem install aaronp-frex --source=http://gems.github.com
33
+
34
+ == LICENSE
35
+
36
+ Rex is distributed under the terms of the GNU Lesser General
37
+ Public License version 2. Note that you do NOT need to follow
38
+ LGPL for your own parser (Rex outputs). You can provide those
39
+ files under any licenses you want.
@@ -0,0 +1,27 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
7
+ require 'frex'
8
+
9
+ HOE = Hoe.new('frex', Frex::VERSION) do |p|
10
+ p.readme_file = 'README.rdoc'
11
+ p.history_file = 'CHANGELOG.rdoc'
12
+ p.developer('Aaron Patterson', 'aaronp@rubyforge.org')
13
+ p.extra_rdoc_files = FileList['*.rdoc']
14
+ end
15
+
16
+ namespace :gem do
17
+ namespace :spec do
18
+ task :dev do
19
+ File.open("#{HOE.name}.gemspec", 'w') do |f|
20
+ HOE.spec.version = "#{HOE.version}.#{Time.now.strftime("%Y%m%d%H%M%S")}"
21
+ f.write(HOE.spec.to_ruby)
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ # vim: syntax=Ruby
@@ -0,0 +1,18 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # rex
4
+ #
5
+ # Copyright (c) 2005-2006 ARIMA Yasuhiro <arima.yasuhiro@nifty.com>
6
+ #
7
+ # This program is free software.
8
+ # You can distribute/modify this program under the terms of
9
+ # the GNU LGPL, Lesser General Public License version 2.1.
10
+ # For details of LGPL, see the file "COPYING".
11
+ #
12
+
13
+ ## ---------------------------------------------------------------------
14
+
15
+ require 'rubygems'
16
+ require 'frex'
17
+
18
+ Frex::Cmd.new.run
@@ -0,0 +1,37 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{frex}
5
+ s.version = "1.0.1.20090313144615"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Aaron Patterson"]
9
+ s.date = %q{2009-03-13}
10
+ s.default_executable = %q{frex}
11
+ s.description = %q{Frex is a fork of Rex. Rex is a lexical scanner generator. It is written in Ruby itself, and generates Ruby program. It is designed for use with Racc.}
12
+ s.email = ["aaronp@rubyforge.org"]
13
+ s.executables = ["frex"]
14
+ s.extra_rdoc_files = ["Manifest.txt", "CHANGELOG.rdoc", "DOCUMENTATION.en.rdoc", "DOCUMENTATION.ja.rdoc", "README.rdoc"]
15
+ s.files = ["CHANGELOG.rdoc", "DOCUMENTATION.en.rdoc", "DOCUMENTATION.ja.rdoc", "Manifest.txt", "README.ja", "README.rdoc", "Rakefile", "bin/frex", "frex.gemspec", "lib/frex.rb", "lib/frex/generator.rb", "lib/frex/info.rb", "lib/frex/rexcmd.rb", "sample/a.cmd", "sample/b.cmd", "sample/c.cmd", "sample/calc3.racc", "sample/calc3.rex", "sample/calc3.rex.rb", "sample/calc3.tab.rb", "sample/error1.rex", "sample/error2.rex", "sample/sample.html", "sample/sample.rex", "sample/sample.rex.rb", "sample/sample.xhtml", "sample/sample1.c", "sample/sample1.rex", "sample/sample2.bas", "sample/sample2.rex", "sample/simple.html", "sample/simple.xhtml", "sample/xhtmlparser.racc", "sample/xhtmlparser.rex", "test/assets/test.rex", "test/rex-20060125.rb", "test/rex-20060511.rb", "test/test_generator.rb"]
16
+ s.has_rdoc = true
17
+ s.homepage = %q{http://github.com/aaronp/frex/tree/master}
18
+ s.rdoc_options = ["--main", "README.rdoc"]
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{frex}
21
+ s.rubygems_version = %q{1.3.1}
22
+ s.summary = %q{Frex is a fork of Rex}
23
+ s.test_files = ["test/test_generator.rb"]
24
+
25
+ if s.respond_to? :specification_version then
26
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
27
+ s.specification_version = 2
28
+
29
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
30
+ s.add_development_dependency(%q<hoe>, [">= 1.9.0"])
31
+ else
32
+ s.add_dependency(%q<hoe>, [">= 1.9.0"])
33
+ end
34
+ else
35
+ s.add_dependency(%q<hoe>, [">= 1.9.0"])
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ require 'frex/generator'
2
+ require 'frex/info'
3
+ require 'frex/rexcmd'
@@ -0,0 +1,526 @@
1
+ #
2
+ # generator.rb
3
+ #
4
+ # Copyright (c) 2005-2006 ARIMA Yasuhiro <arima.yasuhiro@nifty.com>
5
+ #
6
+ # This program is free software.
7
+ # You can distribute/modify this program under the terms of
8
+ # the GNU Lesser General Public License version 2 or later.
9
+ #
10
+
11
+ require 'strscan'
12
+ module Frex
13
+
14
+ ## ---------------------------------------------------------------------
15
+ class ParseError < StandardError ; end
16
+ class FrexError < StandardError ; end
17
+
18
+ ## ---------------------------------------------------------------------
19
+ class Generator
20
+
21
+ ## ---------------------------------------------------------------------
22
+ attr_accessor :grammar_file
23
+ attr_accessor :scanner_file
24
+ attr_accessor :module_name
25
+ attr_accessor :class_name
26
+ attr_accessor :lineno
27
+ attr_accessor :rules
28
+ attr_accessor :exclusive_states
29
+ attr_accessor :ignorecase
30
+ attr_accessor :independent
31
+ attr_accessor :debug
32
+
33
+ ## ---------------------------------------------------------------------
34
+ def initialize(opts)
35
+ @lineno = 0
36
+ @macro = {}
37
+ @rules = []
38
+ @exclusive_states = [nil]
39
+ @grammar_lines = nil
40
+ @scanner_header = ""
41
+ @scanner_footer = ""
42
+ @scanner_inner = ""
43
+ @opt = opts
44
+ end
45
+
46
+ ## ---------------------------------------------------------------------
47
+ def add_header( st )
48
+ @scanner_header += "#{st}\n"
49
+ end
50
+
51
+ ## ---------------------------------------------------------------------
52
+ def add_footer( st )
53
+ @scanner_footer += "#{st}\n"
54
+ end
55
+
56
+ ## ---------------------------------------------------------------------
57
+ def add_inner( st )
58
+ @scanner_inner += "#{st}\n"
59
+ end
60
+
61
+ ## ---------------------------------------------------------------------
62
+ def add_option( st )
63
+ opts = st.split
64
+ opts.each do |opt|
65
+ case opt
66
+ when /ignorecase/i
67
+ @opt['--ignorecase'] = true
68
+ when /stub/i
69
+ @opt['--stub'] = true
70
+ when /independent/i
71
+ @opt['--independent'] = true
72
+ end
73
+ end
74
+ end
75
+
76
+ ## ---------------------------------------------------------------------
77
+ def add_macro( st )
78
+ ss = StringScanner.new(st)
79
+ ss.scan(/\s+/)
80
+ key = ss.scan(/\S+/)
81
+ ss.scan(/\s+/)
82
+ st = ss.post_match
83
+ len = st.size
84
+ ndx = 0
85
+ while ndx <= len
86
+ c = st[ndx,1]
87
+ ndx += 1
88
+ case c
89
+ when '\\'
90
+ ndx += 1
91
+ next
92
+ when '#', ' '
93
+ ndx -= 1
94
+ break
95
+ end
96
+ end
97
+ expr = st[0,ndx]
98
+ expr = expr.gsub(/\\/, '\\\\\\')
99
+ key = '{' + key + '}'
100
+ @macro.each_pair do |k, e|
101
+ expr.gsub! k, e
102
+ end
103
+ @macro[key] = expr
104
+ rescue
105
+ raise ParseError, "parse error in add_macro:'#{st}'"
106
+ end
107
+
108
+ ## ---------------------------------------------------------------------
109
+ def add_rule( rule_state, rule_expr, rule_action=nil )
110
+ st = rule_expr.dup
111
+ @macro.each_pair do |k, e|
112
+ rule_expr.gsub! k, e
113
+ end
114
+ if rule_state.to_s[1,1] =~ /[A-Z]/
115
+ @exclusive_states << rule_state unless @exclusive_states.include?(rule_state)
116
+ exclusive_state = rule_state
117
+ start_state = nil
118
+ else
119
+ exclusive_state = nil
120
+ start_state = rule_state
121
+ end
122
+ rule = [exclusive_state, start_state, rule_expr, rule_action]
123
+ @rules << rule
124
+ rescue
125
+ raise ParseError, "parse error in add_rule:'#{st}'"
126
+ end
127
+
128
+ ## ---------------------------------------------------------------------
129
+ def read_grammar
130
+ if !File.exist?(grammar_file)
131
+ raise Frex::FrexError, "can not file open: " + grammar_file
132
+ end
133
+ f = File.open(grammar_file, 'r')
134
+ @grammar_lines = StringScanner.new(f.read)
135
+ end
136
+
137
+ ## ---------------------------------------------------------------------
138
+ def next_line
139
+ @lineno += 1
140
+ @grammar_lines.scan(/[^\n]*\n/).chomp
141
+ rescue
142
+ nil
143
+ end
144
+
145
+ ## ---------------------------------------------------------------------
146
+ def parse
147
+ state1 = :HEAD
148
+ state2 = nil
149
+ state3 = nil
150
+ lastmodes = []
151
+ while st = next_line
152
+ case state1
153
+ when :FOOT
154
+ add_footer st
155
+
156
+ when :HEAD
157
+ ss = StringScanner.new(st)
158
+ if ss.scan(/class/)
159
+ state1 = :CLASS
160
+ st = ss.post_match.strip
161
+ if st =~ /(\S+)::(\S+)/
162
+ @module_name = $1
163
+ @class_name = $2
164
+ else
165
+ @module_name = nil
166
+ @class_name = st
167
+ end
168
+ else
169
+ add_header st
170
+ end
171
+
172
+ when :CLASS
173
+ s = st.strip
174
+ next if s.size == 0 or s[0,1] == '#'
175
+
176
+ ss = StringScanner.new(st)
177
+ if ss.scan(/option.*$/)
178
+ state2 = :OPTION
179
+ next
180
+ end
181
+ if ss.scan(/inner.*$/)
182
+ state2 = :INNER
183
+ next
184
+ end
185
+ if ss.scan(/macro.*$/)
186
+ state2 = :MACRO
187
+ next
188
+ end
189
+ if ss.scan(/rule.*$/)
190
+ state2 = :RULE
191
+ next
192
+ end
193
+ if ss.scan(/end.*$/)
194
+ state1 = :FOOT
195
+ next
196
+ end
197
+
198
+ case state2
199
+ when :OPTION
200
+ add_option st
201
+
202
+ when :INNER
203
+ add_inner st
204
+
205
+ when :MACRO
206
+ add_macro st
207
+
208
+ when :RULE
209
+ case state3
210
+ when nil
211
+ rule_state, rule_expr, rule_action = parse_rule(st)
212
+ if rule_action =~ /\s*\{/
213
+ lastmodes = parse_action(rule_action, lastmodes)
214
+ if lastmodes.empty?
215
+ add_rule rule_state, rule_expr, rule_action
216
+ else
217
+ state3 = :CONT
218
+ rule_action += "\n"
219
+ end
220
+ else
221
+ add_rule rule_state, rule_expr
222
+ end
223
+
224
+ when :CONT
225
+ rule_action += "#{st}\n"
226
+ lastmodes = parse_action(st, lastmodes)
227
+ if lastmodes.empty?
228
+ state3 = nil
229
+ add_rule rule_state, rule_expr, rule_action
230
+ else
231
+ end
232
+
233
+ end # case state3
234
+
235
+ end # case state2
236
+
237
+ end # case state1
238
+
239
+ end # while
240
+
241
+ end
242
+
243
+ ## ---------------------------------------------------------------------
244
+ def parse_rule(st)
245
+ st.strip!
246
+ return if st.size == 0 or st[0,1] == '#'
247
+ ss = StringScanner.new(st)
248
+ ss.scan(/\s+/)
249
+ rule_state = ss.scan(/\:\S+/)
250
+ ss.scan(/\s+/)
251
+ rule_expr = ss.scan(/\S+/)
252
+ ss.scan(/\s+/)
253
+ [rule_state, rule_expr, ss.post_match]
254
+ end
255
+
256
+ ## ---------------------------------------------------------------------
257
+ def parse_action(st, lastmodes=[])
258
+ modes = lastmodes
259
+ mode = lastmodes[-1]
260
+ ss = StringScanner.new(st)
261
+ until ss.eos?
262
+ c = ss.scan(/./)
263
+ case c
264
+ when '#'
265
+ if (mode == :brace) or (mode == nil)
266
+ #p [c, mode, modes]
267
+ return modes
268
+ end
269
+ when '{'
270
+ if (mode == :brace) or (mode == nil)
271
+ mode = :brace
272
+ modes.push mode
273
+ end
274
+ when '}'
275
+ if (mode == :brace)
276
+ modes.pop
277
+ mode = modes[0]
278
+ end
279
+ when "'"
280
+ if (mode == :brace)
281
+ mode = :quote
282
+ modes.push mode
283
+ elsif (mode == :quote)
284
+ modes.pop
285
+ mode = modes[0]
286
+ end
287
+ when '"'
288
+ if (mode == :brace)
289
+ mode = :doublequote
290
+ modes.push mode
291
+ elsif (mode == :doublequote)
292
+ modes.pop
293
+ mode = modes[0]
294
+ end
295
+ when '`'
296
+ if (mode == :brace)
297
+ mode = :backquote
298
+ modes.push mode
299
+ elsif (mode == :backquote)
300
+ modes.pop
301
+ mode = modes[0]
302
+ end
303
+ end
304
+ end
305
+ #p [c, mode, modes]
306
+ return modes
307
+ end
308
+
309
+ ## ---------------------------------------------------------------------
310
+
311
+ REX_HEADER = <<-REX_EOT
312
+ #--
313
+ # DO NOT MODIFY!!!!
314
+ # This file is automatically generated by rex %s
315
+ # from lexical definition file "%s".
316
+ #++
317
+
318
+ REX_EOT
319
+
320
+ REX_UTIL = <<-REX_EOT
321
+ require 'strscan'
322
+
323
+ class ScanError < StandardError ; end
324
+
325
+ attr_reader :lineno
326
+ attr_reader :filename
327
+
328
+ def scan_setup ; end
329
+
330
+ def action &block
331
+ yield
332
+ end
333
+
334
+ def scan_str( str )
335
+ scan_evaluate str
336
+ do_parse
337
+ end
338
+
339
+ def load_file( filename )
340
+ @filename = filename
341
+ open(filename, "r") do |f|
342
+ scan_evaluate f.read
343
+ end
344
+ end
345
+
346
+ def scan_file( filename )
347
+ load_file filename
348
+ do_parse
349
+ end
350
+
351
+ REX_EOT
352
+
353
+ REX_NEXTTOKEN_DEBUG = <<-REX_EOT
354
+ def next_token
355
+ p token = @rex_tokens.shift
356
+ token
357
+ end
358
+ REX_EOT
359
+
360
+ REX_NEXTTOKEN = <<-REX_EOT
361
+ def next_token
362
+ @rex_tokens.shift
363
+ end
364
+ REX_EOT
365
+
366
+ REX_STUB = <<-REX_EOT
367
+
368
+ if __FILE__ == $0
369
+ exit if ARGV.size != 1
370
+ filename = ARGV.shift
371
+ rex = %s.new
372
+ begin
373
+ rex.load_file filename
374
+ while token = rex.next_token
375
+ p token
376
+ end
377
+ rescue
378
+ $stderr.printf %s, rex.filename, rex.lineno, $!.message
379
+ end
380
+ end
381
+ REX_EOT
382
+
383
+ ## ---------------------------------------------------------------------
384
+ def write_scanner
385
+ unless scanner_file = @opt['--output-file']
386
+ scanner_file = grammar_file + ".rb"
387
+ end
388
+ f = File.open(scanner_file, 'w')
389
+
390
+ ## scan flag
391
+ flag = ""
392
+ flag += "i" if @opt['--ignorecase']
393
+ ## header
394
+ f.printf REX_HEADER, Frex::VERSION, grammar_file
395
+
396
+ unless @opt['--independent']
397
+ f.printf "require 'racc/parser'\n"
398
+ end
399
+
400
+ @scanner_header.each_line do |s|
401
+ f.print s
402
+ end
403
+ if @module_name
404
+ f.puts "module #{@module_name}"
405
+ end
406
+ if @opt['--independent']
407
+ f.puts "class #{@class_name}"
408
+ else
409
+ f.puts "class #{@class_name} < Racc::Parser"
410
+ end
411
+
412
+ ## utility method
413
+ f.print REX_UTIL
414
+
415
+ if @opt['--debug']
416
+ f.print REX_NEXTTOKEN_DEBUG
417
+ else
418
+ f.print REX_NEXTTOKEN
419
+ end
420
+
421
+ ## scanner method
422
+
423
+ f.print <<-REX_EOT
424
+
425
+ def scan_evaluate( str )
426
+ scan_setup
427
+ @rex_tokens = []
428
+ @lineno = 1
429
+ ss = StringScanner.new(str)
430
+ state = nil
431
+ until ss.eos?
432
+ text = ss.peek(1)
433
+ @lineno += 1 if text == "\\n"
434
+ case state
435
+ REX_EOT
436
+
437
+ exclusive_states.each do |es|
438
+ f.printf <<-REX_EOT
439
+ when #{es ? es.to_s : "nil"}
440
+ case
441
+ REX_EOT
442
+ rules.each do |rule|
443
+ exclusive_state, start_state, rule_expr, rule_action = *rule
444
+ if es == exclusive_state
445
+
446
+ if rule_action
447
+ if start_state
448
+ f.print <<-REX_EOT
449
+ when (state == #{start_state}) and (text = ss.scan(/#{rule_expr}/#{flag}))
450
+ @rex_tokens.push action #{rule_action}
451
+
452
+ REX_EOT
453
+ else
454
+ f.print <<-REX_EOT
455
+ when (text = ss.scan(/#{rule_expr}/#{flag}))
456
+ @rex_tokens.push action #{rule_action}
457
+
458
+ REX_EOT
459
+ end
460
+ else
461
+ if start_state
462
+ f.print <<-REX_EOT
463
+ when (state == #{start_state}) and (text = ss.scan(/#{rule_expr}/#{flag}))
464
+ ;
465
+
466
+ REX_EOT
467
+ else
468
+ f.print <<-REX_EOT
469
+ when (text = ss.scan(/#{rule_expr}/#{flag}))
470
+ ;
471
+
472
+ REX_EOT
473
+ end
474
+ end
475
+
476
+ end
477
+ end
478
+ f.print <<-REX_EOT
479
+ else
480
+ text = ss.string[ss.pos .. -1]
481
+ raise ScanError, "can not match: '" + text + "'"
482
+ end # if
483
+
484
+ REX_EOT
485
+ end
486
+ f.print <<-REX_EOT
487
+ else
488
+ raise ScanError, "undefined state: '" + state.to_s + "'"
489
+ end # case state
490
+ end # until ss
491
+ end # def scan_evaluate
492
+
493
+ REX_EOT
494
+
495
+ ## inner method
496
+ @scanner_inner.each_line do |s|
497
+ f.print s
498
+ end
499
+ f.puts "end # class"
500
+ f.puts "end # module" if @module_name
501
+
502
+ ## footer
503
+ @scanner_footer.each_line do |s|
504
+ f.print s
505
+ end # case
506
+
507
+ ## stub main
508
+ f.printf REX_STUB, @class_name, '"%s:%d:%s\n"' if @opt['--stub']
509
+ f.close
510
+
511
+ end ## def
512
+ end ## class
513
+ end ## module
514
+
515
+
516
+ ## ---------------------------------------------------------------------
517
+ ## test
518
+
519
+ if __FILE__ == $0
520
+ rex = Frex::Generator.new(nil)
521
+ rex.grammar_file = "sample.rex"
522
+ rex.read_grammar
523
+ rex.parse
524
+ rex.write_scanner
525
+ end
526
+