packcr 0.0.4 → 0.0.6

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 (75) hide show
  1. checksums.yaml +4 -4
  2. data/exe/packcr +3 -0
  3. data/lib/packcr/broadcast.rb +17 -0
  4. data/lib/packcr/cli.rb +25 -0
  5. data/lib/packcr/code_block.rb +2 -3
  6. data/lib/packcr/context.rb +59 -56
  7. data/lib/packcr/generator.rb +13 -11
  8. data/lib/packcr/node/action_node.rb +14 -5
  9. data/lib/packcr/node/alternate_node.rb +20 -12
  10. data/lib/packcr/node/capture_node.rb +11 -11
  11. data/lib/packcr/node/charclass_node.rb +37 -13
  12. data/lib/packcr/node/eof_node.rb +23 -0
  13. data/lib/packcr/node/error_node.rb +17 -12
  14. data/lib/packcr/node/expand_node.rb +11 -5
  15. data/lib/packcr/node/predicate_node.rb +15 -24
  16. data/lib/packcr/node/quantity_node.rb +23 -18
  17. data/lib/packcr/node/reference_node.rb +21 -5
  18. data/lib/packcr/node/root_node.rb +60 -0
  19. data/lib/packcr/node/rule_node.rb +26 -3
  20. data/lib/packcr/node/sequence_node.rb +46 -31
  21. data/lib/packcr/node/string_node.rb +12 -12
  22. data/lib/packcr/node.rb +35 -4
  23. data/lib/packcr/parser.rb +2939 -2661
  24. data/lib/packcr/stream.rb +8 -13
  25. data/lib/packcr/templates/context/header.c.erb +29 -0
  26. data/lib/packcr/templates/context/source.c.erb +1292 -0
  27. data/lib/packcr/templates/context/source.rb.erb +406 -0
  28. data/lib/packcr/templates/node/action.c.erb +16 -0
  29. data/lib/packcr/templates/node/action.rb.erb +21 -0
  30. data/lib/packcr/templates/node/alternate.c.erb +34 -0
  31. data/lib/packcr/templates/node/alternate.rb.erb +40 -0
  32. data/lib/packcr/templates/node/capture.c.erb +17 -0
  33. data/lib/packcr/templates/node/capture.rb.erb +14 -0
  34. data/lib/packcr/templates/node/charclass.c.erb +47 -0
  35. data/lib/packcr/templates/node/charclass.rb.erb +49 -0
  36. data/lib/packcr/templates/node/charclass_any.c.erb +5 -0
  37. data/lib/packcr/templates/node/charclass_any.rb.erb +7 -0
  38. data/lib/packcr/templates/node/charclass_fail.c.erb +1 -0
  39. data/lib/packcr/templates/node/charclass_fail.rb.erb +1 -0
  40. data/lib/packcr/templates/node/charclass_one.c.erb +19 -0
  41. data/lib/packcr/templates/node/charclass_one.rb.erb +23 -0
  42. data/lib/packcr/templates/node/charclass_utf8.c.erb +49 -0
  43. data/lib/packcr/templates/node/charclass_utf8.rb.erb +50 -0
  44. data/lib/packcr/templates/node/charclass_utf8_reverse.rb.erb +51 -0
  45. data/lib/packcr/templates/node/eof.c.erb +1 -0
  46. data/lib/packcr/templates/node/eof.rb.erb +3 -0
  47. data/lib/packcr/templates/node/error.c.erb +28 -0
  48. data/lib/packcr/templates/node/error.rb.erb +34 -0
  49. data/lib/packcr/templates/node/expand.c.erb +16 -0
  50. data/lib/packcr/templates/node/expand.rb.erb +16 -0
  51. data/lib/packcr/templates/node/predicate.c.erb +30 -0
  52. data/lib/packcr/templates/node/predicate.rb.erb +28 -0
  53. data/lib/packcr/templates/node/predicate_neg.c.erb +23 -0
  54. data/lib/packcr/templates/node/predicate_neg.rb.erb +22 -0
  55. data/lib/packcr/templates/node/quantify_many.c.erb +45 -0
  56. data/lib/packcr/templates/node/quantify_many.rb.erb +47 -0
  57. data/lib/packcr/templates/node/quantify_one.c.erb +21 -0
  58. data/lib/packcr/templates/node/quantify_one.rb.erb +23 -0
  59. data/lib/packcr/templates/node/reference.c.erb +5 -0
  60. data/lib/packcr/templates/node/reference.rb.erb +9 -0
  61. data/lib/packcr/templates/node/reference_reverse.rb.erb +9 -0
  62. data/lib/packcr/templates/node/rule.c.erb +19 -0
  63. data/lib/packcr/templates/node/rule.rb.erb +23 -0
  64. data/lib/packcr/templates/node/sequence.c.erb +12 -0
  65. data/lib/packcr/templates/node/sequence.rb.erb +12 -0
  66. data/lib/packcr/templates/node/string_many.c.erb +11 -0
  67. data/lib/packcr/templates/node/string_many.rb.erb +10 -0
  68. data/lib/packcr/templates/node/string_one.c.erb +8 -0
  69. data/lib/packcr/templates/node/string_one.rb.erb +10 -0
  70. data/lib/packcr/tokenizer.rb +2948 -0
  71. data/lib/packcr/util.rb +0 -8
  72. data/lib/packcr/version.rb +1 -1
  73. data/lib/packcr.rb +1 -2
  74. metadata +87 -8
  75. data/lib/packcr/buffer.rb +0 -47
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b00f2dcd94c63af9d03206e51dbb951778f35cf44a8e4644025f8fb5f59043e2
4
- data.tar.gz: d03d48555f0dfb6086acb7198050defe1e0eea025fca279ef9fc85491803f83b
3
+ metadata.gz: 53243fb5032a86ddf13dcd3c4b99075d4e8ebfae75a0f239ec4e4564ee56c8dc
4
+ data.tar.gz: 17c31d7663eb1207a3426add4c226dde9bdbf4540a11b4570c4b26f5ddb5f0be
5
5
  SHA512:
