tenderlove-frex 1.0.1.20090313144615
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.rdoc +7 -0
- data/DOCUMENTATION.en.rdoc +215 -0
- data/DOCUMENTATION.ja.rdoc +205 -0
- data/Manifest.txt +38 -0
- data/README.ja +73 -0
- data/README.rdoc +39 -0
- data/Rakefile +27 -0
- data/bin/frex +18 -0
- data/frex.gemspec +37 -0
- data/lib/frex.rb +3 -0
- data/lib/frex/generator.rb +526 -0
- data/lib/frex/info.rb +16 -0
- data/lib/frex/rexcmd.rb +136 -0
- data/sample/a.cmd +1 -0
- data/sample/b.cmd +1 -0
- data/sample/c.cmd +4 -0
- data/sample/calc3.racc +47 -0
- data/sample/calc3.rex +15 -0
- data/sample/calc3.rex.rb +94 -0
- data/sample/calc3.tab.rb +188 -0
- data/sample/error1.rex +15 -0
- data/sample/error2.rex +15 -0
- data/sample/sample.html +32 -0
- data/sample/sample.rex +15 -0
- data/sample/sample.rex.rb +100 -0
- data/sample/sample.xhtml +32 -0
- data/sample/sample1.c +9 -0
- data/sample/sample1.rex +43 -0
- data/sample/sample2.bas +4 -0
- data/sample/sample2.rex +33 -0
- data/sample/simple.html +7 -0
- data/sample/simple.xhtml +10 -0
- data/sample/xhtmlparser.racc +66 -0
- data/sample/xhtmlparser.rex +72 -0
- data/test/assets/test.rex +12 -0
- data/test/rex-20060125.rb +152 -0
- data/test/rex-20060511.rb +143 -0
- data/test/test_generator.rb +27 -0
- metadata +105 -0
data/lib/frex/info.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#
|
2
|
+
# info.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
|
+
module Frex
|
12
|
+
VERSION = '1.0.1'
|
13
|
+
Copyright = 'Copyright (c) 2005-2006 ARIMA Yasuhiro'
|
14
|
+
Mailto = 'arima.yasuhiro@nifty.com'
|
15
|
+
end
|
16
|
+
|
data/lib/frex/rexcmd.rb
ADDED
@@ -0,0 +1,136 @@
|
|
1
|
+
#
|
2
|
+
# rexcmd.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 LGPL, Lesser General Public License version 2.1.
|
9
|
+
# For details of LGPL, see the file "COPYING".
|
10
|
+
#
|
11
|
+
|
12
|
+
## ---------------------------------------------------------------------
|
13
|
+
|
14
|
+
require 'getoptlong'
|
15
|
+
module Frex
|
16
|
+
|
17
|
+
class Cmd
|
18
|
+
OPTIONS = <<-EOT
|
19
|
+
|
20
|
+
o -o --output-file <outfile> file name of output [<filename>.rb]
|
21
|
+
o -s --stub - append stub code for debug
|
22
|
+
o -i --ignorecase - ignore char case
|
23
|
+
o -C --check-only - syntax check only
|
24
|
+
o - --independent - independent mode
|
25
|
+
o -d --debug - print debug information
|
26
|
+
o -h --help - print this message and quit
|
27
|
+
o - --version - print version and quit
|
28
|
+
o - --copyright - print copyright and quit
|
29
|
+
|
30
|
+
EOT
|
31
|
+
|
32
|
+
def run
|
33
|
+
@status = 1
|
34
|
+
usage 'no grammar file given' if ARGV.empty?
|
35
|
+
usage 'too many grammar files given' if ARGV.size > 1
|
36
|
+
filename = ARGV[0]
|
37
|
+
|
38
|
+
rex = Frex::Generator.new(@opt)
|
39
|
+
begin
|
40
|
+
rex.grammar_file = filename
|
41
|
+
rex.read_grammar
|
42
|
+
rex.parse
|
43
|
+
if @opt['--check-only']
|
44
|
+
$stderr.puts "syntax ok"
|
45
|
+
return 0
|
46
|
+
end
|
47
|
+
rex.write_scanner
|
48
|
+
@status = 0
|
49
|
+
|
50
|
+
rescue Frex::ParseError, Errno::ENOENT
|
51
|
+
msg = $!.to_s
|
52
|
+
unless /\A\d/ === msg
|
53
|
+
msg[0,0] = ' '
|
54
|
+
end
|
55
|
+
$stderr.puts "#{@cmd}:#{rex.grammar_file}:#{rex.lineno}:#{msg}"
|
56
|
+
|
57
|
+
ensure
|
58
|
+
exit @status
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize
|
64
|
+
@status = 2
|
65
|
+
@cmd = File.basename($0, ".rb")
|
66
|
+
tmp = OPTIONS.collect do |line|
|
67
|
+
next if /\A\s*\z/ === line
|
68
|
+
disp, sopt, lopt, takearg, doc = line.strip.split(/\s+/, 5)
|
69
|
+
a = []
|
70
|
+
a.push lopt unless lopt == '-'
|
71
|
+
a.push sopt unless sopt == '-'
|
72
|
+
a.push takearg == '-' ?
|
73
|
+
GetoptLong::NO_ARGUMENT : GetoptLong::REQUIRED_ARGUMENT
|
74
|
+
a
|
75
|
+
end
|
76
|
+
getopt = GetoptLong.new(*tmp.compact)
|
77
|
+
getopt.quiet = true
|
78
|
+
|
79
|
+
@opt = {}
|
80
|
+
begin
|
81
|
+
getopt.each do |name, arg|
|
82
|
+
raise GetoptLong::InvalidOption,
|
83
|
+
"#{@cmd}: #{name} given twice" if @opt.key? name
|
84
|
+
@opt[name] = arg.empty? ? true : arg
|
85
|
+
end
|
86
|
+
rescue GetoptLong::AmbigousOption, GetoptLong::InvalidOption,
|
87
|
+
GetoptLong::MissingArgument, GetoptLong::NeedlessArgument
|
88
|
+
usage $!.message
|
89
|
+
end
|
90
|
+
|
91
|
+
usage if @opt['--help']
|
92
|
+
|
93
|
+
if @opt['--version']
|
94
|
+
puts "#{@cmd} version #{Frex::Version}"
|
95
|
+
exit 0
|
96
|
+
end
|
97
|
+
if @opt['--copyright']
|
98
|
+
puts "#{@cmd} version #{Frex::Version}"
|
99
|
+
puts "#{Frex::Copyright} <#{Frex::Mailto}>"
|
100
|
+
exit 0
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def usage( msg=nil )
|
105
|
+
f = $stderr
|
106
|
+
f.puts "#{@cmd}: #{msg}" if msg
|
107
|
+
f.print <<-EOT
|
108
|
+
Usage: #{@cmd} [options] <grammar file>
|
109
|
+
Options:
|
110
|
+
EOT
|
111
|
+
|
112
|
+
OPTIONS.each do |line|
|
113
|
+
next if line.strip.empty?
|
114
|
+
if /\A\s*\z/ === line
|
115
|
+
f.puts
|
116
|
+
next
|
117
|
+
end
|
118
|
+
|
119
|
+
disp, sopt, lopt, takearg, doc = line.strip.split(/\s+/, 5)
|
120
|
+
if disp == 'o'
|
121
|
+
sopt = nil if sopt == '-'
|
122
|
+
lopt = nil if lopt == '-'
|
123
|
+
opt = [sopt, lopt].compact.join(',')
|
124
|
+
|
125
|
+
takearg = nil if takearg == '-'
|
126
|
+
opt = [opt, takearg].compact.join(' ')
|
127
|
+
|
128
|
+
f.printf "%-27s %s\n", opt, doc
|
129
|
+
end
|
130
|
+
end
|
131
|
+
|
132
|
+
exit @status
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
data/sample/a.cmd
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
call rex xhtmlparser.rex -s %*
|
data/sample/b.cmd
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
call racc xhtmlparser.racc -v %*
|
data/sample/c.cmd
ADDED
data/sample/calc3.racc
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#
|
2
|
+
# A simple calculator, version 3.
|
3
|
+
#
|
4
|
+
|
5
|
+
class Calculator3
|
6
|
+
prechigh
|
7
|
+
nonassoc UMINUS
|
8
|
+
left '*' '/'
|
9
|
+
left '+' '-'
|
10
|
+
preclow
|
11
|
+
options no_result_var
|
12
|
+
rule
|
13
|
+
target : exp
|
14
|
+
| /* none */ { 0 }
|
15
|
+
|
16
|
+
exp : exp '+' exp { val[0] + val[2] }
|
17
|
+
| exp '-' exp { val[0] - val[2] }
|
18
|
+
| exp '*' exp { val[0] * val[2] }
|
19
|
+
| exp '/' exp { val[0] / val[2] }
|
20
|
+
| '(' exp ')' { val[1] }
|
21
|
+
| '-' NUMBER =UMINUS { -(val[1]) }
|
22
|
+
| NUMBER
|
23
|
+
end
|
24
|
+
|
25
|
+
---- header ----
|
26
|
+
#
|
27
|
+
# generated by racc
|
28
|
+
#
|
29
|
+
require 'calc3.rex'
|
30
|
+
|
31
|
+
---- inner ----
|
32
|
+
|
33
|
+
---- footer ----
|
34
|
+
|
35
|
+
puts 'sample calc'
|
36
|
+
puts '"q" to quit.'
|
37
|
+
calc = Calculator3.new
|
38
|
+
while true
|
39
|
+
print '>>> '; $stdout.flush
|
40
|
+
str = $stdin.gets.strip
|
41
|
+
break if /q/i === str
|
42
|
+
begin
|
43
|
+
p calc.scan_str(str)
|
44
|
+
rescue ParseError
|
45
|
+
puts 'parse error'
|
46
|
+
end
|
47
|
+
end
|
data/sample/calc3.rex
ADDED
data/sample/calc3.rex.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by rex 1.0.0
|
4
|
+
# from lexical definition file "calc3.rex".
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'racc/parser'
|
8
|
+
#
|
9
|
+
# calc3.rex
|
10
|
+
# lexical scanner definition for rex
|
11
|
+
#
|
12
|
+
|
13
|
+
class Calculator3 < Racc::Parser
|
14
|
+
require 'strscan'
|
15
|
+
|
16
|
+
class ScanError < StandardError ; end
|
17
|
+
|
18
|
+
attr_reader :lineno
|
19
|
+
attr_reader :filename
|
20
|
+
|
21
|
+
def scan_setup ; end
|
22
|
+
|
23
|
+
def action &block
|
24
|
+
yield
|
25
|
+
end
|
26
|
+
|
27
|
+
def scan_str( str )
|
28
|
+
scan_evaluate str
|
29
|
+
do_parse
|
30
|
+
end
|
31
|
+
|
32
|
+
def load_file( filename )
|
33
|
+
@filename = filename
|
34
|
+
open(filename, "r") do |f|
|
35
|
+
scan_evaluate f.read
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def scan_file( filename )
|
40
|
+
load_file filename
|
41
|
+
do_parse
|
42
|
+
end
|
43
|
+
|
44
|
+
def next_token
|
45
|
+
@rex_tokens.shift
|
46
|
+
end
|
47
|
+
|
48
|
+
def scan_evaluate( str )
|
49
|
+
scan_setup
|
50
|
+
@rex_tokens = []
|
51
|
+
@lineno = 1
|
52
|
+
ss = StringScanner.new(str)
|
53
|
+
state = nil
|
54
|
+
until ss.eos?
|
55
|
+
text = ss.peek(1)
|
56
|
+
@lineno += 1 if text == "\n"
|
57
|
+
case state
|
58
|
+
when nil
|
59
|
+
case
|
60
|
+
when (text = ss.scan(/\s+/))
|
61
|
+
;
|
62
|
+
|
63
|
+
when (text = ss.scan(/\d+/))
|
64
|
+
@rex_tokens.push action { [:NUMBER, text.to_i] }
|
65
|
+
|
66
|
+
when (text = ss.scan(/.|\n/))
|
67
|
+
@rex_tokens.push action { [text, text] }
|
68
|
+
|
69
|
+
else
|
70
|
+
text = ss.string[ss.pos .. -1]
|
71
|
+
raise ScanError, "can not match: '" + text + "'"
|
72
|
+
end # if
|
73
|
+
|
74
|
+
else
|
75
|
+
raise ScanError, "undefined state: '" + state.to_s + "'"
|
76
|
+
end # case state
|
77
|
+
end # until ss
|
78
|
+
end # def scan_evaluate
|
79
|
+
|
80
|
+
end # class
|
81
|
+
|
82
|
+
if __FILE__ == $0
|
83
|
+
exit if ARGV.size != 1
|
84
|
+
filename = ARGV.shift
|
85
|
+
rex = Calculator3.new
|
86
|
+
begin
|
87
|
+
rex.load_file filename
|
88
|
+
while token = rex.next_token
|
89
|
+
p token
|
90
|
+
end
|
91
|
+
rescue
|
92
|
+
$stderr.printf "%s:%d:%s\n", rex.filename, rex.lineno, $!.message
|
93
|
+
end
|
94
|
+
end
|
data/sample/calc3.tab.rb
ADDED
@@ -0,0 +1,188 @@
|
|
1
|
+
#
|
2
|
+
# DO NOT MODIFY!!!!
|
3
|
+
# This file is automatically generated by racc 1.4.4
|
4
|
+
# from racc grammer file "calc3.racc".
|
5
|
+
#
|
6
|
+
|
7
|
+
require 'racc/parser'
|
8
|
+
|
9
|
+
|
10
|
+
#
|
11
|
+
# generated by racc
|
12
|
+
#
|
13
|
+
require 'calc3.rex'
|
14
|
+
|
15
|
+
|
16
|
+
class Calculator3 < Racc::Parser
|
17
|
+
|
18
|
+
##### racc 1.4.4 generates ###
|
19
|
+
|
20
|
+
racc_reduce_table = [
|
21
|
+
0, 0, :racc_error,
|
22
|
+
1, 11, :_reduce_none,
|
23
|
+
0, 11, :_reduce_2,
|
24
|
+
3, 12, :_reduce_3,
|
25
|
+
3, 12, :_reduce_4,
|
26
|
+
3, 12, :_reduce_5,
|
27
|
+
3, 12, :_reduce_6,
|
28
|
+
3, 12, :_reduce_7,
|
29
|
+
2, 12, :_reduce_8,
|
30
|
+
1, 12, :_reduce_none ]
|
31
|
+
|
32
|
+
racc_reduce_n = 10
|
33
|
+
|
34
|
+
racc_shift_n = 19
|
35
|
+
|
36
|
+
racc_action_table = [
|
37
|
+
7, 8, 9, 10, 6, 18, 3, 4, 11, 5,
|
38
|
+
7, 8, 9, 10, 3, 4, 13, 5, 3, 4,
|
39
|
+
nil, 5, 3, 4, nil, 5, 3, 4, nil, 5,
|
40
|
+
3, 4, nil, 5, 7, 8, 7, 8 ]
|
41
|
+
|
42
|
+
racc_action_check = [
|
43
|
+
12, 12, 12, 12, 1, 12, 10, 10, 3, 10,
|
44
|
+
2, 2, 2, 2, 0, 0, 6, 0, 4, 4,
|
45
|
+
nil, 4, 9, 9, nil, 9, 8, 8, nil, 8,
|
46
|
+
7, 7, nil, 7, 17, 17, 16, 16 ]
|
47
|
+
|
48
|
+
racc_action_pointer = [
|
49
|
+
8, 4, 7, -1, 12, nil, 16, 24, 20, 16,
|
50
|
+
0, nil, -3, nil, nil, nil, 33, 31, nil ]
|
51
|
+
|
52
|
+
racc_action_default = [
|
53
|
+
-2, -10, -1, -10, -10, -9, -10, -10, -10, -10,
|
54
|
+
-10, -8, -10, 19, -5, -6, -3, -4, -7 ]
|
55
|
+
|
56
|
+
racc_goto_table = [
|
57
|
+
2, 1, nil, nil, 12, nil, nil, 14, 15, 16,
|
58
|
+
17 ]
|
59
|
+
|
60
|
+
racc_goto_check = [
|
61
|
+
2, 1, nil, nil, 2, nil, nil, 2, 2, 2,
|
62
|
+
2 ]
|
63
|
+
|
64
|
+
racc_goto_pointer = [
|
65
|
+
nil, 1, 0 ]
|
66
|
+
|
67
|
+
racc_goto_default = [
|
68
|
+
nil, nil, nil ]
|
69
|
+
|
70
|
+
racc_token_table = {
|
71
|
+
false => 0,
|
72
|
+
Object.new => 1,
|
73
|
+
:UMINUS => 2,
|
74
|
+
"*" => 3,
|
75
|
+
"/" => 4,
|
76
|
+
"+" => 5,
|
77
|
+
"-" => 6,
|
78
|
+
"(" => 7,
|
79
|
+
")" => 8,
|
80
|
+
:NUMBER => 9 }
|
81
|
+
|
82
|
+
racc_use_result_var = false
|
83
|
+
|
84
|
+
racc_nt_base = 10
|
85
|
+
|
86
|
+
Racc_arg = [
|
87
|
+
racc_action_table,
|
88
|
+
racc_action_check,
|
89
|
+
racc_action_default,
|
90
|
+
racc_action_pointer,
|
91
|
+
racc_goto_table,
|
92
|
+
racc_goto_check,
|
93
|
+
racc_goto_default,
|
94
|
+
racc_goto_pointer,
|
95
|
+
racc_nt_base,
|
96
|
+
racc_reduce_table,
|
97
|
+
racc_token_table,
|
98
|
+
racc_shift_n,
|
99
|
+
racc_reduce_n,
|
100
|
+
racc_use_result_var ]
|
101
|
+
|
102
|
+
Racc_token_to_s_table = [
|
103
|
+
'$end',
|
104
|
+
'error',
|
105
|
+
'UMINUS',
|
106
|
+
'"*"',
|
107
|
+
'"/"',
|
108
|
+
'"+"',
|
109
|
+
'"-"',
|
110
|
+
'"("',
|
111
|
+
'")"',
|
112
|
+
'NUMBER',
|
113
|
+
'$start',
|
114
|
+
'target',
|
115
|
+
'exp']
|
116
|
+
|
117
|
+
Racc_debug_parser = false
|
118
|
+
|
119
|
+
##### racc system variables end #####
|
120
|
+
|
121
|
+
# reduce 0 omitted
|
122
|
+
|
123
|
+
# reduce 1 omitted
|
124
|
+
|
125
|
+
module_eval <<'.,.,', 'calc3.racc', 13
|
126
|
+
def _reduce_2( val, _values)
|
127
|
+
0
|
128
|
+
end
|
129
|
+
.,.,
|
130
|
+
|
131
|
+
module_eval <<'.,.,', 'calc3.racc', 15
|
132
|
+
def _reduce_3( val, _values)
|
133
|
+
val[0] + val[2]
|
134
|
+
end
|
135
|
+
.,.,
|
136
|
+
|
137
|
+
module_eval <<'.,.,', 'calc3.racc', 16
|
138
|
+
def _reduce_4( val, _values)
|
139
|
+
val[0] - val[2]
|
140
|
+
end
|
141
|
+
.,.,
|
142
|
+
|
143
|
+
module_eval <<'.,.,', 'calc3.racc', 17
|
144
|
+
def _reduce_5( val, _values)
|
145
|
+
val[0] * val[2]
|
146
|
+
end
|
147
|
+
.,.,
|
148
|
+
|
149
|
+
module_eval <<'.,.,', 'calc3.racc', 18
|
150
|
+
def _reduce_6( val, _values)
|
151
|
+
val[0] / val[2]
|
152
|
+
end
|
153
|
+
.,.,
|
154
|
+
|
155
|
+
module_eval <<'.,.,', 'calc3.racc', 19
|
156
|
+
def _reduce_7( val, _values)
|
157
|
+
val[1]
|
158
|
+
end
|
159
|
+
.,.,
|
160
|
+
|
161
|
+
module_eval <<'.,.,', 'calc3.racc', 20
|
162
|
+
def _reduce_8( val, _values)
|
163
|
+
-(val[1])
|
164
|
+
end
|
165
|
+
.,.,
|
166
|
+
|
167
|
+
# reduce 9 omitted
|
168
|
+
|
169
|
+
def _reduce_none( val, _values)
|
170
|
+
val[0]
|
171
|
+
end
|
172
|
+
|
173
|
+
end # class Calculator3
|
174
|
+
|
175
|
+
|
176
|
+
puts 'sample calc'
|
177
|
+
puts '"q" to quit.'
|
178
|
+
calc = Calculator3.new
|
179
|
+
while true
|
180
|
+
print '>>> '; $stdout.flush
|
181
|
+
str = $stdin.gets.strip
|
182
|
+
break if /q/i === str
|
183
|
+
begin
|
184
|
+
p calc.scan_str(str)
|
185
|
+
rescue ParseError
|
186
|
+
puts 'parse error'
|
187
|
+
end
|
188
|
+
end
|