packcr 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/packcr/cli.rb +18 -16
- data/lib/packcr/code_block.rb +0 -1
- data/lib/packcr/context.rb +19 -17
- data/lib/packcr/generated/context.rb +440 -0
- data/lib/packcr/generated/node/action_node.rb +60 -0
- data/lib/packcr/generated/node/alternate_node.rb +98 -0
- data/lib/packcr/generated/node/capture_node.rb +39 -0
- data/lib/packcr/generated/node/charclass_node.rb +372 -0
- data/lib/packcr/generated/node/eof_node.rb +20 -0
- data/lib/packcr/generated/node/error_node.rb +67 -0
- data/lib/packcr/generated/node/expand_node.rb +30 -0
- data/lib/packcr/generated/node/predicate_node.rb +140 -0
- data/lib/packcr/generated/node/quantity_node.rb +167 -0
- data/lib/packcr/generated/node/reference_node.rb +70 -0
- data/lib/packcr/generated/node/rule_node.rb +63 -0
- data/lib/packcr/generated/node/sequence_node.rb +42 -0
- data/lib/packcr/generated/node/string_node.rb +60 -0
- data/lib/packcr/generator.rb +2 -1
- data/lib/packcr/node/action_node.rb +4 -2
- data/lib/packcr/node/alternate_node.rb +3 -1
- data/lib/packcr/node/capture_node.rb +3 -1
- data/lib/packcr/node/charclass_node.rb +24 -28
- data/lib/packcr/node/eof_node.rb +4 -2
- data/lib/packcr/node/error_node.rb +3 -1
- data/lib/packcr/node/expand_node.rb +8 -5
- data/lib/packcr/node/predicate_node.rb +4 -2
- data/lib/packcr/node/quantity_node.rb +12 -10
- data/lib/packcr/node/reference_node.rb +11 -5
- data/lib/packcr/node/root_node.rb +1 -0
- data/lib/packcr/node/rule_node.rb +7 -4
- data/lib/packcr/node/sequence_node.rb +3 -1
- data/lib/packcr/node/string_node.rb +9 -6
- data/lib/packcr/node.rb +3 -5
- data/lib/packcr/parser.rb +4375 -4056
- data/lib/packcr/stream.rb +17 -12
- data/lib/packcr/templates/context/source.c.erb +187 -410
- data/lib/packcr/templates/context/source.rb.erb +91 -156
- data/lib/packcr/templates/node/action.c.erb +3 -3
- data/lib/packcr/templates/node/action.rb.erb +2 -2
- data/lib/packcr/templates/node/alternate.c.erb +8 -8
- data/lib/packcr/templates/node/alternate.rb.erb +4 -5
- data/lib/packcr/templates/node/capture.c.erb +6 -6
- data/lib/packcr/templates/node/capture.rb.erb +4 -4
- data/lib/packcr/templates/node/charclass.c.erb +12 -12
- data/lib/packcr/templates/node/charclass.rb.erb +6 -6
- data/lib/packcr/templates/node/charclass_any.c.erb +3 -3
- data/lib/packcr/templates/node/charclass_any.rb.erb +2 -2
- data/lib/packcr/templates/node/charclass_fail.c.erb +1 -1
- data/lib/packcr/templates/node/charclass_one.c.erb +8 -8
- data/lib/packcr/templates/node/charclass_one.rb.erb +6 -6
- data/lib/packcr/templates/node/charclass_utf8.c.erb +7 -7
- data/lib/packcr/templates/node/charclass_utf8.rb.erb +3 -3
- data/lib/packcr/templates/node/charclass_utf8_reverse.rb.erb +5 -5
- data/lib/packcr/templates/node/eof.c.erb +1 -1
- data/lib/packcr/templates/node/error.c.erb +7 -7
- data/lib/packcr/templates/node/error.rb.erb +2 -2
- data/lib/packcr/templates/node/expand.c.erb +5 -5
- data/lib/packcr/templates/node/expand.rb.erb +3 -3
- data/lib/packcr/templates/node/predicate.c.erb +10 -10
- data/lib/packcr/templates/node/predicate.rb.erb +6 -6
- data/lib/packcr/templates/node/predicate_neg.c.erb +8 -8
- data/lib/packcr/templates/node/predicate_neg.rb.erb +6 -6
- data/lib/packcr/templates/node/{quantify_many.c.erb → quantity_many.c.erb} +11 -11
- data/lib/packcr/templates/node/{quantify_many.rb.erb → quantity_many.rb.erb} +9 -9
- data/lib/packcr/templates/node/{quantify_one.c.erb → quantity_one.c.erb} +7 -7
- data/lib/packcr/templates/node/{quantify_one.rb.erb → quantity_one.rb.erb} +4 -4
- data/lib/packcr/templates/node/reference.c.erb +14 -2
- data/lib/packcr/templates/node/reference.rb.erb +16 -4
- data/lib/packcr/templates/node/reference_reverse.rb.erb +16 -4
- data/lib/packcr/templates/node/rule.c.erb +9 -2
- data/lib/packcr/templates/node/rule.rb.erb +26 -19
- data/lib/packcr/templates/node/string_many.c.erb +5 -5
- data/lib/packcr/templates/node/string_many.rb.erb +3 -3
- data/lib/packcr/templates/node/string_one.c.erb +4 -4
- data/lib/packcr/templates/node/string_one.rb.erb +3 -3
- data/lib/packcr/util.rb +21 -16
- data/lib/packcr/version.rb +1 -1
- data/lib/packcr.rb +8 -11
- metadata +37 -9
- data/lib/packcr/tokenizer.rb +0 -2948
@@ -0,0 +1,60 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class ActionNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "{\n pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_#{gen.rule.name}_#{index}, #{gen.rule.vars.length}, #{gen.rule.capts.length});\n".freeze
|
9
|
+
|
10
|
+
vars.each do |var|
|
11
|
+
erbout << " thunk->data.leaf.values.buf[#{var.index}] = &(chunk->values.buf[#{var.index}]);\n".freeze
|
12
|
+
end
|
13
|
+
capts.each do |capt|
|
14
|
+
erbout << " thunk->data.leaf.capts.buf[#{capt.index}] = &(chunk->capts.buf[#{capt.index}]);\n".freeze
|
15
|
+
end
|
16
|
+
erbout << " thunk->data.leaf.capt0.range.start = chunk->pos;\n thunk->data.leaf.capt0.range.end = ctx->position_offset;\n".freeze
|
17
|
+
|
18
|
+
if gen.location
|
19
|
+
erbout << " thunk->data.leaf.capt0.range.start_loc = chunk->pos_loc;\n thunk->data.leaf.capt0.range.end_loc = ctx->position_offset_loc;\n".freeze
|
20
|
+
end
|
21
|
+
erbout << " pcc_thunk_array__add(ctx->auxil, &chunk->thunks, thunk);\n}\n".freeze
|
22
|
+
|
23
|
+
erbout
|
24
|
+
when :rb
|
25
|
+
erbout = +""
|
26
|
+
erbout << "answer.thunks.push(\n ThunkLeaf.new(\n :action_#{gen.rule.name}_#{index},\n Capture.new(\n answer.pos, @position_offset,\n".freeze
|
27
|
+
|
28
|
+
if gen.location
|
29
|
+
erbout << " answer.pos_loc, @position_offset_loc,\n".freeze
|
30
|
+
end
|
31
|
+
erbout << " ),\n".freeze
|
32
|
+
|
33
|
+
if vars.empty?
|
34
|
+
erbout << " {},\n".freeze
|
35
|
+
|
36
|
+
else
|
37
|
+
erbout << " answer.values.slice(".freeze
|
38
|
+
vars.each_with_index do |var, i|
|
39
|
+
erbout << "#{", " if i > 0}#{var.index}".freeze
|
40
|
+
end
|
41
|
+
erbout << "),\n".freeze
|
42
|
+
end
|
43
|
+
if capts.empty?
|
44
|
+
erbout << " {},\n".freeze
|
45
|
+
|
46
|
+
else
|
47
|
+
erbout << " answer.capts.slice(".freeze
|
48
|
+
capts.each_with_index do |capt, i|
|
49
|
+
erbout << "#{", " if i > 0}#{capt.index}".freeze
|
50
|
+
end
|
51
|
+
erbout << "),\n".freeze
|
52
|
+
end
|
53
|
+
erbout << " )\n)\n".freeze
|
54
|
+
|
55
|
+
erbout
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class AlternateNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
m = gen.next_label
|
9
|
+
erbout << "{\n const size_t p = ctx->position_offset;\n".freeze
|
10
|
+
|
11
|
+
if gen.location
|
12
|
+
erbout << " const pcc_location_t p_loc = ctx->position_offset_loc;\n".freeze
|
13
|
+
end
|
14
|
+
erbout << " const size_t n = chunk->thunks.len;\n".freeze
|
15
|
+
|
16
|
+
nodes.each_with_index do |expr, i|
|
17
|
+
c = i + 1 < nodes.length
|
18
|
+
l = gen.next_label
|
19
|
+
r = expr.reachability
|
20
|
+
|
21
|
+
erbout << "#{gen.generate_code(expr, l, 4, false)}".freeze
|
22
|
+
case r
|
23
|
+
when Packcr::CODE_REACH__ALWAYS_SUCCEED
|
24
|
+
if c
|
25
|
+
erbout << " /* unreachable codes omitted */\n".freeze
|
26
|
+
end
|
27
|
+
break
|
28
|
+
when Packcr::CODE_REACH__BOTH
|
29
|
+
erbout << " goto L#{format("%04d", m)};\n".freeze
|
30
|
+
end
|
31
|
+
erbout << "L#{format("%04d", l)}:;\n ctx->position_offset = p;\n".freeze
|
32
|
+
|
33
|
+
if gen.location
|
34
|
+
erbout << " ctx->position_offset_loc = p_loc;\n".freeze
|
35
|
+
end
|
36
|
+
erbout << " pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n);\n".freeze
|
37
|
+
|
38
|
+
next if c
|
39
|
+
|
40
|
+
erbout << " goto L#{format("%04d", onfail)};\n".freeze
|
41
|
+
end
|
42
|
+
erbout << "L#{format("%04d", m)}:;\n}\n".freeze
|
43
|
+
|
44
|
+
erbout
|
45
|
+
when :rb
|
46
|
+
erbout = +""
|
47
|
+
m = gen.next_label
|
48
|
+
erbout << "catch(#{m}) do\n pos#{gen.level} = @position_offset\n".freeze
|
49
|
+
|
50
|
+
if gen.location
|
51
|
+
erbout << " p_loc#{gen.level} = @position_offset_loc\n".freeze
|
52
|
+
end
|
53
|
+
erbout << " n#{gen.level} = answer.thunks.length\n".freeze
|
54
|
+
|
55
|
+
nodes.each_with_index do |expr, i|
|
56
|
+
c = i + 1 < nodes.length
|
57
|
+
if expr.reversible?(gen)
|
58
|
+
|
59
|
+
erbout << "#{gen.generate_code(expr, m, 2, false, reverse: true, oncut: onfail)}".freeze
|
60
|
+
else
|
61
|
+
l = gen.next_label
|
62
|
+
erbout << " catch(#{l}) do\n".freeze
|
63
|
+
|
64
|
+
r = expr.reachability
|
65
|
+
|
66
|
+
erbout << "#{gen.generate_code(expr, l, 4, false, oncut: onfail)}".freeze
|
67
|
+
case r
|
68
|
+
when Packcr::CODE_REACH__ALWAYS_SUCCEED
|
69
|
+
if c
|
70
|
+
erbout << " # unreachable codes omitted\n".freeze
|
71
|
+
end
|
72
|
+
erbout << " end\n".freeze
|
73
|
+
|
74
|
+
break
|
75
|
+
when Packcr::CODE_REACH__BOTH
|
76
|
+
erbout << " throw(#{m})\n".freeze
|
77
|
+
end
|
78
|
+
erbout << " end\n".freeze
|
79
|
+
end
|
80
|
+
erbout << " @position_offset = pos#{gen.level}\n".freeze
|
81
|
+
|
82
|
+
if gen.location
|
83
|
+
erbout << " @position_offset_loc = p_loc#{gen.level}\n".freeze
|
84
|
+
end
|
85
|
+
erbout << " answer.thunks[n#{gen.level}..-1] = []\n".freeze
|
86
|
+
|
87
|
+
next if c
|
88
|
+
|
89
|
+
erbout << " throw(#{onfail})\n".freeze
|
90
|
+
end
|
91
|
+
erbout << "end\n".freeze
|
92
|
+
|
93
|
+
erbout
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class CaptureNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "{\n const size_t p = ctx->position_offset;\n size_t q;\n".freeze
|
9
|
+
|
10
|
+
if gen.location
|
11
|
+
erbout << " pcc_location_t p_loc = ctx->position_offset_loc;\n pcc_location_t q_loc;\n".freeze
|
12
|
+
end
|
13
|
+
erbout << "#{gen.generate_code(expr, onfail, 4, false)} q = ctx->position_offset;\n chunk->capts.buf[#{index}].range.start = p;\n chunk->capts.buf[#{index}].range.end = q;\n".freeze
|
14
|
+
|
15
|
+
if gen.location
|
16
|
+
erbout << " q_loc = ctx->position_offset_loc;\n chunk->capts.buf[#{index}].range.start_loc = p_loc;\n chunk->capts.buf[#{index}].range.end_loc = q_loc;\n".freeze
|
17
|
+
end
|
18
|
+
erbout << "}\n".freeze
|
19
|
+
|
20
|
+
erbout
|
21
|
+
when :rb
|
22
|
+
erbout = +""
|
23
|
+
erbout << "pos#{gen.level} = @position_offset\n".freeze
|
24
|
+
|
25
|
+
if gen.location
|
26
|
+
erbout << "p_loc#{gen.level} = @position_offset_loc\n".freeze
|
27
|
+
end
|
28
|
+
|
29
|
+
erbout << "#{gen.generate_code(expr, onfail, 0, false)}q#{gen.level} = @position_offset\ncapt#{gen.level} = answer.capts[#{index}]\ncapt#{gen.level}.range_start = pos#{gen.level}\ncapt#{gen.level}.range_end = q#{gen.level}\n".freeze
|
30
|
+
|
31
|
+
if gen.location
|
32
|
+
erbout << "q_loc#{gen.level} = @position_offset_loc\ncapt#{gen.level}.start_loc = p_loc#{gen.level}\ncapt#{gen.level}.end_loc = q_loc#{gen.level}\n".freeze
|
33
|
+
end
|
34
|
+
erbout
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,372 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class CharclassNode
|
4
|
+
def get_code(gen, onfail, indent, bare, charclass, n, a)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "{\n char c;\n if (pcc_refill_buffer(ctx, 1) < 1) goto L#{format("%04d", onfail)};\n c = ctx->buffer.buf[ctx->position_offset];\n".freeze
|
9
|
+
if !a && charclass =~ /\A[^\\]-.\z/
|
10
|
+
|
11
|
+
if a
|
12
|
+
erbout << " if (c >= '#{Packcr.escape_character(charclass[0])}' && c <= '#{Packcr.escape_character(charclass[2])}') goto L#{format("%04d", onfail)};\n".freeze
|
13
|
+
|
14
|
+
else
|
15
|
+
erbout << " if (!(c >= '#{Packcr.escape_character(charclass[0])}' && c <= '#{Packcr.escape_character(charclass[2])}')) goto L#{format("%04d", onfail)};\n".freeze
|
16
|
+
end
|
17
|
+
|
18
|
+
else
|
19
|
+
|
20
|
+
if a
|
21
|
+
erbout << " if (\n".freeze
|
22
|
+
|
23
|
+
else
|
24
|
+
erbout << " if (!(\n".freeze
|
25
|
+
end
|
26
|
+
i = 0
|
27
|
+
while i < n
|
28
|
+
if charclass[i] == "\\" && i + 1 < n
|
29
|
+
i += 1
|
30
|
+
end
|
31
|
+
if i + 2 < n && charclass[i + 1] == "-"
|
32
|
+
erbout << " (c >= '#{Packcr.escape_character(charclass[i])}' && c <= '#{Packcr.escape_character(charclass[i + 2])}')#{i + 3 == n ? "" : " ||"}\n".freeze
|
33
|
+
|
34
|
+
i += 2
|
35
|
+
else
|
36
|
+
erbout << " c == '#{Packcr.escape_character(charclass[i])}'#{i + 1 == n ? "" : " ||"}\n".freeze
|
37
|
+
end
|
38
|
+
i += 1
|
39
|
+
end
|
40
|
+
if a
|
41
|
+
erbout << " ) goto L#{format("%04d", onfail)};\n".freeze
|
42
|
+
|
43
|
+
else
|
44
|
+
erbout << " )) goto L#{format("%04d", onfail)};\n".freeze
|
45
|
+
end
|
46
|
+
end
|
47
|
+
if gen.location
|
48
|
+
erbout << " pcc_location_forward(&ctx->position_offset_loc, ctx->buffer.buf + ctx->position_offset, 1);\n".freeze
|
49
|
+
end
|
50
|
+
erbout << " ctx->position_offset++;\n}\n".freeze
|
51
|
+
|
52
|
+
erbout
|
53
|
+
when :rb
|
54
|
+
erbout = +""
|
55
|
+
erbout << "if refill_buffer(1) < 1\n throw(#{onfail})\nend\nc#{gen.level} = @buffer[@position_offset]\n".freeze
|
56
|
+
if !a && charclass =~ /\A[^\\]-.\z/
|
57
|
+
|
58
|
+
if a
|
59
|
+
erbout << "if c#{gen.level} >= \"#{Packcr.escape_character(charclass[0])}\" && c#{gen.level} <= \"#{Packcr.escape_character(charclass[2])}\"\n throw(#{onfail})\nend\n".freeze
|
60
|
+
|
61
|
+
else
|
62
|
+
erbout << "unless c#{gen.level} >= \"#{Packcr.escape_character(charclass[0])}\" && c#{gen.level} <= \"#{Packcr.escape_character(charclass[2])}\"\n throw(#{onfail})\nend\n".freeze
|
63
|
+
end
|
64
|
+
|
65
|
+
else
|
66
|
+
|
67
|
+
if a
|
68
|
+
erbout << "if (\n".freeze
|
69
|
+
|
70
|
+
else
|
71
|
+
erbout << "unless (\n".freeze
|
72
|
+
end
|
73
|
+
i = 0
|
74
|
+
while i < n
|
75
|
+
if charclass[i] == "\\" && i + 1 < n
|
76
|
+
i += 1
|
77
|
+
end
|
78
|
+
if i + 2 < n && charclass[i + 1] == "-"
|
79
|
+
erbout << " (c#{gen.level} >= \"#{Packcr.escape_character(charclass[i])}\" && c#{gen.level} <= \"#{Packcr.escape_character(charclass[i + 2])}\")#{i + 3 == n ? "" : " ||"}\n".freeze
|
80
|
+
|
81
|
+
i += 2
|
82
|
+
else
|
83
|
+
erbout << " c#{gen.level} == \"#{Packcr.escape_character(charclass[i])}\"#{i + 1 == n ? "" : " ||"}\n".freeze
|
84
|
+
end
|
85
|
+
i += 1
|
86
|
+
end
|
87
|
+
erbout << ")\n throw(#{onfail})\nend\n".freeze
|
88
|
+
|
89
|
+
end
|
90
|
+
if gen.location
|
91
|
+
erbout << "@position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, 1)\n".freeze
|
92
|
+
end
|
93
|
+
erbout << "@position_offset += 1\n".freeze
|
94
|
+
erbout
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def get_any_code(gen, onfail, indent, bare, charclass)
|
99
|
+
case gen.lang
|
100
|
+
when :c
|
101
|
+
erbout = +""
|
102
|
+
erbout << "if (pcc_refill_buffer(ctx, 1) < 1) goto L#{format("%04d", onfail)};\n".freeze
|
103
|
+
|
104
|
+
if gen.location
|
105
|
+
erbout << "pcc_location_forward(&ctx->position_offset, ctx->buffer.buf + ctx->position_offset, 1);\n".freeze
|
106
|
+
end
|
107
|
+
erbout << "ctx->position_offset++;\n".freeze
|
108
|
+
|
109
|
+
erbout
|
110
|
+
when :rb
|
111
|
+
erbout = +""
|
112
|
+
erbout << "if refill_buffer(1) < 1\n throw(#{onfail})\nend\n".freeze
|
113
|
+
|
114
|
+
if gen.location
|
115
|
+
erbout << "@position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, 1)\n".freeze
|
116
|
+
end
|
117
|
+
erbout << "@position_offset += 1\n".freeze
|
118
|
+
|
119
|
+
erbout
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
def get_fail_code(gen, onfail, indent, bare)
|
124
|
+
case gen.lang
|
125
|
+
when :c
|
126
|
+
erbout = +""
|
127
|
+
erbout << "goto L#{format("%04d", onfail)};\n".freeze
|
128
|
+
|
129
|
+
erbout
|
130
|
+
when :rb
|
131
|
+
erbout = +""
|
132
|
+
erbout << "throw(#{onfail})\n".freeze
|
133
|
+
|
134
|
+
erbout
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def get_one_code(gen, onfail, indent, bare, charclass, n, a)
|
139
|
+
case gen.lang
|
140
|
+
when :c
|
141
|
+
erbout = +""
|
142
|
+
if a
|
143
|
+
erbout << "if (\n pcc_refill_buffer(ctx, 1) < 1 ||\n ctx->buffer.buf[ctx->position_offset] == '#{Packcr.escape_character(charclass[i])}'\n) goto L#{format("%04d", onfail)};\n".freeze
|
144
|
+
|
145
|
+
else
|
146
|
+
erbout << "if (\n pcc_refill_buffer(ctx, 1) < 1 ||\n ctx->buffer.buf[ctx->position_offset] != '#{Packcr.escape_character(charclass[0])}'\n) goto L#{format("%04d", onfail)};\n".freeze
|
147
|
+
|
148
|
+
end
|
149
|
+
if gen.location
|
150
|
+
erbout << " pcc_location_forward(&ctx->position_offset_loc, ctx->buffer.buf + ctx->position_offset, 1);\n".freeze
|
151
|
+
end
|
152
|
+
erbout << "ctx->position_offset++;\n".freeze
|
153
|
+
erbout
|
154
|
+
when :rb
|
155
|
+
erbout = +""
|
156
|
+
if a
|
157
|
+
erbout << "if (\n refill_buffer(1) < 1 ||\n @buffer[@position_offset] == \"#{Packcr.escape_character(charclass[0])}\"\n)\n throw(#{onfail})\nend\n".freeze
|
158
|
+
|
159
|
+
else
|
160
|
+
erbout << "if (\n refill_buffer(1) < 1 ||\n @buffer[@position_offset] != \"#{Packcr.escape_character(charclass[0])}\"\n)\n throw(#{onfail})\nend\n".freeze
|
161
|
+
|
162
|
+
end
|
163
|
+
if gen.location
|
164
|
+
erbout << "@position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, 1)\n".freeze
|
165
|
+
end
|
166
|
+
erbout << "@position_offset += 1\n".freeze
|
167
|
+
erbout
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def get_utf8_code(gen, onfail, indent, bare, charclass, n)
|
172
|
+
case gen.lang
|
173
|
+
when :c
|
174
|
+
erbout = +""
|
175
|
+
a = charclass && charclass[0] == "^"
|
176
|
+
i = a ? 1 : 0
|
177
|
+
erbout << "{\n int u;\n const size_t n = pcc_get_char_as_utf32(ctx, &u);\n if (n == 0) goto L#{format("%04d", onfail)};\n".freeze
|
178
|
+
|
179
|
+
if charclass && !(a && n == 1) # not '.' or '[^]'
|
180
|
+
u0 = 0
|
181
|
+
r = false
|
182
|
+
if a
|
183
|
+
erbout << " if (\n".freeze
|
184
|
+
|
185
|
+
else
|
186
|
+
erbout << " if (!(\n".freeze
|
187
|
+
end
|
188
|
+
while i < n
|
189
|
+
if charclass[i] == "\\" && i + 1 < n
|
190
|
+
i += 1
|
191
|
+
end
|
192
|
+
u = charclass[i].ord
|
193
|
+
i += 1
|
194
|
+
if r
|
195
|
+
# character range
|
196
|
+
erbout << " (u >= 0x#{format("%06x", u0)} && u <= 0x#{format("%06x", u)})".freeze
|
197
|
+
if i < n
|
198
|
+
erbout << " ||".freeze
|
199
|
+
end
|
200
|
+
erbout << "\n".freeze
|
201
|
+
|
202
|
+
u0 = 0
|
203
|
+
r = false
|
204
|
+
elsif charclass[i] != "-" || i == n - 1 # the individual '-' character is valid when it is at the first or the last position
|
205
|
+
# single character
|
206
|
+
erbout << " u == 0x#{format("%06x", u)}".freeze
|
207
|
+
if i < n
|
208
|
+
erbout << " ||".freeze
|
209
|
+
end
|
210
|
+
erbout << "\n".freeze
|
211
|
+
|
212
|
+
u0 = 0
|
213
|
+
r = false
|
214
|
+
elsif charclass[i] == "-"
|
215
|
+
i += 1
|
216
|
+
u0 = u
|
217
|
+
r = true
|
218
|
+
else
|
219
|
+
raise "unexpected charclass #{charclass[i]}"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
if a
|
223
|
+
erbout << " ) goto L#{format("%04d", onfail)};\n".freeze
|
224
|
+
|
225
|
+
else
|
226
|
+
erbout << " )) goto L#{format("%04d", onfail)};\n".freeze
|
227
|
+
end
|
228
|
+
end
|
229
|
+
if gen.location
|
230
|
+
erbout << " pcc_location_forward(&ctx->position_offset_loc, ctx->buffer.buf + ctx->position_offset, n);\n".freeze
|
231
|
+
end
|
232
|
+
erbout << " ctx->position_offset += n;\n}\n".freeze
|
233
|
+
|
234
|
+
erbout
|
235
|
+
when :rb
|
236
|
+
erbout = +""
|
237
|
+
a = charclass && charclass[0] == "^"
|
238
|
+
i = a ? 1 : 0
|
239
|
+
erbout << "if refill_buffer(1) < 1\n throw(#{onfail})\nend\nu#{gen.level} = @buffer[@position_offset]\n".freeze
|
240
|
+
|
241
|
+
if charclass && !(a && n == 1) # not '.' or '[^]'
|
242
|
+
u0 = nil
|
243
|
+
r = false
|
244
|
+
if a
|
245
|
+
erbout << "if (\n".freeze
|
246
|
+
|
247
|
+
else
|
248
|
+
erbout << "if (!(\n".freeze
|
249
|
+
end
|
250
|
+
while i < n
|
251
|
+
if charclass[i] == "\\" && i + 1 < n
|
252
|
+
i += 1
|
253
|
+
end
|
254
|
+
u = charclass[i]
|
255
|
+
i += 1
|
256
|
+
if r
|
257
|
+
# character range
|
258
|
+
erbout << " (u#{gen.level} >= #{u0.dump} && u#{gen.level} <= #{u.dump})".freeze
|
259
|
+
if i < n
|
260
|
+
erbout << " ||".freeze
|
261
|
+
end
|
262
|
+
erbout << "\n".freeze
|
263
|
+
|
264
|
+
u0 = 0
|
265
|
+
r = false
|
266
|
+
elsif charclass[i] != "-" || i == n - 1 # the individual '-' character is valid when it is at the first or the last position
|
267
|
+
# single character
|
268
|
+
erbout << " u#{gen.level} == #{u.dump}".freeze
|
269
|
+
if i < n
|
270
|
+
erbout << " ||".freeze
|
271
|
+
end
|
272
|
+
erbout << "\n".freeze
|
273
|
+
|
274
|
+
u0 = 0
|
275
|
+
r = false
|
276
|
+
elsif charclass[i] == "-"
|
277
|
+
i += 1
|
278
|
+
u0 = u
|
279
|
+
r = true
|
280
|
+
else
|
281
|
+
raise "unexpected charclass #{charclass[i]}"
|
282
|
+
end
|
283
|
+
end
|
284
|
+
if a
|
285
|
+
erbout << ")\n".freeze
|
286
|
+
|
287
|
+
else
|
288
|
+
erbout << "))\n".freeze
|
289
|
+
end
|
290
|
+
erbout << " throw(#{onfail})\nend\n".freeze
|
291
|
+
end
|
292
|
+
if gen.location
|
293
|
+
erbout << "@position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, 1)\n".freeze
|
294
|
+
end
|
295
|
+
erbout << "@position_offset += 1\n".freeze
|
296
|
+
|
297
|
+
erbout
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
def get_utf8_reverse_code(gen, onsuccess, indent, bare, charclass, n)
|
302
|
+
case gen.lang
|
303
|
+
when :rb
|
304
|
+
erbout = +""
|
305
|
+
a = charclass && charclass[0] == "^"
|
306
|
+
i = a ? 1 : 0
|
307
|
+
erbout << "if refill_buffer(1) >= 1\n u#{gen.level} = @buffer[@position_offset]\n".freeze
|
308
|
+
|
309
|
+
if charclass && !(a && n == 1) # not '.' or '[^]'
|
310
|
+
u0 = nil
|
311
|
+
r = false
|
312
|
+
if a
|
313
|
+
erbout << " unless (\n".freeze
|
314
|
+
|
315
|
+
else
|
316
|
+
erbout << " if (\n".freeze
|
317
|
+
end
|
318
|
+
while i < n
|
319
|
+
if charclass[i] == "\\" && i + 1 < n
|
320
|
+
i += 1
|
321
|
+
end
|
322
|
+
u = charclass[i]
|
323
|
+
i += 1
|
324
|
+
if r
|
325
|
+
# character range
|
326
|
+
erbout << " (u#{gen.level} >= #{u0.dump} && u#{gen.level} <= #{u.dump})".freeze
|
327
|
+
if i < n
|
328
|
+
erbout << " ||".freeze
|
329
|
+
end
|
330
|
+
erbout << "\n".freeze
|
331
|
+
|
332
|
+
u0 = 0
|
333
|
+
r = false
|
334
|
+
elsif charclass[i] != "-" || i == n - 1 # the individual '-' character is valid when it is at the first or the last position
|
335
|
+
# single character
|
336
|
+
erbout << " u#{gen.level} == #{u.dump}".freeze
|
337
|
+
if i < n
|
338
|
+
erbout << " ||".freeze
|
339
|
+
end
|
340
|
+
erbout << "\n".freeze
|
341
|
+
|
342
|
+
u0 = 0
|
343
|
+
r = false
|
344
|
+
elsif charclass[i] == "-"
|
345
|
+
i += 1
|
346
|
+
u0 = u
|
347
|
+
r = true
|
348
|
+
else
|
349
|
+
raise "unexpected charclass #{charclass[i]}"
|
350
|
+
end
|
351
|
+
end
|
352
|
+
erbout << " )\n".freeze
|
353
|
+
|
354
|
+
if gen.location
|
355
|
+
erbout << " @position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, 1)\n".freeze
|
356
|
+
end
|
357
|
+
erbout << " @position_offset += 1\n throw(#{onsuccess})\n end\n".freeze
|
358
|
+
|
359
|
+
else # '.' or '[^]'
|
360
|
+
if gen.location
|
361
|
+
erbout << " @position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, 1)\n".freeze
|
362
|
+
end
|
363
|
+
erbout << " @position_offset += 1\n throw(#{onsuccess})\n".freeze
|
364
|
+
end
|
365
|
+
erbout << "end\n".freeze
|
366
|
+
|
367
|
+
erbout
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class EofNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "if (pcc_refill_buffer(ctx, 1) >= 1) goto L#{format("%04d", onfail)};\n".freeze
|
9
|
+
|
10
|
+
erbout
|
11
|
+
when :rb
|
12
|
+
erbout = +""
|
13
|
+
erbout << "if refill_buffer(1) >= 1\n throw(#{onfail})\nend\n".freeze
|
14
|
+
|
15
|
+
erbout
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class ErrorNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "{\n".freeze
|
9
|
+
|
10
|
+
l = gen.next_label
|
11
|
+
m = gen.next_label
|
12
|
+
|
13
|
+
erbout << "#{gen.generate_code(expr, l, 4, true)} goto L#{format("%04d", m)};\nL#{format("%04d", l)}:;\n {\n pcc_value_t null;\n pcc_thunk_t *const thunk = pcc_thunk__create_leaf(ctx->auxil, pcc_action_#{gen.rule.name}_#{index}, #{gen.rule.vars.length}, #{gen.rule.capts.length});\n".freeze
|
14
|
+
|
15
|
+
vars.each do |var|
|
16
|
+
erbout << " thunk->data.leaf.values.buf[#{var.index}] = &(chunk->values.buf[#{var.index}]);\n".freeze
|
17
|
+
end
|
18
|
+
capts.each do |capt|
|
19
|
+
erbout << " thunk->data.leaf.capts.buf[#{capt.index}] = &(chunk->capts.buf[#{capt.index}]);\n".freeze
|
20
|
+
end
|
21
|
+
erbout << " thunk->data.leaf.capt0.range.start = chunk->pos;\n thunk->data.leaf.capt0.range.end = ctx->position_offset;\n".freeze
|
22
|
+
|
23
|
+
if gen.location
|
24
|
+
erbout << " thunk->data.leaf.capt0.range.start_loc = chunk->pos_loc;\n thunk->data.leaf.capt0.range.end_loc = ctx->position_offset_loc;\n".freeze
|
25
|
+
end
|
26
|
+
erbout << " memset(&null, 0, sizeof(pcc_value_t)); /* in case */\n thunk->data.leaf.action(ctx, thunk, &null);\n pcc_thunk__destroy(ctx->auxil, thunk);\n }\n goto L#{format("%04d", onfail)};\nL#{format("%04d", m)}:;\n}\n".freeze
|
27
|
+
|
28
|
+
erbout
|
29
|
+
when :rb
|
30
|
+
erbout = +""
|
31
|
+
l = gen.next_label
|
32
|
+
m = gen.next_label
|
33
|
+
erbout << "catch(#{m}) do\n catch(#{l}) do\n#{gen.generate_code(expr, l, 4, false)} throw(#{m})\n end\n\n action_#{gen.rule.name}_#{index}(\n ThunkLeaf.new(\n :action_#{gen.rule.name}_#{index},\n Capture.new(\n answer.pos, @position_offset,\n".freeze
|
34
|
+
|
35
|
+
if gen.location
|
36
|
+
erbout << " answer.pos_loc,@position_offset_loc,\n".freeze
|
37
|
+
end
|
38
|
+
erbout << " ),\n".freeze
|
39
|
+
|
40
|
+
if vars.empty?
|
41
|
+
erbout << " {},\n".freeze
|
42
|
+
|
43
|
+
else
|
44
|
+
erbout << " answer.values.slice(".freeze
|
45
|
+
vars.each_with_index do |var, i|
|
46
|
+
erbout << "#{", " if i > 0}#{var.index}".freeze
|
47
|
+
end
|
48
|
+
erbout << "),\n".freeze
|
49
|
+
end
|
50
|
+
if capts.empty?
|
51
|
+
erbout << " {},\n".freeze
|
52
|
+
|
53
|
+
else
|
54
|
+
erbout << " answer.capts.slice(".freeze
|
55
|
+
capts.each_with_index do |capt, i|
|
56
|
+
erbout << "#{", " if i > 0}#{capt.index}".freeze
|
57
|
+
end
|
58
|
+
erbout << "),\n".freeze
|
59
|
+
end
|
60
|
+
erbout << " ),\n nil,\n 0\n )\n\n throw(#{onfail})\nend\n".freeze
|
61
|
+
|
62
|
+
erbout
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class ExpandNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "{\n const size_t n = chunk->capts.buf[#{index}].range.end - chunk->capts.buf[#{index}].range.start;\n if (pcc_refill_buffer(ctx, n) < n) goto L#{format("%04d", onfail)};\n if (n > 0) {\n const char *const p = ctx->buffer.buf + ctx->position_offset;\n const char *const q = ctx->buffer.buf + chunk->capts.buf[#{index}].range.start;\n size_t i;\n for (i = 0; i < n; i++) {\n if (p[i] != q[i]) goto L#{format("%04d", onfail)};\n }\n".freeze
|
9
|
+
|
10
|
+
if gen.location
|
11
|
+
erbout << " pcc_location_forward(&ctx->position_offset_loc, ctx->buffer.buf + ctx->position_offset, n);\n".freeze
|
12
|
+
end
|
13
|
+
erbout << " ctx->position_offset += n;\n }\n}\n".freeze
|
14
|
+
|
15
|
+
erbout
|
16
|
+
when :rb
|
17
|
+
erbout = +""
|
18
|
+
erbout << "capt#{gen.level} = answer.capts[#{index}]\nn#{gen.level} = capt#{gen.level}.range_end - capt#{gen.level}.range_start\nif refill_buffer(n#{gen.level}) < n#{gen.level}\n throw(#{onfail})\nend\nif n#{gen.level} > 0\n ptr#{gen.level} = @buffer[@position_offset, n#{gen.level}]\n q#{gen.level} = @buffer[capt#{gen.level}.range_start, n#{gen.level}]\n if ptr#{gen.level} != q#{gen.level}\n throw(#{onfail})\n end\n".freeze
|
19
|
+
|
20
|
+
if gen.location
|
21
|
+
erbout << " @position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, n#{gen.level})\n".freeze
|
22
|
+
end
|
23
|
+
erbout << " @position_offset += n#{gen.level}\nend\n".freeze
|
24
|
+
|
25
|
+
erbout
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|