6
- metadata.gz: a06709977ca0f8a12529668b2ae879f5a713798a35daaf27a76038560cf949817d128f47f019b2ef59ce347f61021415806343646f4835dd239e9965e4dd1814
7
- data.tar.gz: f4de00a9453f68af3eeefb2b07792ff1cfd3748dd21aaa96fb859ec57a13bd4fd7c63931c7695ee8e2c13256f6d8a17ff694de8e48df809d7e33582f0861d8c7
6
+ metadata.gz: 5fd7efc77c5b5e49c540652d0072aa3b749b8d99c39bad10984ad02f12c4f0fef3df2783ff11a012f4eac5cf62e0d8c3640b381909ee9c08e00dc990e67a3acb
7
+ data.tar.gz: cb94b6e3bc70fbad68a50471321f66d76425d6729775a1d542f44e45900fef286a592947fbabcf398cca67c142be58cc64b89a7249eba5baa5775ae19f7af4f3
data/exe/packcr ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env ruby
2
+ require "packcr/cli"
3
+ Packcr::Cli.run(ARGV)
@@ -0,0 +1,17 @@
1
+ class Packcr
2
+ class BroadCast
3
+ def initialize(*arrays)
4
+ @arrays = arrays
5
+ end
6
+
7
+ def <<(obj)
8
+ @arrays.each do |array|
9
+ array << obj
10
+ end
11
+ end
12
+
13
+ def to_ary
14
+ @arrays
15
+ end
16
+ end
17
+ end
data/lib/packcr/cli.rb ADDED
@@ -0,0 +1,25 @@
1
+ require "packcr"
2
+ require "optparse"
3
+
4
+ class Packcr::Cli
5
+ class << self
6
+ def run(argv)
7
+ new.run(argv)
8
+ end
9
+ end
10
+
11
+ def run(argv)
12
+ lang = nil
13
+ debug = false
14
+ ascii = false
15
+ opt = OptionParser.new
16
+ opt.on("-l", "--lang=VAL") {|v| lang = v.to_sym }
17
+ opt.on("-d", "--debug") {|v| debug = true }
18
+ opt.on("-a", "--ascii") {|v| ascii = true }
19
+
20
+ opt.parse!(argv)
21
+ argv.each do |ifile|
22
+ Packcr.new(ifile, lang: lang, debug: debug, ascii: ascii).run
23
+ end
24
+ end
25
+ end
@@ -1,11 +1,10 @@
1
1
 
