packcr 0.0.3 → 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.
- checksums.yaml +4 -4
- data/exe/packcr +3 -0
- data/lib/packcr/broadcast.rb +17 -0
- data/lib/packcr/cli.rb +25 -0
- data/lib/packcr/code_block.rb +2 -3
- data/lib/packcr/context.rb +58 -872
- data/lib/packcr/generator.rb +13 -10
- data/lib/packcr/node/action_node.rb +20 -5
- data/lib/packcr/node/alternate_node.rb +27 -14
- data/lib/packcr/node/capture_node.rb +22 -8
- data/lib/packcr/node/charclass_node.rb +41 -13
- data/lib/packcr/node/eof_node.rb +23 -0
- data/lib/packcr/node/error_node.rb +29 -11
- data/lib/packcr/node/expand_node.rb +14 -4
- data/lib/packcr/node/predicate_node.rb +19 -23
- data/lib/packcr/node/quantity_node.rb +28 -18
- data/lib/packcr/node/reference_node.rb +43 -5
- data/lib/packcr/node/root_node.rb +60 -0
- data/lib/packcr/node/rule_node.rb +38 -3
- data/lib/packcr/node/sequence_node.rb +51 -31
- data/lib/packcr/node/string_node.rb +16 -12
- data/lib/packcr/node.rb +48 -0
- data/lib/packcr/parser.rb +4570 -0
- data/lib/packcr/stream.rb +9 -13
- data/lib/packcr/templates/context/header.c.erb +29 -0
- data/lib/packcr/templates/context/source.c.erb +1292 -0
- data/lib/packcr/templates/context/source.rb.erb +406 -0
- data/lib/packcr/templates/node/action.c.erb +16 -0
- data/lib/packcr/templates/node/action.rb.erb +21 -0
- data/lib/packcr/templates/node/alternate.c.erb +34 -0
- data/lib/packcr/templates/node/alternate.rb.erb +40 -0
- data/lib/packcr/templates/node/capture.c.erb +17 -0
- data/lib/packcr/templates/node/capture.rb.erb +14 -0
- data/lib/packcr/templates/node/charclass.c.erb +47 -0
- data/lib/packcr/templates/node/charclass.rb.erb +49 -0
- data/lib/packcr/templates/node/charclass_any.c.erb +5 -0
- data/lib/packcr/templates/node/charclass_any.rb.erb +7 -0
- data/lib/packcr/templates/node/charclass_fail.c.erb +1 -0
- data/lib/packcr/templates/node/charclass_fail.rb.erb +1 -0
- data/lib/packcr/templates/node/charclass_one.c.erb +19 -0
- data/lib/packcr/templates/node/charclass_one.rb.erb +23 -0
- data/lib/packcr/templates/node/charclass_utf8.c.erb +49 -0
- data/lib/packcr/templates/node/charclass_utf8.rb.erb +50 -0
- data/lib/packcr/templates/node/charclass_utf8_reverse.rb.erb +51 -0
- data/lib/packcr/templates/node/eof.c.erb +1 -0
- data/lib/packcr/templates/node/eof.rb.erb +3 -0
- data/lib/packcr/templates/node/error.c.erb +28 -0
- data/lib/packcr/templates/node/error.rb.erb +34 -0
- data/lib/packcr/templates/node/expand.c.erb +16 -0
- data/lib/packcr/templates/node/expand.rb.erb +16 -0
- data/lib/packcr/templates/node/predicate.c.erb +30 -0
- data/lib/packcr/templates/node/predicate.rb.erb +28 -0
- data/lib/packcr/templates/node/predicate_neg.c.erb +23 -0
- data/lib/packcr/templates/node/predicate_neg.rb.erb +22 -0
- data/lib/packcr/templates/node/quantify_many.c.erb +45 -0
- data/lib/packcr/templates/node/quantify_many.rb.erb +47 -0
- data/lib/packcr/templates/node/quantify_one.c.erb +21 -0
- data/lib/packcr/templates/node/quantify_one.rb.erb +23 -0
- data/lib/packcr/templates/node/reference.c.erb +5 -0
- data/lib/packcr/templates/node/reference.rb.erb +9 -0
- data/lib/packcr/templates/node/reference_reverse.rb.erb +9 -0
- data/lib/packcr/templates/node/rule.c.erb +19 -0
- data/lib/packcr/templates/node/rule.rb.erb +23 -0
- data/lib/packcr/templates/node/sequence.c.erb +12 -0
- data/lib/packcr/templates/node/sequence.rb.erb +12 -0
- data/lib/packcr/templates/node/string_many.c.erb +11 -0
- data/lib/packcr/templates/node/string_many.rb.erb +10 -0
- data/lib/packcr/templates/node/string_one.c.erb +8 -0
- data/lib/packcr/templates/node/string_one.rb.erb +10 -0
- data/lib/packcr/tokenizer.rb +2948 -0
- data/lib/packcr/util.rb +3 -8
- data/lib/packcr/version.rb +1 -1
- data/lib/packcr.rb +1 -2
- metadata +88 -8
- data/lib/packcr/buffer.rb +0 -47
data/lib/packcr/generator.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
|
-
|
2
1
|
class Packcr
|
3
2
|
class Generator
|
4
|
-
attr_reader :ascii, :rule, :location, :lang
|
3
|
+
attr_reader :ascii, :rule, :location, :lang, :level
|
5
4
|
|
6
5
|
def initialize(rule, ascii, location, lang = :c)
|
7
6
|
@rule = rule
|
@@ -9,27 +8,31 @@ class Packcr
|
|
9
8
|
@ascii = !!ascii
|
10
9
|
@location = !!location
|
11
10
|
@lang = lang
|
11
|
+
@level = 0
|
12
12
|
end
|
13
13
|
|
14
14
|
def next_label
|
15
15
|
@label += 1
|
16
16
|
end
|
17
17
|
|
18
|
-
def generate_code(node,
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
def generate_code_str(node, onfail, indent, bare)
|
23
|
-
@stream, stream = StringIO.new, @stream
|
18
|
+
def generate_code(node, onescape, indent, bare, reverse: false, oncut: nil)
|
19
|
+
@stream, stream = +"", @stream
|
20
|
+
@level += 1
|
24
21
|
begin
|
25
|
-
|
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
|
26
28
|
ensure
|
29
|
+
@level -= 1
|
27
30
|
@stream = stream
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
31
34
|
def write(str)
|
32
|
-
@stream
|
35
|
+
@stream << str
|
33
36
|
end
|
34
37
|
end
|
35
38
|
end
|
@@ -3,8 +3,9 @@ class Packcr
|
|
3
3
|
class ActionNode < Packcr::Node
|
4
4
|
attr_accessor :code, :index, :vars, :capts
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
super
|
6
|
+
def initialize(code = nil)
|
7
|
+
super()
|
8
|
+
@code = code
|
8
9
|
self.vars = []
|
9
10
|
self.capts = []
|
10
11
|
end
|
@@ -32,9 +33,12 @@ class Packcr
|
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
35
|
-
def generate_code(gen, onfail, indent, bare)
|
36
|
+
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
36
37
|
gen.write Packcr.template("node/action.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
37
|
-
|
38
|
+
end
|
39
|
+
|
40
|
+
def reachability
|
41
|
+
Packcr::CODE_REACH__ALWAYS_SUCCEED
|
38
42
|
end
|
39
43
|
|
40
44
|
def verify_variables(vars)
|
@@ -45,7 +49,18 @@ class Packcr
|
|
45
49
|
@capts = capts
|
46
50
|
end
|
47
51
|
|
48
|
-
def
|
52
|
+
def setup_rule(rule)
|
53
|
+
@index = rule.codes.length
|
54
|
+
rule.codes.push(self)
|
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
|
+
}
|
49
64
|
end
|
50
65
|
end
|
51
66
|
end
|
@@ -3,9 +3,14 @@ class Packcr
|
|
3
3
|
class AlternateNode < Packcr::Node
|
4
4
|
attr_accessor :nodes
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
super
|
8
|
-
self.nodes =
|
6
|
+
def initialize(*nodes)
|
7
|
+
super()
|
8
|
+
self.nodes = nodes
|
9
|
+
end
|
10
|
+
|
11
|
+
def alt(node)
|
12
|
+
@nodes << node if node
|
13
|
+
self
|
9
14
|
end
|
10
15
|
|
11
16
|
def debug_dump(indent = 0)
|
@@ -22,14 +27,21 @@ class Packcr
|
|
22
27
|
m
|
23
28
|
end
|
24
29
|
|
25
|
-
def generate_code(gen, onfail, indent, bare)
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
reach = nil
|
30
|
-
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
|
31
33
|
|
32
|
-
|
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
|
33
45
|
end
|
34
46
|
|
35
47
|
def verify_variables(vars)
|
@@ -61,10 +73,11 @@ class Packcr
|
|
61
73
|
end
|
62
74
|
end
|
63
75
|
|
64
|
-
def
|
65
|
-
|
66
|
-
|
67
|
-
|
76
|
+
def to_h
|
77
|
+
{
|
78
|
+
type: :alternate,
|
79
|
+
nodes: nodes&.map(&:to_h),
|
80
|
+
}
|
68
81
|
end
|
69
82
|
end
|
70
83
|
end
|
@@ -3,6 +3,10 @@ class Packcr
|
|
3
3
|
class CaptureNode < Packcr::Node
|
4
4
|
attr_accessor :expr, :index
|
5
5
|
|
6
|
+
def initialize(expr = nil)
|
7
|
+
@expr = expr
|
8
|
+
end
|
9
|
+
|
6
10
|
def debug_dump(indent = 0)
|
7
11
|
$stdout.print "#{" " * indent}Capture(index:"
|
8
12
|
Packcr.dump_integer_value(index)
|
@@ -11,23 +15,33 @@ class Packcr
|
|
11
15
|
$stdout.print "#{" " * indent}}\n"
|
12
16
|
end
|
13
17
|
|
14
|
-
def generate_code(gen, onfail, indent, bare)
|
15
|
-
r = nil
|
18
|
+
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
16
19
|
gen.write Packcr.template("node/capture.#{gen.lang}.erb", binding, indent: indent)
|
17
|
-
return r
|
18
20
|
end
|
19
21
|
|
20
|
-
def
|
21
|
-
expr.
|
22
|
+
def reachability
|
23
|
+
expr.reachability
|
22
24
|
end
|
23
25
|
|
24
26
|
def verify_captures(ctx, capts)
|
25
|
-
|
27
|
+
super
|
26
28
|
capts.push(self)
|
27
29
|
end
|
28
30
|
|
29
|
-
def
|
30
|
-
expr
|
31
|
+
def nodes
|
32
|
+
[expr]
|
33
|
+
end
|
34
|
+
|
35
|
+
def setup_rule(rule)
|
36
|
+
@index = rule.capts.length
|
37
|
+
rule.capts << self
|
38
|
+
end
|
39
|
+
|
40
|
+
def to_h
|
41
|
+
{
|
42
|
+
type: :capture,
|
43
|
+
expr: expr&.to_h,
|
44
|
+
}
|
31
45
|
end
|
32
46
|
end
|
33
47
|
end
|
@@ -3,13 +3,21 @@ class Packcr
|
|
3
3
|
class CharclassNode < Packcr::Node
|
4
4
|
attr_accessor :value
|
5
5
|
|
6
|
+
def initialize(value = nil)
|
7
|
+
@value = value
|
8
|
+
end
|
9
|
+
|
6
10
|
def debug_dump(indent = 0)
|
7
11
|
$stdout.print "#{" " * indent}Charclass(value:'"
|
8
12
|
Packcr.dump_escaped_string(value)
|
9
13
|
$stdout.print "')\n"
|
10
14
|
end
|
11
15
|
|
12
|
-
def
|
16
|
+
def reversible?(gen)
|
17
|
+
gen.lang == :rb && !gen.ascii
|
18
|
+
end
|
19
|
+
|
20
|
+
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
13
21
|
if gen.ascii
|
14
22
|
return generate_ascii_code(gen, onfail, indent, bare)
|
15
23
|
else
|
@@ -17,13 +25,22 @@ class Packcr
|
|
17
25
|
end
|
18
26
|
end
|
19
27
|
|
20
|
-
def
|
21
|
-
|
22
|
-
|
23
|
-
|
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
|
24
34
|
end
|
25
35
|
|
26
|
-
def
|
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
|
27
44
|
end
|
28
45
|
|
29
46
|
private
|
@@ -35,13 +52,20 @@ class Packcr
|
|
35
52
|
end
|
36
53
|
n = charclass&.length || 0
|
37
54
|
if charclass.nil? || n > 0
|
38
|
-
a = charclass && charclass[0] == '^'
|
39
|
-
i = a ? 1 : 0
|
40
55
|
gen.write Packcr.template("node/charclass_utf8.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
41
|
-
return Packcr::CODE_REACH__BOTH
|
42
56
|
else
|
43
57
|
gen.write Packcr.template("node/charclass_fail.#{gen.lang}.erb", binding, indent: indent)
|
44
|
-
|
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)
|
45
69
|
end
|
46
70
|
end
|
47
71
|
|
@@ -60,16 +84,20 @@ class Packcr
|
|
60
84
|
else
|
61
85
|
gen.write Packcr.template("node/charclass_one.#{gen.lang}.erb", binding, indent: indent)
|
62
86
|
end
|
63
|
-
return Packcr::CODE_REACH__BOTH
|
64
87
|
else
|
65
88
|
gen.write Packcr.template("node/charclass_fail.#{gen.lang}.erb", binding, indent: indent)
|
66
|
-
return Packcr::CODE_REACH__ALWAYS_FAIL
|
67
89
|
end
|
68
90
|
else
|
69
91
|
gen.write Packcr.template("node/charclass_any.#{gen.lang}.erb", binding, indent: indent)
|
70
|
-
return Packcr::CODE_REACH__BOTH
|
71
92
|
end
|
72
93
|
end
|
94
|
+
|
95
|
+
def to_h
|
96
|
+
{
|
97
|
+
type: :charclass,
|
98
|
+
value: value,
|
99
|
+
}
|
100
|
+
end
|
73
101
|
end
|
74
102
|
end
|
75
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
|
@@ -3,8 +3,11 @@ class Packcr
|
|
3
3
|
class ErrorNode < Packcr::Node
|
4
4
|
attr_accessor :expr, :code, :index, :vars, :capts
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
super
|
6
|
+
def initialize(expr = nil, code = nil, index = nil)
|
7
|
+
super()
|
8
|
+
@expr = expr
|
9
|
+
@code = code
|
10
|
+
@index = index
|
8
11
|
self.vars = []
|
9
12
|
self.capts = []
|
10
13
|
end
|
@@ -26,26 +29,41 @@ class Packcr
|
|
26
29
|
$stdout.print "#{" " * indent}}\n"
|
27
30
|
end
|
28
31
|
|
29
|
-
def generate_code(gen, onfail, indent, bare)
|
30
|
-
l = gen.next_label
|
31
|
-
m = gen.next_label
|
32
|
-
r, code = gen.generate_code_str(expr, l, 4, true)
|
32
|
+
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
33
33
|
gen.write Packcr.template("node/error.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
34
|
-
|
34
|
+
end
|
35
|
+
|
36
|
+
def reachability
|
37
|
+
expr.reachability
|
35
38
|
end
|
36
39
|
|
37
40
|
def verify_variables(vars)
|
38
41
|
@vars = vars
|
39
|
-
|
42
|
+
super
|
40
43
|
end
|
41
44
|
|
42
45
|
def verify_captures(ctx, capts)
|
43
46
|
@capts = capts
|
44
|
-
|
47
|
+
super
|
48
|
+
end
|
49
|
+
|
50
|
+
def nodes
|
51
|
+
[expr]
|
52
|
+
end
|
53
|
+
|
54
|
+
def setup_rule(rule)
|
55
|
+
@index = rule.codes.length
|
56
|
+
rule.codes.push(self)
|
45
57
|
end
|
46
58
|
|
47
|
-
def
|
48
|
-
|
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
|
+
}
|
49
67
|
end
|
50
68
|
end
|
51
69
|
end
|
@@ -3,18 +3,24 @@ class Packcr
|
|
3
3
|
class ExpandNode < Packcr::Node
|
4
4
|
attr_accessor :index, :line, :col
|
5
5
|
|
6
|
+
def initialize(index = nil, line = nil, col = nil)
|
7
|
+
@index = index
|
8
|
+
@line = line
|
9
|
+
@col = col
|
10
|
+
end
|
11
|
+
|
6
12
|
def debug_dump(indent = 0)
|
7
13
|
$stdout.print "#{" " * indent}Expand(index:"
|
8
14
|
Packcr.dump_integer_value(index)
|
9
15
|
$stdout.print ")\n"
|
10
16
|
end
|
11
17
|
|
12
|
-
def generate_code(gen, onfail, indent, bare)
|
18
|
+
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
13
19
|
gen.write Packcr.template("node/expand.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
14
|
-
return Packcr::CODE_REACH__BOTH
|
15
20
|
end
|
16
21
|
|
17
|
-
def
|
22
|
+
def reachability
|
23
|
+
return Packcr::CODE_REACH__BOTH
|
18
24
|
end
|
19
25
|
|
20
26
|
def verify_captures(ctx, capts)
|
@@ -29,7 +35,11 @@ class Packcr
|
|
29
35
|
end
|
30
36
|
end
|
31
37
|
|
32
|
-
def
|
38
|
+
def to_h
|
39
|
+
{
|
40
|
+
type: :expand,
|
41
|
+
index: index,
|
42
|
+
}
|
33
43
|
end
|
34
44
|
end
|
35
45
|
end
|
@@ -3,9 +3,10 @@ class Packcr
|
|
3
3
|
class PredicateNode < Packcr::Node
|
4
4
|
attr_accessor :neg, :expr
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
super
|
8
|
-
|
6
|
+
def initialize(expr = nil, neg = false)
|
7
|
+
super()
|
8
|
+
@expr = expr
|
9
|
+
@neg = neg
|
9
10
|
end
|
10
11
|
|
11
12
|
def debug_dump(indent = 0)
|
@@ -14,37 +15,32 @@ class Packcr
|
|
14
15
|
$stdout.print "#{" " * indent}}\n"
|
15
16
|
end
|
16
17
|
|
17
|
-
def generate_code(gen, onfail, indent, bare)
|
18
|
-
r = nil
|
18
|
+
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
19
19
|
if neg
|
20
|
-
l = gen.next_label
|
21
|
-
r, code = gen.generate_code_str(expr, l, 4, false)
|
22
20
|
gen.write Packcr.template("node/predicate_neg.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
23
|
-
case r
|
24
|
-
when Packcr::CODE_REACH__ALWAYS_SUCCEED
|
25
|
-
r = Packcr::CODE_REACH__ALWAYS_FAIL
|
26
|
-
when Packcr::CODE_REACH__ALWAYS_FAIL
|
27
|
-
r = Packcr::CODE_REACH__ALWAYS_SUCCEED
|
28
|
-
end
|
29
21
|
else
|
30
|
-
l = gen.next_label
|
31
|
-
m = gen.next_label
|
32
|
-
r, code = gen.generate_code_str(expr, l, 4, false)
|
33
22
|
gen.write Packcr.template("node/predicate.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
34
23
|
end
|
35
|
-
return r
|
36
24
|
end
|
37
25
|
|
38
|
-
def
|
39
|
-
|
26
|
+
def reachability
|
27
|
+
if neg
|
28
|
+
-expr.reachability
|
29
|
+
else
|
30
|
+
expr.reachability
|
31
|
+
end
|
40
32
|
end
|
41
33
|
|
42
|
-
def
|
43
|
-
expr
|
34
|
+
def nodes
|
35
|
+
[expr]
|
44
36
|
end
|
45
37
|
|
46
|
-
def
|
47
|
-
|
38
|
+
def to_h
|
39
|
+
{
|
40
|
+
type: :predicate,
|
41
|
+
expr: expr&.to_h,
|
42
|
+
neg: neg,
|
43
|
+
}
|
48
44
|
end
|
49
45
|
end
|
50
46
|
end
|
@@ -3,10 +3,11 @@ class Packcr
|
|
3
3
|
class QuantityNode < Packcr::Node
|
4
4
|
attr_accessor :min, :max, :expr
|
5
5
|
|
6
|
-
def initialize
|
7
|
-
super
|
8
|
-
|
9
|
-
|
6
|
+
def initialize(expr = nil, min = 0, max = 0)
|
7
|
+
super()
|
8
|
+
@expr = expr
|
9
|
+
@min = min
|
10
|
+
@max = max
|
10
11
|
end
|
11
12
|
|
12
13
|
def debug_dump(indent = 0)
|
@@ -15,40 +16,49 @@ class Packcr
|
|
15
16
|
$stdout.print "#{" " * indent}}\n"
|
16
17
|
end
|
17
18
|
|
18
|
-
def generate_code(gen, onfail, indent, bare)
|
19
|
+
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
19
20
|
if max > 1 || max < 0
|
20
|
-
r = nil
|
21
21
|
gen.write Packcr.template("node/quantify_many.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
22
|
+
elsif max == 1
|
23
|
+
if min > 0
|
24
|
+
gen.write gen.generate_code(expr, onfail, indent, bare)
|
25
|
+
else
|
26
|
+
gen.write Packcr.template("node/quantify_one.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def reachability
|
32
|
+
if max > 1 || max < 0
|
22
33
|
if min <= 0
|
23
34
|
return Packcr::CODE_REACH__ALWAYS_SUCCEED
|
24
35
|
end
|
25
|
-
if
|
36
|
+
if expr.reachability == Packcr::CODE_REACH__ALWAYS_FAIL
|
26
37
|
return Packcr::CODE_REACH__ALWAYS_FAIL
|
27
38
|
end
|
28
39
|
return Packcr::CODE_REACH__BOTH
|
29
40
|
elsif max == 1
|
30
41
|
if min > 0
|
31
|
-
return
|
42
|
+
return expr.reachability
|
32
43
|
else
|
33
|
-
gen.write Packcr.template("node/quantify_one.#{gen.lang}.erb", binding, indent: indent, unwrap: bare)
|
34
44
|
return Packcr::CODE_REACH__ALWAYS_SUCCEED
|
35
45
|
end
|
36
46
|
else
|
37
|
-
# no code to generate
|
38
47
|
return Packcr::CODE_REACH__ALWAYS_SUCCEED
|
39
48
|
end
|
40
49
|
end
|
41
50
|
|
42
|
-
def
|
43
|
-
expr
|
44
|
-
end
|
45
|
-
|
46
|
-
def verify_captures(ctx, capts)
|
47
|
-
expr.verify_captures(ctx, capts)
|
51
|
+
def nodes
|
52
|
+
[expr]
|
48
53
|
end
|
49
54
|
|
50
|
-
def
|
51
|
-
|
55
|
+
def to_h
|
56
|
+
{
|
57
|
+
type: :predicate,
|
58
|
+
expr: expr&.to_h,
|
59
|
+
min: min,
|
60
|
+
max: max,
|
61
|
+
}
|
52
62
|
end
|
53
63
|
end
|
54
64
|
end
|
@@ -3,17 +3,50 @@ class Packcr
|
|
3
3
|
class ReferenceNode < Packcr::Node
|
4
4
|
attr_accessor :var, :index, :name, :rule, :line, :col
|
5
5
|
|
6
|
+
def initialize(name = nil, var = nil, line = nil, col = nil)
|
7
|
+
@name = name
|
8
|
+
@var = var
|
9
|
+
@line = line
|
10
|
+
@col = col
|
11
|
+
end
|
12
|
+
|
6
13
|
def debug_dump(indent = 0)
|
7
14
|
$stdout.print "#{" " * indent}Reference(var:'#{var || "(null)"}', index:"
|
8
15
|
Packcr.dump_integer_value(index)
|
9
16
|
$stdout.print ", name:'#{name}', rule:'#{rule&.name || "(null)"}')\n"
|
10
17
|
end
|
11
18
|
|
12
|
-
def
|
19
|
+
def reversible?(gen)
|
20
|
+
gen.lang == :rb
|
21
|
+
end
|
22
|
+
|
23
|
+
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
13
24
|
gen.write Packcr.template("node/reference.#{gen.lang}.erb", binding, indent: indent)
|
25
|
+
end
|
26
|
+
|
27
|
+
def generate_reverse_code(gen, onsuccess, indent, bare, oncut: nil)
|
28
|
+
gen.write Packcr.template("node/reference_reverse.#{gen.lang}.erb", binding, indent: indent)
|
29
|
+
end
|
30
|
+
|
31
|
+
def reachability
|
14
32
|
Packcr::CODE_REACH__BOTH
|
15
33
|
end
|
16
34
|
|
35
|
+
def setup_rule(rule)
|
36
|
+
return unless var
|
37
|
+
i = rule.vars.index do |ref|
|
38
|
+
unless ref.is_a?(Packcr::Node::ReferenceNode)
|
39
|
+
raise "Unexpected node type: #{ref.class}"
|
40
|
+
end
|
41
|
+
var == ref.var
|
42
|
+
end
|
43
|
+
if !i
|
44
|
+
i = rule.vars.length
|
45
|
+
rule.vars << self
|
46
|
+
end
|
47
|
+
@index = i
|
48
|
+
end
|
49
|
+
|
17
50
|
def verify_variables(vars)
|
18
51
|
return if index.nil?
|
19
52
|
|
@@ -26,11 +59,8 @@ class Packcr
|
|
26
59
|
vars.push(self) if !found
|
27
60
|
end
|
28
61
|
|
29
|
-
def verify_captures(ctx, capts)
|
30
|
-
end
|
31
|
-
|
32
62
|
def link_references(ctx)
|
33
|
-
rule = ctx.rule(name)
|
63
|
+
rule = ctx.root.rule(name)
|
34
64
|
if !rule
|
35
65
|
ctx.error line + 1, col + 1, "No definition of rule '#{name}'"
|
36
66
|
else
|
@@ -41,6 +71,14 @@ class Packcr
|
|
41
71
|
self.rule = rule
|
42
72
|
end
|
43
73
|
end
|
74
|
+
|
75
|
+
def to_h
|
76
|
+
{
|
77
|
+
type: :reference,
|
78
|
+
name: name,
|
79
|
+
var: var,
|
80
|
+
}
|
81
|
+
end
|
44
82
|
end
|
45
83
|
end
|
46
84
|
end
|