rexical 1.0.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of rexical might be problematic. Click here for more details.
- data/CHANGELOG.rdoc +13 -0
- data/DOCUMENTATION.en.rdoc +215 -0
- data/DOCUMENTATION.ja.rdoc +205 -0
- data/Manifest.txt +37 -0
- data/README.ja +73 -0
- data/README.rdoc +52 -0
- data/Rakefile +28 -0
- data/bin/rex +18 -0
- data/lib/rexical.rb +3 -0
- data/lib/rexical/generator.rb +523 -0
- data/lib/rexical/info.rb +16 -0
- data/lib/rexical/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 +184 -0
- metadata +109 -0
data/lib/rexical/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 Rexical
|
12
|
+
VERSION = '1.0.3'
|
13
|
+
Copyright = 'Copyright (c) 2005-2006 ARIMA Yasuhiro'
|
14
|
+
Mailto = 'arima.yasuhiro@nifty.com'
|
15
|
+
end
|
16
|
+
|
@@ -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 Rexical
|
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 = Rexical::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 Rexical::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 #{Rexical::Version}"
|
95
|
+
exit 0
|
96
|
+
end
|
97
|
+
if @opt['--copyright']
|
98
|
+
puts "#{@cmd} version #{Rexical::Version}"
|
99
|
+
puts "#{Rexical::Copyright} <#{Rexical::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
|