2
2
  class Packcr
3
3
  class CodeBlock
4
- attr_reader :text, :len, :line
4
+ attr_reader :text, :line
5
5
 
6
- def initialize(text = nil, len = 0, line = nil, col = nil)
6
+ def initialize(text = nil, line = nil, col = nil)
7
7
  @text = text
8
- @len = len
9
8
  @line = line
10
9
  @col = col
11
10
  end
@@ -1,15 +1,20 @@
1
+ require "tempfile"
1
2
  require "packcr/parser"
3
+ require "packcr/broadcast"
2
4
 
3
5
  class Packcr
4
- class Context < Packcr::Parser
6
+ class Context
7
+ attr_reader :lang, :root
8
+ attr_accessor :prefix, :auxil_type, :value_type, :errnum, :capture_in_code
9
+
5
10
  def initialize(path, lines: false, debug: false, ascii: false, lang: nil)
6
- super(debug: debug)
7
11
  if !path
8
12
  raise ArgumentError, "bad path: #{path}";
9
13
  end
10
14
 
11
15
  @iname = path
12
- @ifile = File.open(path, "rb")
16
+ @debug = debug
17
+
13
18
  dirname = File.dirname(path)
14
19
  basename = File.basename(path, ".*")
15
20
  if !lang
@@ -29,40 +34,38 @@ class Packcr
29
34
  @lang = lang.to_sym
30
35
  case @lang
31
36
  when :c
32
- @sname = path + ".c"
33
37
  @hname = path + ".h"
38
+ @patterns = {
39
+ source: path + ".c",
40
+ header: @hname
41
+ }
34
42
  @hid = File.basename(@hname).upcase.gsub(/[^A-Z0-9]/, "_")
35
43
  when :rb
36
- @sname = path + ".rb"
37
- @hname = nil
44
+ @patterns = {
45
+ source: path + ".rb"
46
+ }
38
47
  else
39
48
  raise "unexpected lang: #{@lang}"
40
49
  end
41
50
 
42
51
  @lines = !!lines
43
52
  @ascii = !!ascii
53
+ @utf8 = !ascii
44
54
 
45
55
  @errnum = 0
46
- @linenum = 0
47
- @charnum = 0
48
- @linepos = 0
49
- @bufpos = 0
50
- @bufcur = 0
51
-
52
- @esource = []
53
- @eheader = []
54
- @source = []
55
- @header = []
56
- @lheader = []
57
- @lsource = []
58
- @location = []
59
- @init = []
56
+
57
+ @codes = {}
58
+ @root = Node::RootNode.new
60
59
 
61
60
  if block_given?
62
61
  yield(self)
63
62
  end
64
63
  end
65
64
 
65
+ def code(name)
66
+ @codes[name] ||= []
67
+ end
68
+
66
69
  def inspect
67
70
  "#<#{self.class}:0x%016x>" % object_id
68
71
  end
@@ -84,6 +87,15 @@ class Packcr
84
87
  @prefix || "pcc"
85
88
  end
86
89
 
90
+ def pass_value_code(var)
91
+ case @lang
92
+ when :c
93
+ "__ = #{var};"
94
+ when :rb
95
+ "____ = #{var}"
96
+ end
97
+ end
98
+
87
99
  def class_name
