depager 0.3.0.b20160729 → 0.3.0.b20250423

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.
Files changed (63) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +44 -0
  3. data/.simplecov +5 -0
  4. data/Gemfile +12 -0
  5. data/LICENSE.gpl +339 -0
  6. data/Manifest.txt +73 -0
  7. data/README.en +4 -3
  8. data/README.ja +4 -47
  9. data/Rakefile +31 -0
  10. data/bin/depager +3 -38
  11. data/examples/action_pl0d/pl0d.action.dr +4 -4
  12. data/examples/action_pl0d/test.pl0ds +2 -3
  13. data/examples/c89/c89.dr +4 -4
  14. data/examples/c89/test.c89 +1 -1
  15. data/examples/extension/astdf.rb +4 -5
  16. data/examples/extension/atree.dr +3 -3
  17. data/examples/extension/calc.atree.dr +4 -4
  18. data/examples/extension/calc.simple_action.dr +3 -3
  19. data/examples/extension/paction.dr +3 -3
  20. data/examples/extension/pactiontest.dr +3 -3
  21. data/examples/extension/simple_action.rb +26 -24
  22. data/examples/pl0d/pl0ds.dr +5 -5
  23. data/examples/pl0d/test.pl0ds +2 -2
  24. data/examples/rie_calc/calc.rie.dr +4 -4
  25. data/examples/rie_dcuse/dcuse.rie.dr +4 -4
  26. data/examples/rie_pl0/pl0.rie.dr +3 -3
  27. data/examples/slex_test/divreg.slex.dr +5 -5
  28. data/examples/slex_test/ljoin.slex.dr +5 -5
  29. data/examples/{sample_calc → tiny_calc}/calc.action.dr +4 -4
  30. data/examples/{sample_calc → tiny_calc}/calc.ast.action.dr +20 -9
  31. data/examples/{sample_calc → tiny_calc}/calc.ast.dr +19 -7
  32. data/examples/{sample_calc → tiny_calc}/calc.cst.dr +12 -7
  33. data/examples/{sample_calc → tiny_calc}/calc.dr +1 -1
  34. data/examples/{sample_calc → tiny_calc}/calc.lex.dr +2 -2
  35. data/examples/{sample_calc → tiny_calc}/calc_prec.action.dr +4 -4
  36. data/lib/depager/cli.rb +44 -0
  37. data/lib/depager/grammar.rb +72 -75
  38. data/lib/depager/lr.rb +169 -154
  39. data/lib/depager/parser.rb +90 -103
  40. data/lib/depager/plugins/_rie_debug.rb +63 -0
  41. data/lib/depager/plugins/action.rb +47 -0
  42. data/lib/depager/{ruby/plugins → plugins}/ast.dr +20 -17
  43. data/lib/depager/{ruby/plugins → plugins}/ast.rb +266 -304
  44. data/lib/depager/{ruby/plugins → plugins}/cst.dr +18 -16
  45. data/lib/depager/{ruby/plugins → plugins}/cst.rb +152 -148
  46. data/lib/depager/{ruby/plugins → plugins}/lex.dr +7 -7
  47. data/lib/depager/{ruby/plugins → plugins}/lex.rb +72 -69
  48. data/lib/depager/{ruby/plugins → plugins}/rie.dr +12 -10
  49. data/lib/depager/{ruby/plugins → plugins}/rie.rb +224 -263
  50. data/lib/depager/{ruby/plugins → plugins}/slex.dr +13 -14
  51. data/lib/depager/{ruby/plugins → plugins}/slex.rb +183 -194
  52. data/lib/depager/plugins/srp.rb +46 -0
  53. data/lib/depager/ruby/templates/extension_lalr_master.erb +6 -12
  54. data/lib/depager/ruby/templates/extension_lalr_slave.erb +31 -17
  55. data/lib/depager/ruby/templates/single_lalr_parser.erb +35 -26
  56. data/lib/depager/utils.rb +56 -46
  57. data/lib/depager/version.rb +1 -2
  58. data/lib/depager.rb +166 -176
  59. metadata +38 -33
  60. data/lib/depager/ruby/plugins/_rie_debug.rb +0 -35
  61. data/lib/depager/ruby/plugins/action.rb +0 -53
  62. data/lib/depager/ruby/plugins/srp.rb +0 -56
  63. /data/examples/{sample_calc → tiny_calc}/test.calc +0 -0
