ruby_parser 3.8.4 → 3.9.0
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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data.tar.gz.sig +0 -0
- data/History.rdoc +29 -0
- data/Manifest.txt +5 -0
- data/README.rdoc +12 -0
- data/Rakefile +128 -69
- data/compare/normalize.rb +146 -0
- data/lib/rp_extensions.rb +77 -0
- data/lib/rp_stringscanner.rb +64 -0
- data/lib/ruby18_parser.rb +2180 -2175
- data/lib/ruby18_parser.y +17 -13
- data/lib/ruby19_parser.rb +2250 -2241
- data/lib/ruby19_parser.y +18 -14
- data/lib/ruby20_parser.rb +2498 -2503
- data/lib/ruby20_parser.y +18 -29
- data/lib/ruby21_parser.rb +2287 -2275
- data/lib/ruby21_parser.y +18 -24
- data/lib/ruby22_parser.rb +2573 -2560
- data/lib/ruby22_parser.y +18 -24
- data/lib/ruby23_parser.rb +2498 -2494
- data/lib/ruby23_parser.y +18 -24
- data/lib/ruby24_parser.rb +6797 -0
- data/lib/ruby24_parser.y +2367 -0
- data/lib/ruby_lexer.rb +11 -16
- data/lib/ruby_parser.rb +86 -7
- data/lib/ruby_parser.yy +57 -53
- data/lib/ruby_parser_extras.rb +34 -237
- data/test/test_ruby_lexer.rb +54 -41
- data/test/test_ruby_parser.rb +776 -700
- data/test/test_ruby_parser_extras.rb +4 -6
- metadata +7 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db3aec0f342263aec6c4bc598f2af937d889219b
|
4
|
+
data.tar.gz: 0a7300cfcb5109443168aa3432eefb0b103a07a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c26c726384052dc9ea43d9cb29f982ed03768458c1ff0e64a515026c721be346f009ead616d18c499d449fbf9a6c23234a4c637afb14cf28fb74035a33a743db
|
7
|
+
data.tar.gz: 4f3d570afe84856c5275be5a9eaf9277168a89db5bd3dea605cc86cf8c38492d9ee0b5ec2d32c3413124c068ff57e24a5241d8474463e15018376328fff024ec
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
data.tar.gz.sig
CHANGED
Binary file
|
data/History.rdoc
CHANGED
@@ -1,3 +1,32 @@
|
|
1
|
+
=== 3.9.0 / 2017-04-13
|
2
|
+
|
3
|
+
* 1 major enhancement:
|
4
|
+
|
5
|
+
* Added tentative ruby 2.4 support. Probably missing things.
|
6
|
+
|
7
|
+
* 13 minor enhancements:
|
8
|
+
|
9
|
+
* Added RubyParser.latest.
|
10
|
+
* Added RubyParser::Parser.version to make version range comparisons easier
|
11
|
+
* Changed superclasses of all parsers to RubyParser::Parser
|
12
|
+
* Cleaned up a lot of the version specific code to be more generic/flexible.
|
13
|
+
* Documented how to add new versions in README.
|
14
|
+
* Moved RubyParser from ruby_parser_extras.rb into ruby_parser.rb to fix bootstrap issues.
|
15
|
+
* Renamed RubyParserStuff#get_match_node to new_match. Aliased and deprecated.
|
16
|
+
* Renamed RubyParserStuff#logop to logical_op. Aliased and deprecated.
|
17
|
+
* Renamed RubyParserStuff#node_assign to new_assign. Aliased and deprecated.
|
18
|
+
* Renamed all parsers to RubyParser::V##.
|
19
|
+
* Revamped grammar preprocessing to make adding new versions easier.
|
20
|
+
* RubyParser.for_current_ruby falls back to latest if current not available.
|
21
|
+
* Subclasses of RubyParser::Parser register themselves into RubyParser::VERSIONS.
|
22
|
+
|
23
|
+
* 4 bug fixes:
|
24
|
+
|
25
|
+
* Fixed `&.` after newline. (presidentbeef)
|
26
|
+
* Fixed bug setting line number for hash literals to line of opening brace.
|
27
|
+
* Fixed grammar preprocessing bug.
|
28
|
+
* Properly handle kDO with no-parens stabby lambda. (presidentbeef)
|
29
|
+
|
1
30
|
=== 3.8.4 / 2017-01-13
|
2
31
|
|
3
32
|
* 3 bug fixes:
|
data/Manifest.txt
CHANGED
@@ -5,7 +5,10 @@ README.rdoc
|
|
5
5
|
Rakefile
|
6
6
|
bin/ruby_parse
|
7
7
|
bin/ruby_parse_extract_error
|
8
|
+
compare/normalize.rb
|
8
9
|
lib/.document
|
10
|
+
lib/rp_extensions.rb
|
11
|
+
lib/rp_stringscanner.rb
|
9
12
|
lib/ruby18_parser.rb
|
10
13
|
lib/ruby18_parser.y
|
11
14
|
lib/ruby19_parser.rb
|
@@ -18,6 +21,8 @@ lib/ruby22_parser.rb
|
|
18
21
|
lib/ruby22_parser.y
|
19
22
|
lib/ruby23_parser.rb
|
20
23
|
lib/ruby23_parser.y
|
24
|
+
lib/ruby24_parser.rb
|
25
|
+
lib/ruby24_parser.y
|
21
26
|
lib/ruby_lexer.rb
|
22
27
|
lib/ruby_lexer.rex
|
23
28
|
lib/ruby_lexer.rex.rb
|
data/README.rdoc
CHANGED
@@ -57,6 +57,18 @@ You can also use Ruby19Parser, Ruby18Parser, or RubyParser.for_current_ruby:
|
|
57
57
|
RubyParser.for_current_ruby.parse "1+1"
|
58
58
|
# => s(:call, s(:lit, 1), :+, s(:lit, 1))
|
59
59
|
|
60
|
+
== DEVELOPER NOTES:
|
61
|
+
|
62
|
+
To add a new version:
|
63
|
+
|
64
|
+
* New parser should be generated from lib/ruby_parser.yy.
|
65
|
+
* Extend lib/ruby_parser.yy with new class name.
|
66
|
+
* Add new version number to Rakefile for rule creation.
|
67
|
+
* Require generated parser in lib/ruby_parser.rb.
|
68
|
+
* Add empty TestRubyParserShared##Plus module and TestRubyParserV## to test/test_ruby_parser.rb.
|
69
|
+
* Extend Manifest.txt with generated file names.
|
70
|
+
* Extend sexp_processor's pt_testcase.rb to match version
|
71
|
+
|
60
72
|
== REQUIREMENTS:
|
61
73
|
|
62
74
|
* ruby. woot.
|
data/Rakefile
CHANGED
@@ -14,6 +14,10 @@ Hoe.add_include_dirs "../../sexp_processor/dev/lib"
|
|
14
14
|
Hoe.add_include_dirs "../../minitest/dev/lib"
|
15
15
|
Hoe.add_include_dirs "../../oedipus_lex/dev/lib"
|
16
16
|
|
17
|
+
V1 = %w[18 19]
|
18
|
+
V2 = %w[20 21 22 23 24]
|
19
|
+
V1_2 = V1 + V2
|
20
|
+
|
17
21
|
Hoe.spec "ruby_parser" do
|
18
22
|
developer "Ryan Davis", "ryand-ruby@zenspider.com"
|
19
23
|
|
@@ -24,45 +28,35 @@ Hoe.spec "ruby_parser" do
|
|
24
28
|
dependency "oedipus_lex", "~> 2.1", :developer
|
25
29
|
|
26
30
|
if plugin? :perforce then # generated files
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
self.perforce_ignore << "lib/ruby20_parser.y"
|
31
|
-
self.perforce_ignore << "lib/ruby21_parser.rb"
|
32
|
-
self.perforce_ignore << "lib/ruby21_parser.y"
|
33
|
-
self.perforce_ignore << "lib/ruby22_parser.rb"
|
34
|
-
self.perforce_ignore << "lib/ruby22_parser.y"
|
35
|
-
self.perforce_ignore << "lib/ruby23_parser.rb"
|
36
|
-
self.perforce_ignore << "lib/ruby23_parser.y"
|
37
|
-
self.perforce_ignore << "lib/ruby_lexer.rex.rb"
|
38
|
-
end
|
31
|
+
V1_2.each do |n|
|
32
|
+
self.perforce_ignore << "lib/ruby#{n}_parser.rb"
|
33
|
+
end
|
39
34
|
|
40
|
-
|
41
|
-
|
35
|
+
V2.each do |n|
|
36
|
+
self.perforce_ignore << "lib/ruby#{n}_parser.y"
|
37
|
+
end
|
42
38
|
|
43
|
-
|
44
|
-
|
45
|
-
end
|
39
|
+
self.perforce_ignore << "lib/ruby_lexer.rex.rb"
|
40
|
+
end
|
46
41
|
|
47
|
-
|
48
|
-
|
42
|
+
if plugin?(:racc)
|
43
|
+
self.racc_flags << " -t" if ENV["DEBUG"]
|
44
|
+
self.racc_flags << " --superclass RubyParser::Parser"
|
45
|
+
# self.racc_flags << " --runtime ruby_parser" # TODO: broken in racc
|
46
|
+
end
|
49
47
|
end
|
50
48
|
|
51
|
-
|
52
|
-
|
49
|
+
V2.each do |n|
|
50
|
+
file "lib/ruby#{n}_parser.y" => "lib/ruby_parser.yy" do |t|
|
51
|
+
cmd = 'unifdef -tk -DV=%s -UDEAD %s > %s || true' % [n, t.source, t.name]
|
52
|
+
sh cmd
|
53
|
+
end
|
53
54
|
end
|
54
55
|
|
55
|
-
|
56
|
-
|
56
|
+
V1_2.each do |n|
|
57
|
+
file "lib/ruby#{n}_parser.rb" => "lib/ruby#{n}_parser.y"
|
57
58
|
end
|
58
59
|
|
59
|
-
|
60
|
-
file "lib/ruby18_parser.rb" => "lib/ruby18_parser.y"
|
61
|
-
file "lib/ruby19_parser.rb" => "lib/ruby19_parser.y"
|
62
|
-
file "lib/ruby20_parser.rb" => "lib/ruby20_parser.y"
|
63
|
-
file "lib/ruby21_parser.rb" => "lib/ruby21_parser.y"
|
64
|
-
file "lib/ruby22_parser.rb" => "lib/ruby22_parser.y"
|
65
|
-
file "lib/ruby23_parser.rb" => "lib/ruby23_parser.y"
|
66
60
|
file "lib/ruby_lexer.rex.rb" => "lib/ruby_lexer.rex"
|
67
61
|
|
68
62
|
task :clean do
|
@@ -94,32 +88,110 @@ end
|
|
94
88
|
|
95
89
|
task :isolate => :phony
|
96
90
|
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
91
|
+
def in_compare
|
92
|
+
Dir.chdir "compare" do
|
93
|
+
yield
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def dl v
|
98
|
+
dir = v[/^\d+\.\d+/]
|
99
|
+
url = "https://cache.ruby-lang.org/pub/ruby/#{dir}/ruby-#{v}.tar.bz2"
|
100
|
+
path = File.basename url
|
101
|
+
unless File.exist? path then
|
102
|
+
system "curl -O #{url}"
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def ruby_parse version
|
107
|
+
v = version[/^\d+\.\d+/].delete "."
|
108
|
+
rp_txt = "rp#{v}.txt"
|
109
|
+
mri_txt = "mri#{v}.txt"
|
110
|
+
parse_y = "parse#{v}.y"
|
111
|
+
tarball = "ruby-#{version}.tar.bz2"
|
112
|
+
ruby_dir = "ruby-#{version}"
|
113
|
+
diff = "diff#{v}.diff"
|
114
|
+
rp_out = "lib/ruby#{v}_parser.output"
|
115
|
+
|
116
|
+
c_diff = "compare/#{diff}"
|
117
|
+
c_rp_txt = "compare/#{rp_txt}"
|
118
|
+
c_mri_txt = "compare/#{mri_txt}"
|
119
|
+
c_parse_y = "compare/#{parse_y}"
|
120
|
+
c_tarball = "compare/#{tarball}"
|
121
|
+
|
122
|
+
file tarball do
|
123
|
+
in_compare do
|
124
|
+
dl version
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
file c_parse_y => c_tarball do
|
129
|
+
in_compare do
|
130
|
+
system "tar yxf #{tarball} #{ruby_dir}/{id.h,parse.y,tool/{id2token.rb,vpath.rb}}"
|
131
|
+
Dir.chdir ruby_dir do
|
132
|
+
if File.exist? "tool/id2token.rb" then
|
133
|
+
sh "ruby tool/id2token.rb --path-separator=.:./ id.h parse.y > ../#{parse_y}"
|
134
|
+
else
|
135
|
+
cp "parse.y", "../#{parse_y}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
sh "rm -rf #{ruby_dir}"
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
file c_mri_txt => c_parse_y do
|
143
|
+
in_compare do
|
144
|
+
sh "bison -r all #{parse_y}"
|
145
|
+
sh "./normalize.rb parse#{v}.output > #{mri_txt}"
|
146
|
+
rm ["parse#{v}.output", "parse#{v}.tab.c"]
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
file rp_out => :parser
|
151
|
+
|
152
|
+
file c_rp_txt => rp_out do
|
153
|
+
in_compare do
|
154
|
+
sh "./normalize.rb ../#{rp_out} > #{rp_txt}"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
compare = "compare#{v}"
|
159
|
+
|
160
|
+
desc "Compare all grammars to MRI"
|
161
|
+
task :compare => compare
|
162
|
+
|
163
|
+
task c_diff => [c_mri_txt, c_rp_txt] do
|
164
|
+
in_compare do
|
165
|
+
system "diff -du #{mri_txt} #{rp_txt} > #{diff}"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
desc "Compare #{v} grammar to MRI #{version}"
|
170
|
+
task compare => c_diff do
|
171
|
+
in_compare do
|
172
|
+
system "wc -l #{diff}"
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
task :clean do
|
177
|
+
rm_f Dir[c_parse_y, c_mri_txt, c_rp_txt]
|
178
|
+
end
|
179
|
+
|
180
|
+
task :realclean do
|
181
|
+
rm_f Dir[tarball]
|
118
182
|
end
|
119
183
|
end
|
120
184
|
|
185
|
+
ruby_parse "1.8.7-p374"
|
186
|
+
ruby_parse "1.9.3-p551"
|
187
|
+
ruby_parse "2.0.0-p648"
|
188
|
+
ruby_parse "2.1.9"
|
189
|
+
ruby_parse "2.2.6"
|
190
|
+
ruby_parse "2.3.3"
|
191
|
+
# TODO ruby_parse "2.4.0"
|
192
|
+
|
121
193
|
task :debug => :isolate do
|
122
|
-
ENV["V"] ||=
|
194
|
+
ENV["V"] ||= V1_2.last
|
123
195
|
Rake.application[:parser].invoke # this way we can have DEBUG set
|
124
196
|
Rake.application[:lexer].invoke # this way we can have DEBUG set
|
125
197
|
|
@@ -127,22 +199,9 @@ task :debug => :isolate do
|
|
127
199
|
require "ruby_parser"
|
128
200
|
require "pp"
|
129
201
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
when "19" then
|
134
|
-
Ruby19Parser.new
|
135
|
-
when "20" then
|
136
|
-
Ruby20Parser.new
|
137
|
-
when "21" then
|
138
|
-
Ruby21Parser.new
|
139
|
-
when "22" then
|
140
|
-
Ruby22Parser.new
|
141
|
-
when "23" then
|
142
|
-
Ruby23Parser.new
|
143
|
-
else
|
144
|
-
raise "Unsupported version #{ENV["V"]}"
|
145
|
-
end
|
202
|
+
klass = Object.const_get("Ruby#{ENV["V"]}Parser") rescue nil
|
203
|
+
raise "Unsupported version #{ENV["V"]}" unless klass
|
204
|
+
parser = klass.new
|
146
205
|
|
147
206
|
time = (ENV["RP_TIMEOUT"] || 10).to_i
|
148
207
|
|
@@ -173,7 +232,7 @@ task :debug_ruby do
|
|
173
232
|
end
|
174
233
|
|
175
234
|
task :extract => :isolate do
|
176
|
-
ENV["V"] ||=
|
235
|
+
ENV["V"] ||= V1_2.last
|
177
236
|
Rake.application[:parser].invoke # this way we can have DEBUG set
|
178
237
|
|
179
238
|
file = ENV["F"] || ENV["FILE"]
|
@@ -0,0 +1,146 @@
|
|
1
|
+
#!/usr/bin/ruby -w
|
2
|
+
|
3
|
+
good = false
|
4
|
+
|
5
|
+
rules = Hash.new { |h,k| h[k] = [] }
|
6
|
+
rule = nil
|
7
|
+
order = []
|
8
|
+
|
9
|
+
def munge s
|
10
|
+
renames = [
|
11
|
+
"'='", "tEQL",
|
12
|
+
"'!'", "tBANG",
|
13
|
+
"'%'", "tPERCENT",
|
14
|
+
"'&'", "tAMPER2",
|
15
|
+
"'('", "tLPAREN2",
|
16
|
+
"')'", "tRPAREN",
|
17
|
+
"'*'", "tSTAR2",
|
18
|
+
"'+'", "tPLUS",
|
19
|
+
"','", "tCOMMA",
|
20
|
+
"'-'", "tMINUS",
|
21
|
+
"'.'", "tDOT",
|
22
|
+
"'/'", "tDIVIDE",
|
23
|
+
"';'", "tSEMI",
|
24
|
+
"':'", "tCOLON",
|
25
|
+
"'<'", "tLT",
|
26
|
+
"'>'", "tGT",
|
27
|
+
"'?'", "tEH",
|
28
|
+
"'['", "tLBRACK",
|
29
|
+
"'\\n'", "tNL",
|
30
|
+
"']'", "tRBRACK",
|
31
|
+
"'^'", "tCARET",
|
32
|
+
"'`'", "tBACK_REF2",
|
33
|
+
"'{'", "tLCURLY",
|
34
|
+
"'|'", "tPIPE",
|
35
|
+
"'}'", "tRCURLY",
|
36
|
+
"'~'", "tTILDE",
|
37
|
+
'"["', "tLBRACK",
|
38
|
+
|
39
|
+
# 2.0 changes?
|
40
|
+
'"<=>"', "tCMP",
|
41
|
+
'"=="', "tEQ",
|
42
|
+
'"==="', "tEQQ",
|
43
|
+
'"!~"', "tNMATCH",
|
44
|
+
'"=~"', "tMATCH",
|
45
|
+
'">="', "tGEQ",
|
46
|
+
'"<="', "tLEQ",
|
47
|
+
'"!="', "tNEQ",
|
48
|
+
'"<<"', "tLSHFT",
|
49
|
+
'">>"', "tRSHFT",
|
50
|
+
'"*"', "tSTAR",
|
51
|
+
|
52
|
+
'".."', "tDOT2",
|
53
|
+
|
54
|
+
'"&"', "tAMPER",
|
55
|
+
'"&&"', "tANDOP",
|
56
|
+
'"||"', "tOROP",
|
57
|
+
|
58
|
+
'"..."', "tDOT3",
|
59
|
+
'"**"', "tPOW",
|
60
|
+
'"unary+"', "tUPLUS",
|
61
|
+
'"unary-"', "tUMINUS",
|
62
|
+
'"[]"', "tAREF",
|
63
|
+
'"[]="', "tASET",
|
64
|
+
'"::"', "tCOLON2",
|
65
|
+
'"{ arg"', "tLBRACE_ARG",
|
66
|
+
'"( arg"', "tLPAREN_ARG",
|
67
|
+
'"("', "tLPAREN",
|
68
|
+
'rparen', "tRPAREN",
|
69
|
+
'"{"', "tLBRACE",
|
70
|
+
'"=>"', "tASSOC",
|
71
|
+
'"->"', "tLAMBDA",
|
72
|
+
'":: at EXPR_BEG"', "tCOLON3",
|
73
|
+
'"**arg"', "tDSTAR",
|
74
|
+
'","', "tCOMMA",
|
75
|
+
|
76
|
+
# other
|
77
|
+
|
78
|
+
'tLBRACK2', "tLBRACK", # HACK
|
79
|
+
|
80
|
+
"' '", "tSPACE", # needs to be later to avoid bad hits
|
81
|
+
|
82
|
+
"/* empty */", "none",
|
83
|
+
/^\s*$/, "none",
|
84
|
+
"keyword_BEGIN", "klBEGIN",
|
85
|
+
"keyword_END", "klEND",
|
86
|
+
/keyword_(\w+)/, proc { "k#{$1.upcase}" },
|
87
|
+
/\bk_([a-z_]+)/, proc { "k#{$1.upcase}" },
|
88
|
+
/modifier_(\w+)/, proc { "k#{$1.upcase}_MOD" },
|
89
|
+
"kVARIABLE", "keyword_variable", # ugh
|
90
|
+
|
91
|
+
/@(\d+)\s+/, "",
|
92
|
+
]
|
93
|
+
|
94
|
+
renames.each_slice(2) do |(a, b)|
|
95
|
+
if Proc === b then
|
96
|
+
s.gsub!(a, &b)
|
97
|
+
else
|
98
|
+
s.gsub!(a, b)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
s.strip
|
103
|
+
end
|
104
|
+
|
105
|
+
ARGF.each_line do |line|
|
106
|
+
next unless good or line =~ /^-* ?Grammar|\$accept : /
|
107
|
+
|
108
|
+
case line.strip
|
109
|
+
when /^$/ then
|
110
|
+
when /^(\d+) (\$?\w+): (.*)/ then # yacc
|
111
|
+
rule = $2
|
112
|
+
order << rule unless rules.has_key? rule
|
113
|
+
rules[rule] << munge($3)
|
114
|
+
when /^(\d+) \s+\| (.*)/ then # yacc
|
115
|
+
rules[rule] << munge($2)
|
116
|
+
when /^(\d+) (@\d+): (.*)/ then # yacc
|
117
|
+
rule = $2
|
118
|
+
order << rule unless rules.has_key? rule
|
119
|
+
rules[rule] << munge($3)
|
120
|
+
when /^rule (\d+) (@?\w+):(.*)/ then # racc
|
121
|
+
rule = $2
|
122
|
+
order << rule unless rules.has_key? rule
|
123
|
+
rules[rule] << munge($3)
|
124
|
+
when /\$accept/ then # byacc?
|
125
|
+
good = true
|
126
|
+
when /Grammar/ then # both
|
127
|
+
good = true
|
128
|
+
when /^-+ Symbols/ then # racc
|
129
|
+
break
|
130
|
+
when /^Terminals/ then # yacc
|
131
|
+
break
|
132
|
+
when /^\cL/ then # byacc
|
133
|
+
break
|
134
|
+
else
|
135
|
+
warn "unparsed: #{$.}: #{line.chomp}"
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
require 'yaml'
|
140
|
+
|
141
|
+
order.each do |k|
|
142
|
+
next if k =~ /@/
|
143
|
+
puts
|
144
|
+
puts "#{k}:"
|
145
|
+
puts rules[k].map { |r| " #{r}" }.join "\n"
|
146
|
+
end
|