88
100
  prefix.gsub(/(?:_|^|(\W))([a-z])/) { "#{$1}#{$2}".upcase }
89
101
  end
@@ -106,33 +118,20 @@ class Packcr
106
118
  EOS
107
119
  end
108
120
 
109
- def parse
110
- $stdin = @ifile
111
- nil while super
112
-
113
- if @location.empty?
114
- @location = nil
121
+ def parse_all
122
+ File.open(@iname, "rb") do |r|
123
+ parser = Packcr::Parser.new(self, r, debug: @debug)
124
+ nil while parser.parse
115
125
  end
116
126
 
117
- make_rulehash
118
- @rules.each do |rule|
119
- rule.setup
120
- rule.expr.link_references(self)
121
- end
122
- @rules[1..-1]&.each do |rule|
123
- if rule.ref == 0
124
- error rule.line + 1, rule.col + 1, "Never used rule '#{rule.name}'"
125
- elsif rule.ref < 0 # impossible?
126
- error rule.line + 1, rule.col + 1, "Multiple definition of rule '#{rule.name}'"
127
- end
127
+ if !code(:location).empty?
128
+ @location = true
128
129
  end
129
130
 
130
- @rules.each do |rule|
131
- rule.verify(self)
132
- end
131
+ @root.setup(self)
133
132
 
134
133
  if @debug
135
- @rules.each(&:debug_dump)
134
+ @root.debug_dump
136
135
  dump_options
137
136
  end
138
137
 
@@ -140,24 +139,28 @@ class Packcr
140
139
  end
141
140
 
142
141
  def generate
143
- if @hname
144
- File.open(@hname, "wt") do |hio|
145
- hstream = ::Packcr::Stream.new(hio, @hname, @lines ? 0 : nil)
146
-
147
- hstream.write Packcr.template("context/header.#{@lang}.erb", binding), rewrite_line_directive: true
142
+ results = []
143
+
144
+ @patterns.each do |template, ofile|
145
+ result = Tempfile.new
146
+ result.unlink
147
+ results << [ofile, result]
148
+ stream = Packcr::Stream.new(result, ofile, @lines ? 0 : nil)
149
+ stream.write Packcr.template("context/#{template}.#{@lang}.erb", binding), rewrite_line_directive: true
150
+
151
+ if !@errnum.zero?
152
+ results.each do |_, result|
153
+ result.close
154
+ end
155
+ return false
148
156
  end
149
157
  end
150
158
 
151
- File.open(@sname, "wt") do |sio|
152
- sstream = ::Packcr::Stream.new(sio, @sname, @lines ? 0 : nil)
153
-
154
- sstream.write Packcr.template("context/source.#{@lang}.erb", binding), rewrite_line_directive: true
155
- end
156
-
157
- if !@errnum.zero?
158
- File.unlink(@hname) if @name
159
- File.unlink(@sname)
160
- return false
159
+ results.each do |(name, result)|
160
+ result.rewind
161
+ open(name, "wt") do |f|
162
+ IO.copy_stream(result, f)
163
+ end
161
164
  end
162
165
  true
163
166
  end
@@ -1,8 +1,6 @@
1
- require "stringio"
2
-
3
1
  class Packcr
4
2
  class Generator
5
- attr_reader :ascii, :rule, :location, :lang
3
+ attr_reader :ascii, :rule, :location, :lang, :level
6
4
 
7
5
  def initialize(rule, ascii, location, lang = :c)
8
6
  @rule = rule
@@ -10,27 +8,31 @@ class Packcr
10
8
  @ascii = !!ascii
11
9
  @location = !!location
12
10
  @lang = lang
11
+ @level = 0
13
12
  end
14
13
 
15
14
  def next_label
16
15
  @label += 1
17
16
  end
18
17
 