data/lib/depager.rb CHANGED
@@ -1,17 +1,16 @@
1
- # -*- coding: utf-8 -*-
2
- require 'erb'
3
- require "depager/parser.rb"
4
- require "depager/grammar.rb"
5
- require "depager/utils.rb"
1
+ require "erb"
2
+ require "depager/parser"
3
+ require "depager/grammar"
4
+ require "depager/utils"
6
5
 
7
6
  module Depager
8
7
  def self.configuration
9
- @flags ||= {}
8
+ @configuration ||= {}
10
9
  end
11
10
 
12
- def self.debug_mode? flag = ''
11
+ def self.debug_mode?(flag = "")
13
12
  value = configuration[:debug] or return false
14
- !! value.match(/#{flag.to_s}/)
13
+ !!value.match(/#{flag}/)
15
14
  end
16
15
 
17
16
  def self.verbose_mode?
@@ -28,21 +27,21 @@ module Depager
28
27
  @g_parser = GrammarPartParser.new(self)
29
28
 
30
29
  until file.eof?
31
- case line = file.gets
30
+ case file.gets
32
31
  when /^\s*(#.*)?$/
33
- #skip space and comment.
32
+ # skip space and comment.
34
33
  when /^%class\s+(\S+)(\s+based_on\s+(\S+)(\s+\(\s*'(.+)'\s*\))?)?\s*$/
35
34
  @target_name = $1
36
35
  if $2
37
36
  require $5 if $5
38
- nesting = $3.split(/::/).tap{|it| it[-1] = "#{it[-1]}Generator"}
39
- generator_class = nesting.inject(Object){|c,name| c.const_get(name) }
37
+ nesting = $3.split("::").tap { |it| it[-1] = "#{it[-1]}Generator" }
38
+ generator_class = nesting.inject(Object) { |c, name| c.const_get(name) }
40
39
  else
41
- require 'depager/lr.rb'
40
+ require "depager/lr"
42
41
  generator_class = LALR::ParserGenerator
43
42
  end
44
43
 
45
- if @target_name.match('(.+)::([^:]+)')
44
+ if @target_name =~ /(.+)::([^:]+)/
46
45
  @target_namespace = $1
47
46
  @target_name = $2
48
47
  else
@@ -52,10 +51,10 @@ module Depager
52
51
  @generator = generator_class.new(self)
53
52
  break
54
53
  when /^%defext\s+(\S+)\s*$/
55
- require 'depager/lr.rb'
54
+ require "depager/lr"
56
55
 
57
56
  @target_namespace = $1
58
- @target_name = 'Master'
57
+ @target_name = "Master"
59
58
 
60
59
  @generator = LALR::ExtensionGenerator.new(self)
61
60
  break
@@ -76,36 +75,34 @@ module Depager
76
75
 
77
76
  Token = Struct.new(:tag, :value, :name, :lineno)
78
77
 
79
- HOOK_KEYS = [
80
- :pre_rule_list, :post_rule_list,
81
- :pre_rule, :post_rule,
82
- :post_lhs,
83
- :post_rhs_list, :pre_rhs_list,
84
- :pre_rhs, :post_rhs,
85
- :post_symbol
86
- ] #:nodoc:
87
-
88
- attr_accessor :rules, :terms, :nonterms, :precs, :table
89
- attr_accessor :lhs, :rhs, :nrhs, :rhs_names, :nrules
90
- attr_accessor :line, :original_line, :old_line, :token
91
- attr_accessor :outer_code, :inner_code, :mixins
78
+ HOOK_KEYS = %i[
79
+ pre_rule_list post_rule_list
80
+ pre_rule post_rule
81
+ post_lhs
82
+ post_rhs_list pre_rhs_list
83
+ pre_rhs post_rhs
84
+ post_symbol
85
+ ].freeze # :nodoc:
86
+
87
+ attr_accessor :rules, :terms, :nonterms, :precs, :table, :lhs, :rhs, :nrhs, :rhs_names, :nrules, :line,
88
+ :original_line, :old_line, :token, :outer_code, :inner_code, :mixins
92
89
  attr_reader :d_parser, :target_namespace, :target_name, :hooks
93
90
 
94
- def initialize d_parser
91
+ def initialize(d_parser)
95
92
  @d_parser = d_parser
96
93
  end
97
94
 
98
95
  # parse and make LALR(1) table
99
96
  def parse(full_target_name, precs = [], extensions = [], options = {})
100
- @original_line = @old_line = @line = ''
101
- @inner_code = ''
102
- @outer_code = ''
97
+ @original_line = @old_line = @line = ""
98
+ @inner_code = ""
99
+ @outer_code = ""
103
100
 
104
101
  full_target_name.match(/::([^:]+)$/) or raise
105
102
  @target_namespace = $`
106
103
  @target_name = $1
107
104
 
108
- extend_paser(extensions, options)
105
+ extend_parser(extensions, options)
109
106
  init_grammar
110
107
  parse_grammar
111
108
  check_grammar
@@ -114,20 +111,20 @@ module Depager
114
111
  grammar = d_parser.parsing_method::Grammar.new(@rules, @terms, @nonterms, @precs)
115
112
  @table = d_parser.parsing_method::Table.new(grammar)
116
113
  @table.check_table d_parser
117
- @extensions.each{|o| o.send :term_extension }
114
+ @extensions.each { |o| o.send :term_extension }
118
115
  @table
119
116
  end
120
117
 
121
- def hook_name? s
118
+ def hook_name?(s)
122
119
  HOOK_KEYS.include? s.to_sym
123
120
  end
124
121
 
125
- def update_context line
122
+ def update_context(line)
126
123
  @line = line
127
- get_token
124
+ scan_token
128
125
  end
129
126
 
130
- def int_to_sym n
127
+ def int_to_sym(n)
131
128
  @int_to_sym[n]
132
129
  end
133
130
 
@@ -135,116 +132,114 @@ module Depager
135
132
  int_to_sym(lhs)
136
133
  end
137
134
 
138
- def add_nonterm sym
135
+ def add_nonterm(sym)
139
136
  sym = sym.to_s.intern
140
137
  isym = @nonterms[sym] = @nonterms.size
141
138
  @int_to_sym[isym] = sym
142
- return isym
139
+ isym
143
140
  end
144
141
 
145
- def add_rule lhs, rhs, prec = nil, rhs_names = nil
142
+ def add_rule(lhs, rhs, prec = nil, rhs_names = nil)
146
143
  @lhs_syms[lhs] = true
147
- rule = @parsing_method::Rule[lhs, rhs, prec, rhs_names]
144
+ rule = d_parser.parsing_method::Rule[lhs, rhs, prec, rhs_names]
148
145
  @rules.push rule
149
- return rule
146
+ rule
150
147
  end
151
148
 
152
- def name_to_rhs_index name
149
+ def name_to_rhs_index(name)
153
150
  @rhs_names.index(name)
154
151
  end
155
152
 
156
- def insert_sym_to_rhs pos, token_value, token_name
153
+ def insert_sym_to_rhs(pos, token_value, token_name)
157
154
  if pos < 0
158
155
  @rhs.push token_value
159
156
  @rhs_names[@rhs.size - 1] = token_name
160
- @rhs_syms[token_value] = true
161
157
  else
162
158
  @rhs.insert(pos, token_value)
163
159
  @rhs_names.insert(pos, token_name)
164
- @rhs_syms[token_value] = true
165
160
  end
161
+ @rhs_syms[token_value] = true
166
162
  end
167
163
 
168
164
  private
165
+
169
166
  def parse_grammar
170
- get_token
167
+ scan_token
171
168
  do_hook :pre_rule_list
172
169
  parse_rulelist
173
170
  do_hook :post_rule_list
174
- unless @token.tag == nil
175
- error_exit "syntax error(grammar). unexpected '#{@token.tag}' expect '%%'"
176
- end
171
+ return if @token.tag.nil?
172
+
173
+ error_exit "syntax error(grammar). unexpected '#{@token.tag}' expect '%%'"
177
174
  end
178
175
 
179
176
  def parse_rulelist
180
177
  do_hook :pre_rule
181
178
  parse_rule
182
179
  do_hook :post_rule
183
- if @token.tag == :NT
184
- parse_rulelist
185
- end
180
+ return unless @token.tag == :NT
181
+
182
+ parse_rulelist
186
183
  end
187
184
 
188
185
  def parse_rule
189
- if @token[0] == :NT
190
- @lhs = @token.value
186
+ return unless @token[0] == :NT
191
187
 
192
- get_token
193
- do_hook :post_lhs
188
+ @lhs = @token.value
194
189
 
195
- unless @token.tag == ':'
196
- error_exit "syntax error(grammar). unexpected '#{@token.tag}' expecting ':'"
197
- end
198
- get_token
190
+ scan_token
191
+ do_hook :post_lhs
199
192
 
200
- @nrhs = 0
201
- do_hook :pre_rhs_list
202
- parse_rhslist
203
- do_hook :post_rhs_list
193
+ error_exit "syntax error(grammar). unexpected '#{@token.tag}' expecting ':'" unless @token.tag == ":"
194
+ scan_token
204
195
 
205
- unless @token.tag == ';'
206
- error_exit "syntax error(grammar). unexpected '#{@token.tag}' expecting ';'"
207
- end
208
- get_token
209
- end
196
+ @nrhs = 0
197
+ do_hook :pre_rhs_list
198
+ parse_rhslist
199
+ do_hook :post_rhs_list
200
+
201
+ error_exit "syntax error(grammar). unexpected '#{@token.tag}' expecting ';'" unless @token.tag == ";"
202
+ scan_token
210
203
  end
211
204
 
212
205
  def parse_rhslist
213
- @rhs = []; @rhs_names = []; @prec = nil
206
+ @rhs = []
207
+ @rhs_names = []
208
+ @prec = nil
214
209
  do_hook :pre_rhs
215
210
  parse_syms
216
211
  add_rule(@lhs, @rhs, @prec, @rhs_names)
217
212
  do_hook :post_rhs
218
213
  @nrhs += 1
219
214
 
220
- if @token.tag == '|'
221
- get_token
222
- parse_rhslist
223
- end
215
+ return unless @token.tag == "|"
216
+
217
+ scan_token
218
+ parse_rhslist
224
219
  end
225
220
 
226
221
  def parse_syms
227
- if @token.tag == :NT || @token.tag == :T
228
- insert_sym_to_rhs(-1, @token.value, @token.name)
229
- get_token
222
+ return unless @token.tag == :NT || @token.tag == :T
230
223
 
231
- do_hook :post_symbol
232
- parse_syms
233
- end
224
+ insert_sym_to_rhs(-1, @token.value, @token.name)
225
+ scan_token
226
+
227
+ do_hook :post_symbol
228
+ parse_syms
234
229
  end
235
230
 
236
- def make_token tag, value, name = nil
231
+ def make_token(tag, value, name = nil)
237
232
  @token = Token.new(tag, value, name, file.lineno)
238
233
  end
239
234
 
240
- def get_token
235
+ def scan_token
241
236
  while !@line.empty? || !file.eof?
242
237
  @original_line = @old_line = @line = file.gets if @line.empty?
243
238
 
244
239
  tag = s = name = val = nil
245
- until @line.empty? do
240
+ until @line.empty?
246
241
  case @line
247
- when /^\s+/, /^\#.*/ ;
242
+ when /^\s+/, /^\#.*/
248
243
  # skip
249
244
  when /^=([a-zA-Z]+)/
250
245
  @prec = s = $1.intern
@@ -252,17 +247,17 @@ module Depager
252
247
  when /^([a-z][a-z0-9_]*)(-([a-z][_a-z0-9]*))?/
253
248
  tag = :NT
254
249
  s = $1.intern
255
- name = $3 ? $3 : $1
250
+ name = $3 || $1
256
251
  val = @nonterms[s] ||= @nonterms.size
257
252
  when /^([A-Z][A-Z0-9_]*)(-([a-z][_a-z0-9]*))?/
258
253
  tag = :T
259
254
  s = $1.intern
260
- name = $3 ? $3 : $1
261
- val = @terms[s] ||= - (@terms.size + 1)
255
+ name = $3 || $1
256
+ val = @terms[s] ||= - (@terms.size + 1)
262
257
  when /^'(.+?)'/
263
258
  tag = :T
264
259
  name = s = $1
265
- val = @terms[s] ||= - (@terms.size + 1)
260
+ val = @terms[s] ||= - (@terms.size + 1)
266
261
  when /^%%/
267
262
  return make_token(nil, nil)
268
263
  when /^([:;|])/
@@ -271,32 +266,31 @@ module Depager
271
266
  else
272
267
  return make_token(:UNKNOWN, @line[0].chr)
273
268
  end
274
- @old_line, @line = @line, $'
269
+ @old_line = @line
270
+ @line = $'
275
271
  @int_to_sym[val] ||= s if val && s
276
272
  return make_token(tag, val, name) if tag
277
273
  end
278
274
  end
279
- return make_token(nil, nil)
275
+ make_token(nil, nil)
280
276
  end
281
277
 
282
- def extend_paser extensions, options
278
+ def extend_parser(extensions, options)
283
279
  init_hook
284
280
  @extensions = []
285
281
  extensions.each do |f, m|
286
- if f && f.match(%r!^\./!)
282
+ if f&.match(%r{^\./})
287
283
  require File.expand_path(f, File.dirname(file.path))
288
284
  elsif f
289
285
  require f
290
286
  end
291
287
 
292
- nesting = m.split(/::/).tap{|it| it[-1] = "#{it[-1]}Extension"}
293
- extension = nesting.inject(Object){|c,name| c.const_get(name) }.new
294
- options[m] and options[m].each do |k, v|
295
- begin
296
- e.send("#{k}=", v)
297
- rescue NoMethodError
298
- warning "no such a option '#{m}.#{k}'."
299
- end
288
+ nesting = m.split("::").tap { |it| it[-1] = "#{it[-1]}Extension" }
289
+ extension = nesting.inject(Object) { |c, name| c.const_get(name) }.new
290
+ options[m]&.each do |k, v|
291
+ extension.send(:"#{k}=", v)
292
+ rescue NoMethodError
293
+ warning "no such a option '#{m}.#{k}'."
300
294
  end
301
295
  @extensions << extension
302
296
  extension.extension_registered self
@@ -305,17 +299,17 @@ module Depager
305
299
  end
306
300
 
307
301
  def init_grammar
308
- @rules = [ d_parser.parsing_method::Rule[0 , [1]]]
302
+ @rules = [d_parser.parsing_method::Rule[0, [1]]]
309
303
  @terms = { nil => -1, false => -2 }
310
- @nonterms = { '$start' => 0 }
304
+ @nonterms = { "$start" => 0 }
311
305
  @int_to_sym = {}
312
306
  @rhs_syms = {}
313
307
  @lhs_syms = {}
314
308
  end
315
309
 
316
- def make_grammar precs
310
+ def make_grammar(precs)
317
311
  ts = @nonterms.size - 1
318
- @terms.each{|k,v| @terms[k] = ts - v}
312
+ @terms.each { |k, v| @terms[k] = ts - v }
319
313
 
320
314
  @precs = {}
321
315
  precs.each_with_index do |p, x|
@@ -328,19 +322,19 @@ module Depager
328
322
  end
329
323
  end
330
324
  @rules.each do |rule|
331
- rule.rhs.each_with_index{|i, x| rule.rhs[x] = ts - i if i < 0}
325
+ rule.rhs.each_with_index { |i, x| rule.rhs[x] = ts - i if i < 0 }
332
326
  rule.prec &&= @precs[@terms[rule.prec]]
333
327
  end
334
328
  end
335
329
 
336
330
  def check_grammar
337
331
  lhs_warns = []
338
- @lhs_syms.each do |s, _|
339
- lhs_warns << s if s != 1 and !@rhs_syms[s]
332
+ @lhs_syms.each_key do |s|
333
+ lhs_warns << s if (s != 1) && !@rhs_syms[s]
340
334
  end
341
335
  rhs_warns = []
342
- @rhs_syms.each do |s, _|
343
- rhs_warns << s if s > 0 and !@lhs_syms[s]
336
+ @rhs_syms.each_key do |s|
337
+ rhs_warns << s if (s > 0) && !@lhs_syms[s]
344
338
  end
345
339
  lhs_warns.uniq.each do |s|
346
340
  warning "the lhs '#{@int_to_sym[s]}' is not used"
@@ -351,24 +345,25 @@ module Depager
351
345
  end
352
346
 
353
347
  def init_hook
354
- @hooks = HOOK_KEYS.inject({}){|r, i| r[i] = []; r }
348
+ @hooks = HOOK_KEYS.each_with_object({}) do |i, r|
349
+ r[i] = []
350
+ end
355
351
  end
356
352
 
357
- def do_hook hook
358
- @hooks[hook].each{|o, m| o.send m}
353
+ def do_hook(hook)
354
+ @hooks[hook].each { |o, m| o.send m }
359
355
  end
360
356
  end
361
357
 
362
358
  class Generator
363
359
  include Depager::Utils::CommonMethods
364
360
 
365
- TEMPLATES_DIR = File.expand_path('../depager/ruby/templates', __FILE__)
361
+ TEMPLATES_DIR = File.expand_path("depager/ruby/templates", __dir__)
366
362
 
367
363
  attr_reader :d_parser, :g_parser, :parsing_method
368
- attr_accessor :outer_code, :inner_code
369
- attr_accessor :decorators, :requirements, :options
364
+ attr_accessor :outer_code, :inner_code, :setup_code, :decorators, :requirements, :options
370
365
 
371
- def initialize d_parser
366
+ def initialize(d_parser)
372
367
  @d_parser = d_parser
373
368
  @g_parser = d_parser.g_parser
374
369
  @parsing_method = nil
@@ -377,14 +372,15 @@ module Depager
377
372
  @decorators = []
378
373
  @requirements = []
379
374
  @extensions = []
380
- @inner_code = ''
381
- @outer_code = ''
375
+ @inner_code = ""
376
+ @outer_code = ""
377
+ @setup_code = ""
382
378
  @precs = []
383
379
  @mixins = []
384
380
  end
385
381
 
386
- def generate_code template
387
- ERB.new(template || '', nil, '-').result(binding)
382
+ def generate_code(template)
383
+ ERB.new(template || "", trim_mode: "-").result(binding)
388
384
  end
389
385
 
390
386
  def parse_prec
@@ -395,7 +391,7 @@ module Depager
395
391
  # skip
396
392
  when /^\s*(left|right|nonassoc)\s+(.*)$/
397
393
  dir = $1.upcase.intern
398
- syms = $2.split.map{|i| (i =~ /'(.+?)'/) ? $1 : i.intern}
394
+ syms = $2.split.map { |i| i =~ /'(.+?)'/ ? $1 : i.intern }
399
395
  precs.push [dir, syms]
400
396
  when /^%\}\s*$/
401
397
  break
@@ -403,38 +399,41 @@ module Depager
403
399
  error_exit "syntax error(prec).\n> #{line}"
404
400
  end
405
401
  end
406
- return precs
402
+ precs
407
403
  end
408
404
 
409
- def parse_block raw = false
410
- lineno, val = self.file.lineno, ''
405
+ def parse_block(raw: false)
406
+ lineno = file.lineno
407
+ val = ""
411
408
  until file.eof?
412
409
  line = file.gets
413
- break if line =~ /^%\}/
410
+ break if /^%\}/.match?(line)
411
+
414
412
  val.concat line
415
413
  end
416
414
  return val if raw
417
415
 
418
- delimiter = Depager.configuration[:expanded_code_delimiter] ||
419
- ".,.,#{Time.now.to_i}#{rand(0xffff)}.,.,"
420
- return "module_eval <<'#{delimiter}', '#{file.path}', #{lineno + 1}\n" <<
421
- "#{val.gsub('\\', '\\\\')}\n" <<
422
- "#{delimiter}\n"
416
+ delimiter = expanded_code_delimiter
417
+ <<~EXPANDED_CODE
418
+ module_eval <<'#{delimiter}', '#{file.path}', #{lineno + 1}
419
+ #{val}
420
+ #{delimiter}
421
+ EXPANDED_CODE
423
422
  end
424
423
 
425
- def parse_common line
424
+ def parse_common(line)
426
425
  case line
427
426
  when /^\s*(#.*)?$/
428
- #skip space and comment.
427
+ # skip space and comment.
429
428
  when /^%decorate\s+(.*?)\s*\((.*)\)\s*$/
430
429
  @decorators.push $1
431
430
  @requirements.push $2
432
431
  when /^%decorate\s+(.*?)\s*$/
433
432
  @decorators.push $1
434
433
  when /^%extend\s+(.*?)\s*\(\s*'(.*)'\s*\)\s*$/
435
- @extensions.push [$2.strip, $1] unless @extensions.find{|i| i[1] == $1}
436
- when /^%option\s+(\w+).(\w+)\s+(.*)\s*$/
437
- if $1 == 'Generator'
434
+ @extensions.push [$2.strip, $1] unless @extensions.find { |i| i[1] == $1 }
435
+ when /^%option\s+([\w:]+).(\w+)\s+(.*)\s*$/
436
+ if $1 == "Generator"
438
437
  Depager.configuration[$2.to_sym] = $3
439
438
  else
440
439
  @options[$1] ||= []
@@ -451,6 +450,9 @@ module Depager
451
450
  @precs = parse_prec
452
451
  when /^%expanded_code_delimiter\s+(\S+)\s*$/
453
452
  Depager.configuration[:expanded_code_delimiter] = $1
453
+ when /^%abort_behavior\s+(pending\s+)?(.*)$/
454
+ @inner_code << " def do_abort_driver; end\n" if $1
455
+ @inner_code << " def abort_driver; #{$2}; end\n" unless $2.strip.empty?
454
456
  else
455
457
  warning "syntax error(declaration).\n> #{line}"
456
458
  end
@@ -458,63 +460,62 @@ module Depager
458
460
  end
459
461
 
460
462
  class ParserGenerator < Generator
461
- def initialize d_parser
462
- super
463
- end
464
-
465
463
  def parse
466
464
  until file.eof?
467
465
  line = file.gets
468
466
  case line
469
467
  when /^%%\s*$/
470
468
  g_parser.parse(@d_parser.full_target_name, @precs, @extensions, @options)
471
- @outer_code << parse_block(true)
469
+ @outer_code << parse_block(raw: true)
472
470
  return generate_code parser_code_template
471
+ when /^%setup((\s*{\s*)|(\s.*))$/
472
+ @setup_code << ($2 ? parse_block : $3.lstrip)
473
473
  else
474
474
  parse_common(line)
475
475
  end
476
476
  end
477
- return nil
477
+ nil
478
478
  end
479
479
 
480
- def parser_code_template
481
- end
480
+ def parser_code_template; end
482
481
  end
483
482
 
484
483
  class ExtensionGenerator < Generator
485
484
  attr_accessor :slaves
486
- def initialize d_parser
485
+
486
+ def initialize(d_parser)
487
487
  super
488
- @slaves = { }
488
+ @slaves = {}
489
489
  end
490
490
 
491
491
  def parse
492
492
  until file.eof?
493
493
  line = file.gets
494
494
  case line
495
- when /^%hook\s+([\w \t]+?)(\/((?:[^\/\\]+|\\.)+)\/(\s+skip)?)?\s*$/
496
- hooks = $1.split(' ')
497
- @banner = hooks.join(',')
495
+ when %r{^%hook\s+([\w \t]+?)(/((?:[^/\\]+|\\.)+)/(\s+skip)?)?\s*$}
496
+ hooks = $1.split
497
+ @banner = hooks.join(",")
498
498
  @do_parse_re = $3
499
499
  @do_parse_skip = $4
500
500
 
501
- target_name = "#{d_parser.target_namespace}::Slave_#{ hooks.join('__') }::Parser"
502
- hooks.each do |i| i = i.to_sym
501
+ parts = hooks.map do |i|
503
502
  error_exit "Unknown hook: #{i}" unless g_parser.hook_name? i
504
- @slaves[i] = target_name
503
+ i.split("_").map(&:capitalize).join
505
504
  end
505
+ target_name = "#{d_parser.target_namespace}::#{parts.join}#{slaves.size}::Parser"
506
+ @slaves[target_name] = hooks
506
507
  @outer_code << parse_hook(target_name)
507
508
  when /^%%\s*$/
508
- @outer_code << parse_block(true)
509
+ @outer_code << parse_block(raw: true)
509
510
  else
510
511
  parse_common(line)
511
512
  end
512
513
  end
513
- return generate_code master_code_template
514
+ generate_code master_code_template
514
515
  end
515
516
 
516
- def parse_hook target_name
517
- inner = ''
517
+ def parse_hook(target_name)
518
+ inner = ""
518
519
  precs = []
519
520
  @slave_mixins = @mixins.dup
520
521
  until file.eof?
@@ -539,11 +540,9 @@ module Depager
539
540
  end
540
541
  end
541
542
 
542
- def slave_code_template
543
- end
543
+ def slave_code_template; end
544
544
 
545
- def master_code_template
546
- end
545
+ def master_code_template; end
547
546
  end
548
547
 
549
548
  class Extension
@@ -552,31 +551,22 @@ module Depager
552
551
 
553
552
  attr_reader :d_parser, :g_parser
554
553
 
555
- def init_extension
556
- end
554
+ def init_extension; end
557
555
 
558
- def term_extension
559
- end
556
+ def term_extension; end
560
557
 
561
- def extension_registered g_parser
558
+ def extension_registered(g_parser)
562
559
  @g_parser = g_parser
563
560
  @d_parser = g_parser.d_parser
564
561
 
565
- self.methods.sort.each do |m|
562
+ methods.sort.each do |m|
566
563
  m = m.to_sym
567
564
  g_parser.hooks[m].push [self, m] if g_parser.hook_name? m
568
565
  end
569
566
  end
570
567
 
571
568
  def decorator_name
572
- self.class.name.split('::').last.sub(/Extension$/, '')
569
+ self.class.name.split("::").last.sub(/Extension$/, "")
573
570
  end
574
571
  end
575
572
  end
576
-
577
- class String
578
- def unindent
579
- indent = match(/\n(\s+)/) ? $1 : ''
580
- gsub(/^#{indent}/m, '')
581
- end
582
- end