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
@@ -1,12 +1,17 @@
1
- # -*- coding: utf-8 -*-
2
- lib = File.expand_path("../ruby", __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
1
+ require "forwardable"
4
2
 
5
3
  module Depager
4
+ def self.path_of(io)
5
+ return "-" if io == $stdin
6
+ return "<#{io.class}>" unless io.respond_to?(:path) # StringIO
7
+
8
+ io.path
9
+ end
10
+
6
11
  class Token
7
12
  attr_accessor :value, :lineno, :filename
8
13
 
9
- def initialize value, lineno=nil, filename=nil
14
+ def initialize(value, lineno = nil, filename = nil)
10
15
  @value = value
11
16
  @lineno = lineno
12
17
  @filename = filename
@@ -33,23 +38,7 @@ module Depager
33
38
  class Parser
34
39
  ACC = 0x03ffffff
35
40
 
36
- attr_reader :action_table, :defred_table, :defred_after_shift_table
37
- attr_reader :goto_table, :reduce_table
38
- attr_reader :int_to_term, :term_to_int, :nonterm_to_int, :int_to_nonterm
39
-
40
- def initialize
41
- @reduce_table,
42
- @action_table,
43
- @defred_table,
44
- @defred_after_shift_table,
45
- @goto_table,
46
- @term_to_int,
47
- @int_to_term,
48
- @nonterm_to_int,
49
- @int_to_nonterm = basis.class::Tables
50
- end
51
-
52
- def parse f, line = ''
41
+ def parse(f, line = "")
53
42
  basis.__send__ :internal_initialize, f, line, [0, nil]
54
43
 
55
44
  do_hook :before_parse
@@ -62,52 +51,42 @@ module Depager
62
51
  stack[1][2..basis.parser_size]
63
52
  end
64
53
 
65
- def accept
66
- end
54
+ def lex; end
55
+ def accept; end
56
+ def error; end
57
+ def shift; end
58
+ def reduce; end
67
59
 
68
- def error
69
- end
70
-
71
- def shift
72
- end
73
-
74
- def reduce
75
- end
76
-
77
- def stack
78
- basis.stack
79
- end
80
-
81
- def lookahead
82
- basis.lookahead
83
- end
84
-
85
- def action_value
86
- basis.action_value
87
- end
60
+ def reduce_table; end
61
+ def action_table; end
62
+ def defred_table; end
63
+ def defred_after_shift_table; end
64
+ def goto_table; end
65
+ def term_to_int; end
66
+ def int_to_term; end
67
+ def nonterm_to_int; end
68
+ def int_to_nonterm; end
88
69
 
89
70
  protected
90
- def lex &block
91
- basis.lex &block
92
- end
93
71
 
94
72
  def driver
95
- while true
73
+ loop do
96
74
  basis.action_value = action_table[stack.last][lookahead[0]] || defred_table[stack.last]
97
75
 
98
- if action_value == nil
76
+ if action_value.nil?
99
77
  error
100
- exit 1
78
+ basis.do_abort_driver
101
79
  elsif action_value == ACC
102
- if int_to_term[lookahead[0]] == nil
80
+ if int_to_term[lookahead[0]].nil?
103
81
  accept
82
+ return true
104
83
  else
105
84
  error
85
+ basis.do_abort_driver
106
86
  end
107
- return true
108
87
  elsif action_value > 0
109
88
  shift
110
- while v = defred_after_shift_table[stack.last]
89
+ while (v = defred_after_shift_table[stack.last])
111
90
  basis.action_value = v
112
91
  reduce
113
92
  end
@@ -118,10 +97,10 @@ module Depager
118
97
  end
119
98
  end
120
99
 
121
- def do_hook hook
100
+ def do_hook(hook)
122
101
  if @basis == self
123
102
  send hook
124
- elsif hook.to_s.match(/^before_/)
103
+ elsif /^before_/.match?(hook.to_s)
125
104
  send hook
126
105
  @inside.do_hook hook
127
106
  else
@@ -131,45 +110,47 @@ module Depager
131
110
  end
132
111
 
133
112
  private
134
- def before_parse
135
- end
136
113
 
137
- def after_parse
138
- end
114
+ def before_parse; end
115
+ def after_parse; end
139
116
  end
140
117
 
141
118
  class Basis < Parser
142
- attr_reader :basis, :file, :line, :parser_size
119
+ attr_reader :basis, :file, :line, :parser_size
143
120
  attr_accessor :lookahead, :action_value, :stack
144
121
 
145
122
  def initialize
123
+ super
124
+
146
125
  @basis = self
147
126
  @parser_size = 1
148
- super()
149
127
  end
150
128
 
151
129
  def banner
152
130
  self.class.name
153
131
  end
154
132
 
155
- def get_decorator_index
133
+ def next_decorator_index
156
134
  @parser_size += 1
157
135
  end
158
136
 
159
- def accept
160
- end
137
+ def accept; end
161
138
 
162
139
  def error
163
- path = file.respond_to?(:path) ? file.path : '-'
140
+ path = Depager.path_of(file)
164
141
  exp = []
165
142
  action_table[stack.last].each_with_index do |i, x|
166
143
  exp << int_to_term[x] if i
167
144
  end
168
- la = lookahead[1].value rescue lookahead[1]
145
+ la = begin
146
+ lookahead[1].value
147
+ rescue StandardError
148
+ lookahead[1]
149
+ end
169
150
  la = (int_to_term[lookahead[0]] || la).inspect
170
- exp = exp.map{|i| i ? i.inspect : '$' }.join(', ')
151
+ exp = exp.map { |i| i ? i.inspect : "$" }.join(", ")
171
152
  warn "#{path}:#{file.lineno}: syntax error(#{banner}), unexpected #{la}, expecting #{exp}."
172
- warn @stack.pretty_inspect if Depager.debug_mode?
153
+ warn @stack.pretty_inspect if Depager.respond_to?(:debug_mode?) && Depager.debug_mode?
173
154
  end
174
155
 
175
156
  def shift
@@ -178,31 +159,50 @@ module Depager
178
159
 
179
160
  def reduce
180
161
  r, x = reduce_table[-action_value]
181
- (x * 2).times{ stack.pop }
162
+ (x * 2).times { stack.pop }
182
163
  v = goto_table[stack.last][r]
183
164
  stack << [r, :NT] << v
184
165
  end
185
166
 
167
+ def do_abort_driver
168
+ abort_driver
169
+ end
170
+
171
+ def abort_driver
172
+ exit 1
173
+ end
174
+
186
175
  private
187
- def internal_initialize file, line, lookahead
188
- @stack, @action_value, @file, @line, @lookahead =
189
- [0], nil, file, line, lookahead
176
+
177
+ def internal_initialize(file, line, lookahead)
178
+ @stack = [0]
179
+ @action_value = nil
180
+ @file = file
181
+ @line = line
182
+ @lookahead = lookahead
190
183
  end
191
184
 
192
- def token sym, value = nil, lineno = nil
185
+ def token(sym, value = nil, lineno = nil)
193
186
  lineno ||= file.lineno
194
- path = file.respond_to?(:path) ? file.path : '-'
195
- return sym, Depager::Token.new(value, lineno, path)
187
+ path = file.respond_to?(:path) ? file.path : "-"
188
+ [sym, Depager::Token.new(value, lineno, path)]
196
189
  end
197
190
  end
198
191
 
199
192
  class AdvancedParser < Parser
193
+ extend Forwardable
194
+ delegate %i[
195
+ lookahead action_value stack lex abort_driver
196
+ reduce_table action_table defred_table defred_after_shift_table goto_table
197
+ term_to_int int_to_term nonterm_to_int int_to_nonterm
198
+ ] => :@basis
199
+
200
200
  attr_reader :basis, :decorator_index
201
201
 
202
- def initialize inside
202
+ def initialize(inside)
203
203
  @inside = inside
204
204
  @basis = inside.basis
205
- @decorator_index = @basis.get_decorator_index
205
+ @decorator_index = @basis.next_decorator_index
206
206
  super()
207
207
  end
208
208
 
@@ -231,49 +231,36 @@ module Depager
231
231
  end
232
232
 
233
233
  private
234
- def before_accept
235
- end
236
234
 
237
- def after_accept
238
- end
239
-
240
- def before_error
241
- end
242
-
243
- def after_error
244
- end
245
-
246
- def before_shift
247
- end
248
-
249
- def after_shift
250
- end
251
-
252
- def before_reduce
253
- end
254
-
255
- def after_reduce
256
- end
235
+ def before_accept; end
236
+ def after_accept; end
237
+ def before_error; end
238
+ def after_error; end
239
+ def before_shift; end
240
+ def after_shift; end
241
+ def before_reduce; end
242
+ def after_reduce; end
257
243
  end
258
244
 
259
245
  class Action < AdvancedParser
260
- def initialize inside
261
- super inside
246
+ def on_reduce; end
247
+
248
+ def initialize(inside)
249
+ super
262
250
  @_arguments = []
263
- @on_reduce, = self.class::Tables
264
251
  end
265
252
 
266
253
  def before_reduce
267
254
  @_arguments = []
268
255
  n = reduce_table[-action_value][1]
269
256
  n.times do |i|
270
- v = stack[stack.size - 2 * (i + 1)]
257
+ v = stack[stack.size - (2 * (i + 1))]
271
258
  @_arguments[n - i - 1] = v[1] == :NT ? v[decorator_index] : v[1]
272
259
  end
273
260
  end
274
261
 
275
262
  def after_reduce
276
- method = @on_reduce[-action_value]
263
+ method = on_reduce[-action_value]
277
264
  result = method ? send(method, @_arguments) : nil
278
265
  stack[stack.size - 2][decorator_index] = result
279
266
  end
@@ -0,0 +1,63 @@
1
+ class Depager::RieExtension
2
+ module DebugHelper
3
+ def inspect
4
+ "<#{node_name}:#{node_values.inspect}>"
5
+ end
6
+
7
+ def pretty_print(q)
8
+ q.group(1, "<#{node_name}:", ">") { q.pp node_values }
9
+ end
10
+
11
+ def node_name
12
+ self.class.name.split("::").last
13
+ end
14
+
15
+ def node_values
16
+ to_h.tap { _1.delete(:lineno) }
17
+ end
18
+ end
19
+
20
+ module Nodes
21
+ N_THREAD.class_eval do
22
+ include DebugHelper
23
+ end
24
+
25
+ N_TRANSFER.class_eval do
26
+ include DebugHelper
27
+ end
28
+
29
+ N_EXCEPT.class_eval do
30
+ include DebugHelper
31
+ end
32
+
33
+ N_LET.class_eval do
34
+ include DebugHelper
35
+ end
36
+
37
+ N_ACTION.class_eval do
38
+ include DebugHelper
39
+ end
40
+
41
+ N_ATOC.class_eval do
42
+ include DebugHelper
43
+
44
+ def inspect
45
+ name = sym_name == "$" ? "$#{grammar.symname(grammar[rx].lhs)}" : sym_name
46
+ "<N_ATOC:#{[name, attr_name, rx].inspect}>"
47
+ end
48
+
49
+ def pretty_print(q)
50
+ name = begin
51
+ sym_name == "$" ? "$#{grammar.symname(grammar[rx].lhs)}" : sym_name
52
+ rescue StandardError
53
+ nil
54
+ end
55
+ q.group(1, "<N_ATOC:", ">") { q.pp [name, attr_name, rx] }
56
+ end
57
+
58
+ def grammar
59
+ $grammar # rubocop: disable Style/GlobalVars
60
+ end
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,47 @@
1
+ class Depager::ActionExtension < Depager::Extension
2
+ def init_extension
3
+ @action_code = ""
4
+ @on_reduce = []
5
+ end
6
+
7
+ def term_extension
8
+ g_parser.outer_code <<
9
+ generate_action_decorator_code(@on_reduce, @action_code)
10
+ end
11
+
12
+ def pre_rule_list
13
+ return unless /^%ACTION\{\s*$/.match?(g_parser.original_line)
14
+
15
+ while (line = file.gets)
16
+ break if /^%\}\s*$/.match?(line)
17
+
18
+ @action_code << line
19
+ end
20
+ g_parser.update_context ""
21
+ end
22
+
23
+ def post_rhs
24
+ return unless /\s*\{/.match?(g_parser.line)
25
+
26
+ @original_line = g_parser.original_line
27
+ @line = g_parser.line
28
+ lineno = g_parser.file.lineno
29
+ code = modify_action_code(parse_block)
30
+ n = g_parser.rules.size - 1
31
+ @action_code <<
32
+ expand_inline_code(code, lineno, wrap: "def _act_#{n} val", delta: 1)
33
+ g_parser.update_context @line
34
+ @on_reduce[n] = ":_act_#{n}"
35
+ end
36
+
37
+ def modify_action_code(code)
38
+ let_code = " # empty rule\n"
39
+ unless g_parser.rhs_names.empty?
40
+ vars = g_parser.rhs_names.map do |i|
41
+ /[a-zA-Z][a-zA-Z0-9_]*/.match?(i) ? "_#{i}" : "_"
42
+ end
43
+ let_code = " #{vars.join(', ')}, = *val\n"
44
+ end
45
+ let_code << code
46
+ end
47
+ end
@@ -1,9 +1,8 @@
1
1
  %defext Depager::ASTBuilderExtension
2
- %extend Depager::Lexer ('plugins/lex.rb')
3
- %extend Depager::Action ('plugins/action.rb')
2
+ %extend Depager::Lexer ('depager/plugins/lex.rb')
3
+ %extend Depager::Action ('depager/plugins/action.rb')
4
4
  %decorate @Action
5
- #%decorate Depager::LALR::ShiftReducePrinter ('plugins/srp.rb')
6
- %expanded_code_delimiter DEPAGER_EXPANDED_CODE
5
+ #%decorate Depager::LALR::ShiftReducePrinter ('depager/plugins/srp.rb')
7
6
  %inner{
8
7
  attr_accessor :action_code, :on_reduce, :visitors
9
8
  def init_extension
@@ -19,11 +18,11 @@
19
18
 
20
19
  def modify_action_code code, nodes=[]
21
20
  code = code.gsub(/\$\.([a-z_])/, 'node.\1')
22
- code << %{
21
+ code << <<-CODE
23
22
  rescue
24
23
  warn "raise at src:\#{node.lineno}/\#{node.class.name}"
25
24
  raise
26
- }
25
+ CODE
27
26
  end
28
27
 
29
28
  def gen_accept_code sym
@@ -80,11 +79,11 @@
80
79
  { "" }
81
80
  | NODE opt_attr ACTION
82
81
  {
83
- ini = %{
82
+ ini = <<-CODE
84
83
  def initialize
85
84
  #{_ACTION.value}
86
85
  end
87
- };#code
86
+ CODE
88
87
  ERB.new(master.class::BASE_NODE_TEMPLATE, nil, '-').result(binding)
89
88
  }
90
89
  ;
@@ -173,11 +172,11 @@
173
172
  %inner{
174
173
  def do_default
175
174
  n = g_parser.rules.size-1
176
- master.action_code << %{
175
+ master.action_code << <<~CODE
177
176
  def _ast_#{n} val
178
177
  NilNode.new(basis.file.lineno)
179
178
  end
180
- }.unindent #code
179
+ CODE
181
180
  master.on_reduce[n] = ":_ast_#{n}"
182
181
  end
183
182
  %}
@@ -266,7 +265,7 @@
266
265
  %%
267
266
 
268
267
  class Depager::ASTBuilderExtension
269
- BASE_NODE_TEMPLATE = <<-'EOS'
268
+ BASE_NODE_TEMPLATE = <<-'CODE'
270
269
  class Node
271
270
  attr_accessor :lineno
272
271
  attr_accessor <%= _opt_attr.map{|i| ":#{i}" }.join(', ') %>
@@ -331,14 +330,14 @@ class Depager::ASTBuilderExtension
331
330
  def accept v
332
331
  end
333
332
  end
334
- EOS
333
+ CODE
335
334
 
336
- NODE_TEMPLATE = <<-'EOS'
335
+ NODE_TEMPLATE = <<-'CODE'
337
336
  class Node_<%= name %> < Node
338
337
  attr_accessor <%= nodes.map{|i| ":#{i}" }.join(', ') %>
339
338
  attr_accessor <%= attrs.map{|i| ":#{i}" }.join(', ') %>
340
339
 
341
- def initialize <%= nodes.unshift('lineno').join(', ') %>
340
+ def initialize <%= ['lineno', *nodes].join(', ') %>
342
341
  super()
343
342
  @lineno = lineno
344
343
  <%= nodes.inject(''){|r,i| r << " @#{i} = #{i}\n"} %>
@@ -350,15 +349,19 @@ class Depager::ASTBuilderExtension
350
349
  v.visit_Node_<%= name %>(self)
351
350
  self
352
351
  end
352
+
353
+ def attributes
354
+ { <%= (nodes + attrs).uniq.map{|i| "#{i}: #{i}" }.join(', ') %>, lineno: lineno }
355
+ end
353
356
  end
354
- EOS
357
+ CODE
355
358
 
356
- VISITOR_TEMPLATE = <<-'EOS'
359
+ VISITOR_TEMPLATE = <<-'CODE'
357
360
  class Visitor<%= name ? '_' + name : '' %>
358
361
  def visit node
359
362
  node.accept(self)
360
363
  end
361
364
  <%= body.join %>
362
365
  end # Visitor<%= name ? '_' + name : '' %>
363
- EOS
366
+ CODE
364
367
  end