19
- def generate_code(node, onfail, indent, bare)
20
- node.generate_code(self, onfail, indent, bare)
21
- end
22
-
23
- def generate_code_str(node, onfail, indent, bare)
24
- @stream, stream = StringIO.new, @stream
18
+ def generate_code(node, onescape, indent, bare, reverse: false, oncut: nil)
19
+ @stream, stream = +"", @stream
20
+ @level += 1
25
21
  begin
26
- return generate_code(node, onfail, indent, bare), @stream.string
22
+ if reverse
23
+ node.generate_reverse_code(self, onescape, indent, bare, oncut: oncut)
24
+ else
25
+ node.generate_code(self, onescape, indent, bare, oncut: oncut)
26
+ end
27
+ @stream
27
28
  ensure
29
+ @level -= 1
28
30
  @stream = stream
29
31
  end
30
32
  end
31
33
 
32
34
  def write(str)
33
- @stream.write(str)
35
+ @stream << str
34
36
  end
35
37
  end
36
38
  end
@@ -33,9 +33,12 @@ class Packcr
33
33
  end
34
34
  end
35
35
 
36
- def generate_code(gen, onfail, indent, bare)
36
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
37
37
  gen.write Packcr.template("node/action.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
38
- return Packcr::CODE_REACH__ALWAYS_SUCCEED
38
+ end
39
+
40
+ def reachability
41
+ Packcr::CODE_REACH__ALWAYS_SUCCEED
39
42
  end
40
43
 
41
44
  def verify_variables(vars)
@@ -46,13 +49,19 @@ class Packcr
46
49
  @capts = capts
47
50
  end
48
51
 
49
- def link_references(ctx)
50
- end
51
-
52
52
  def setup_rule(rule)
53
53
  @index = rule.codes.length
54
54
  rule.codes.push(self)
55
55
  end
56
+
57
+ def to_h
58
+ {
59
+ type: :action,
60
+ code: code&.text,
61
+ vars: vars&.map(&:to_h),
62
+ capts: capts&.map(&:to_h),
63
+ }
64
+ end
56
65
  end
57
66
  end
58
67
  end
@@ -9,7 +9,7 @@ class Packcr
9
9
  end
10
10
 
11
11
  def alt(node)
12
- @nodes << node
12
+ @nodes << node if node
13
13
  self
14
14
  end
15
15
 
@@ -27,14 +27,21 @@ class Packcr
27
27
  m
28
28
  end
29
29
 
30
- def generate_code(gen, onfail, indent, bare)
31
- b = false
32
- m = gen.next_label
33
-
34
- reach = nil
35
- gen.write Packcr.template("node/alternate.#{gen.lang}.erb", binding, indent: indent - 4, unwrap: bare)
30
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
31
+ gen.write Packcr.template("node/alternate.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
32
+ end
36
33
 
37
- reach || Packcr::CODE_REACH__ALWAYS_FAIL
34
+ def reachability
35
+ r = Packcr::CODE_REACH__ALWAYS_FAIL
36
+ nodes.each do |expr|
37
+ case expr.reachability
38
+ when Packcr::CODE_REACH__ALWAYS_SUCCEED
39
+ return Packcr::CODE_REACH__ALWAYS_SUCCEED
40
+ when Packcr::CODE_REACH__BOTH
41
+ r = Packcr::CODE_REACH__BOTH
42
+ end
43
+ end
44
+ r
38
45
  end
39
46
 
40
47
  def verify_variables(vars)
@@ -66,10 +73,11 @@ class Packcr
66
73
  end
67
74
  end
68
75
 
69
- def link_references(ctx)
70
- nodes.each do |node|
71
- node.link_references(ctx)
72
- end
76
+ def to_h
77
+ {
78
+ type: :alternate,
79
+ nodes: nodes&.map(&:to_h),
80
+ }
73
81
  end
74
82
  end
75
83
  end
@@ -15,25 +15,19 @@ class Packcr
15
15
  $stdout.print "#{" " * indent}}\n"
16
16
  end
17
17
 
18
- def generate_code(gen, onfail, indent, bare)
19
- r = nil
18
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
20
19
  gen.write Packcr.template("node/capture.#{gen.lang}.erb", binding, indent: indent)
21
- return r
22
20
  end
23
21
 
24
- def verify_variables(vars)
25
- expr.verify_variables(vars)
22
+ def reachability
23
+ expr.reachability
26
24
  end
27
25
 
28
26
  def verify_captures(ctx, capts)
29
- expr.verify_captures(ctx, capts)
27
+ super
30
28
  capts.push(self)
31
29
  end
32
30
 
33
- def link_references(ctx)
34
- expr.link_references(ctx)
35
- end
36
-
37
31
  def nodes
38
32
  [expr]
39
33
  end
@@ -41,7 +35,13 @@ class Packcr
41
35
  def setup_rule(rule)
42
36
  @index = rule.capts.length
43
37
  rule.capts << self
44
- super
38
+ end
39
+
40
+ def to_h
41
+ {
42
+ type: :capture,
43
+ expr: expr&.to_h,
44
+ }
45
45
  end
46
46
  end
47
47
  end
@@ -13,7 +13,11 @@ class Packcr
13
13
  $stdout.print "')\n"
14
14
  end
15
15
 
16
- def generate_code(gen, onfail, indent, bare)
16
+ def reversible?(gen)
17
+ gen.lang == :rb && !gen.ascii
18
+ end
19
+
20
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
17
21
  if gen.ascii
18
22
  return generate_ascii_code(gen, onfail, indent, bare)
19
23
  else
@@ -21,13 +25,22 @@ class Packcr
21
25
  end
22
26
  end
23
27
 
24
- def verify_variables(vars)
25
- end
26
-
27
- def verify_captures(ctx, capts)
28
+ def generate_reverse_code(gen, onsuccess, indent, bare, oncut: nil)
29
+ if gen.ascii
30
+ raise "unexpected"
31
+ else
32
+ return generate_utf8_charclass_reverse_code(gen, onsuccess, indent, bare)
33
+ end
28
34
  end
29
35
 
30
- def link_references(ctx)
36
+ def reachability
37
+ charclass = self.value
38
+ n = charclass&.length || 0
39
+ if charclass.nil? || n > 0
40
+ return Packcr::CODE_REACH__BOTH
41
+ else
42
+ return Packcr::CODE_REACH__ALWAYS_FAIL
43
+ end
31
44
  end
32
45
 
33
46
  private
@@ -39,13 +52,20 @@ class Packcr
39
52
  end
40
53
  n = charclass&.length || 0
41
54
  if charclass.nil? || n > 0
42
- a = charclass && charclass[0] == '^'
43
- i = a ? 1 : 0
44
55
  gen.write Packcr.template("node/charclass_utf8.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
45
- return Packcr::CODE_REACH__BOTH
46
56
  else
47
57
  gen.write Packcr.template("node/charclass_fail.#{gen.lang}.erb", binding, indent: indent)
48
- return Packcr::CODE_REACH__ALWAYS_FAIL
58
+ end
59
+ end
60
+
61
+ def generate_utf8_charclass_reverse_code(gen, onsuccess, indent, bare)
62
+ charclass = self.value
63
+ if charclass && charclass.encoding != Encoding::UTF_8
64
+ charclass = charclass.dup.force_encoding(Encoding::UTF_8)
65
+ end
66
+ n = charclass&.length || 0
67
+ if charclass.nil? || n > 0
68
+ gen.write Packcr.template("node/charclass_utf8_reverse.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
49
69
  end
50
70
  end
51
71
 
@@ -64,16 +84,20 @@ class Packcr
64
84
  else
65
85
  gen.write Packcr.template("node/charclass_one.#{gen.lang}.erb", binding, indent: indent)
66
86
  end
67
- return Packcr::CODE_REACH__BOTH
68
87
  else
69
88
  gen.write Packcr.template("node/charclass_fail.#{gen.lang}.erb", binding, indent: indent)
70
- return Packcr::CODE_REACH__ALWAYS_FAIL
71
89
  end
72
90
  else
73
91
  gen.write Packcr.template("node/charclass_any.#{gen.lang}.erb", binding, indent: indent)
74
- return Packcr::CODE_REACH__BOTH
75
92
  end
76
93
  end
94
+
95
+ def to_h
96
+ {
97
+ type: :charclass,
98
+ value: value,
99
+ }
100
+ end
77
101
  end
78
102
  end
79
103
  end
@@ -0,0 +1,23 @@
1
+ class Packcr
2
+ class Node
3
+ class EofNode < Packcr::Node
4
+ def debug_dump(indent = 0)
5
+ $stdout.print "#{" " * indent}Eof()\n"
6
+ end
7
+
8
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
9
+ gen.write Packcr.template("node/eof.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
10
+ end
11
+
12
+ def reachability
13
+ return Packcr::CODE_REACH__BOTH
14
+ end
15
+
16
+ def to_h
17
+ {
18
+ type: :eof,
19
+ }
20
+ end
21
+ end
22
+ end
23
+ end
@@ -29,26 +29,22 @@ class Packcr
29
29
  $stdout.print "#{" " * indent}}\n"
30
30
  end
31
31
 
32
- def generate_code(gen, onfail, indent, bare)
33
- l = gen.next_label
34
- m = gen.next_label
35
- r, code = gen.generate_code_str(expr, l, 4, true)
32
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
36
33
  gen.write Packcr.template("node/error.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
37
- return r
34
+ end
35
+
36
+ def reachability
37
+ expr.reachability
38
38
  end
39
39
 
40
40
  def verify_variables(vars)
41
41
  @vars = vars
42
- expr.verify_variables(vars)
42
+ super
43
43
  end
44
44
 
45
45
  def verify_captures(ctx, capts)
46
46
  @capts = capts
47
- expr.verify_captures(ctx, capts)
48
- end
49
-
50
- def link_references(ctx)
51
- expr.link_references(ctx)
47
+ super
52
48
  end
53
49
 
54
50
  def nodes
@@ -58,7 +54,16 @@ class Packcr
58
54
  def setup_rule(rule)
59
55
  @index = rule.codes.length
60
56
  rule.codes.push(self)
61
- super
57
+ end
58
+
59
+ def to_h
60
+ {
61
+ type: :error,
62
+ code: code&.text,
63
+ vars: vars&.map(&:to_h),
64
+ capts: capts&.map(&:to_h),
65
+ index: @index,
66
+ }
62
67
  end
63
68
  end
64
69
  end
@@ -3,8 +3,10 @@ class Packcr
3
3
  class ExpandNode < Packcr::Node
4
4
  attr_accessor :index, :line, :col
5
5
 
6
- def initialize(index = nil)
6
+ def initialize(index = nil, line = nil, col = nil)
7
7
  @index = index
8
+ @line = line
9
+ @col = col
8
10
  end
9
11
 
10
12
  def debug_dump(indent = 0)
@@ -13,12 +15,12 @@ class Packcr
13
15
  $stdout.print ")\n"
14
16
  end
15
17
 
16
- def generate_code(gen, onfail, indent, bare)
18
+ def generate_code(gen, onfail, indent, bare, oncut: nil)
17
19
  gen.write Packcr.template("node/expand.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
18
- return Packcr::CODE_REACH__BOTH
19
20
  end
20
21
 
21
- def verify_variables(vars)
22
+ def reachability
23
+ return Packcr::CODE_REACH__BOTH
22
24
  end
23
25
 
24
26
  def verify_captures(ctx, capts)
@@ -33,7 +35,11 @@ class Packcr
33
35
  end
34
36
  end
35
37
 
36
- def link_references(ctx)
38
+ def to_h
39
+ {
40
+ type: :expand,
41
+ index: index,
42
+ }
37
43
  end
38
44
  end
39
45
  end