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,140 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class PredicateNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
l = gen.next_label
|
9
|
+
m = gen.next_label
|
10
|
+
r = expr.reachability
|
11
|
+
erbout << "{\n const size_t p = ctx->position_offset;\n".freeze
|
12
|
+
|
13
|
+
if gen.location
|
14
|
+
erbout << " const pcc_location_t p_loc = ctx->position_offset_loc;\n".freeze
|
15
|
+
end
|
16
|
+
erbout << "#{gen.generate_code(expr, l, 4, false)}".freeze
|
17
|
+
if r != Packcr::CODE_REACH__ALWAYS_FAIL
|
18
|
+
erbout << " ctx->position_offset = p;\n".freeze
|
19
|
+
|
20
|
+
if gen.location
|
21
|
+
erbout << " ctx->position_offset_loc = p_loc;\n".freeze
|
22
|
+
end
|
23
|
+
end
|
24
|
+
if r == Packcr::CODE_REACH__BOTH
|
25
|
+
erbout << " goto L#{format("%04d", m)};\n".freeze
|
26
|
+
end
|
27
|
+
if r != Packcr::CODE_REACH__ALWAYS_SUCCEED
|
28
|
+
erbout << "L#{format("%04d", l)}:;\n ctx->position_offset = p;\n".freeze
|
29
|
+
|
30
|
+
if gen.location
|
31
|
+
erbout << " ctx->position_offset_loc = p_loc;\n".freeze
|
32
|
+
end
|
33
|
+
erbout << " goto L#{format("%04d", onfail)};\n".freeze
|
34
|
+
end
|
35
|
+
if r == Packcr::CODE_REACH__BOTH
|
36
|
+
erbout << "L#{format("%04d", m)}:;\n".freeze
|
37
|
+
end
|
38
|
+
erbout << "}\n".freeze
|
39
|
+
|
40
|
+
erbout
|
41
|
+
when :rb
|
42
|
+
erbout = +""
|
43
|
+
l = gen.next_label
|
44
|
+
m = gen.next_label
|
45
|
+
r = expr.reachability
|
46
|
+
erbout << "catch(#{m}) do\n pos#{gen.level} = @position_offset\n".freeze
|
47
|
+
|
48
|
+
if gen.location
|
49
|
+
erbout << " p_loc#{gen.level} = @position_offset_pos\n".freeze
|
50
|
+
end
|
51
|
+
erbout << " catch(#{l}) do\n#{gen.generate_code(expr, l, 4, false)}".freeze
|
52
|
+
if r != Packcr::CODE_REACH__ALWAYS_FAIL
|
53
|
+
erbout << " @position_offset = pos#{gen.level}\n".freeze
|
54
|
+
|
55
|
+
if gen.location
|
56
|
+
erbout << " @position_offset_loc = p_loc#{gen.level}\n".freeze
|
57
|
+
end
|
58
|
+
end
|
59
|
+
if r == Packcr::CODE_REACH__BOTH
|
60
|
+
erbout << " throw(#{m})\n".freeze
|
61
|
+
end
|
62
|
+
erbout << " end\n".freeze
|
63
|
+
|
64
|
+
if r != Packcr::CODE_REACH__ALWAYS_SUCCEED
|
65
|
+
erbout << " @position_offset = pos#{gen.level}\n".freeze
|
66
|
+
|
67
|
+
if gen.location
|
68
|
+
erbout << " @position_offset_loc = p_loc#{gen.level}\n".freeze
|
69
|
+
end
|
70
|
+
erbout << " throw(#{onfail})\n".freeze
|
71
|
+
end
|
72
|
+
erbout << "end\n".freeze
|
73
|
+
|
74
|
+
erbout
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_neg_code(gen, onfail, indent, bare, oncut)
|
79
|
+
case gen.lang
|
80
|
+
when :c
|
81
|
+
erbout = +""
|
82
|
+
l = gen.next_label
|
83
|
+
r = expr.reachability
|
84
|
+
erbout << "{\n const size_t p = ctx->position_offset;\n".freeze
|
85
|
+
|
86
|
+
if gen.location
|
87
|
+
erbout << " const pcc_location_t p_loc = ctx->position_offset_loc;\n".freeze
|
88
|
+
end
|
89
|
+
erbout << "#{gen.generate_code(expr, l, 4, false)}".freeze
|
90
|
+
if r != Packcr::CODE_REACH__ALWAYS_FAIL
|
91
|
+
erbout << " ctx->position_offset = p;\n".freeze
|
92
|
+
|
93
|
+
if gen.location
|
94
|
+
erbout << " ctx->position_offset_loc = p_loc;\n".freeze
|
95
|
+
end
|
96
|
+
erbout << " goto L#{format("%04d", onfail)};\n".freeze
|
97
|
+
end
|
98
|
+
if r != Packcr::CODE_REACH__ALWAYS_SUCCEED
|
99
|
+
erbout << "L#{format("%04d", l)}:;\n ctx->position_offset = p;\n".freeze
|
100
|
+
|
101
|
+
if gen.location
|
102
|
+
erbout << " ctx->position_offset_loc = p_loc;\n".freeze
|
103
|
+
end
|
104
|
+
end
|
105
|
+
erbout << "}\n".freeze
|
106
|
+
|
107
|
+
erbout
|
108
|
+
when :rb
|
109
|
+
erbout = +""
|
110
|
+
l = gen.next_label
|
111
|
+
r = expr.reachability
|
112
|
+
erbout << "pos#{gen.level} = @position_offset\n".freeze
|
113
|
+
|
114
|
+
if gen.location
|
115
|
+
erbout << "p_loc#{gen.level} = @position_offset_loc\n".freeze
|
116
|
+
end
|
117
|
+
erbout << "catch(#{l}) do\n#{gen.generate_code(expr, l, 2, false)}".freeze
|
118
|
+
if r != Packcr::CODE_REACH__ALWAYS_FAIL
|
119
|
+
erbout << " @position_offset = pos#{gen.level}\n".freeze
|
120
|
+
|
121
|
+
if gen.location
|
122
|
+
erbout << " @position_offset_loc = p_loc#{gen.level}\n".freeze
|
123
|
+
end
|
124
|
+
erbout << " throw(#{onfail})\n".freeze
|
125
|
+
end
|
126
|
+
erbout << "end\n".freeze
|
127
|
+
|
128
|
+
if r != Packcr::CODE_REACH__ALWAYS_SUCCEED
|
129
|
+
erbout << "@position_offset = pos#{gen.level}\n".freeze
|
130
|
+
|
131
|
+
if gen.location
|
132
|
+
erbout << "@position_offset_loc = p_loc#{gen.level}\n".freeze
|
133
|
+
end
|
134
|
+
end
|
135
|
+
erbout
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
end
|
@@ -0,0 +1,167 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class QuantityNode
|
4
|
+
def get_many_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "{\n".freeze
|
9
|
+
|
10
|
+
if min > 0
|
11
|
+
erbout << " const size_t p0 = ctx->position_offset;\n".freeze
|
12
|
+
|
13
|
+
if gen.location
|
14
|
+
erbout << " const pcc_location_t p0_loc = ctx->position_offset_loc;\n".freeze
|
15
|
+
end
|
16
|
+
erbout << " const size_t n0 = chunk->thunks.len;\n".freeze
|
17
|
+
end
|
18
|
+
erbout << " int i;\n".freeze
|
19
|
+
|
20
|
+
if max < 0
|
21
|
+
erbout << " for (i = 0;; i++) {\n".freeze
|
22
|
+
|
23
|
+
else
|
24
|
+
erbout << " for (i = 0; i < #{max}; i++) {\n".freeze
|
25
|
+
end
|
26
|
+
erbout << " const size_t p = ctx->position_offset;\n".freeze
|
27
|
+
|
28
|
+
if gen.location
|
29
|
+
erbout << " const pcc_location_t p_loc = ctx->position_offset_loc;\n".freeze
|
30
|
+
end
|
31
|
+
erbout << " const size_t n = chunk->thunks.len;\n".freeze
|
32
|
+
|
33
|
+
l = gen.next_label
|
34
|
+
r = expr.reachability
|
35
|
+
erbout << "#{gen.generate_code(expr, l, 8, false)} if (ctx->position_offset == p) break;\n".freeze
|
36
|
+
|
37
|
+
if r != Packcr::CODE_REACH__ALWAYS_SUCCEED
|
38
|
+
erbout << " continue;\n L#{format("%04d", l)}:;\n ctx->position_offset = p;\n".freeze
|
39
|
+
|
40
|
+
if gen.location
|
41
|
+
erbout << " ctx->position_offset_loc = p_loc;\n".freeze
|
42
|
+
end
|
43
|
+
erbout << " pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n);\n break;\n".freeze
|
44
|
+
end
|
45
|
+
erbout << " }\n".freeze
|
46
|
+
|
47
|
+
if min > 0
|
48
|
+
erbout << " if (i < #{min}) {\n ctx->position_offset = p0;\n".freeze
|
49
|
+
|
50
|
+
if gen.location
|
51
|
+
erbout << " ctx->position_offset_loc = p0_loc;\n".freeze
|
52
|
+
end
|
53
|
+
erbout << " pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n0);\n goto L#{format("%04d", onfail)};\n }\n".freeze
|
54
|
+
end
|
55
|
+
erbout << "}\n".freeze
|
56
|
+
|
57
|
+
erbout
|
58
|
+
when :rb
|
59
|
+
erbout = +""
|
60
|
+
if min > 0
|
61
|
+
erbout << "q#{gen.level} = @position_offset\n".freeze
|
62
|
+
|
63
|
+
if gen.location
|
64
|
+
erbout << "q_loc#{gen.level} = @position_offset_loc\n".freeze
|
65
|
+
end
|
66
|
+
erbout << "m#{gen.level} = answer.thunks.length\n".freeze
|
67
|
+
end
|
68
|
+
erbout << "i#{gen.level} = 0\npos#{gen.level} = nil\n".freeze
|
69
|
+
|
70
|
+
if gen.location
|
71
|
+
erbout << "p_loc#{gen.level} = nil\n".freeze
|
72
|
+
end
|
73
|
+
erbout << "n#{gen.level} = nil\n".freeze
|
74
|
+
|
75
|
+
l = gen.next_label
|
76
|
+
erbout << "catch(#{l}) do\n pos#{gen.level} = @position_offset\n".freeze
|
77
|
+
|
78
|
+
if gen.location
|
79
|
+
erbout << " p_loc#{gen.level} = @position_offset_loc\n".freeze
|
80
|
+
end
|
81
|
+
erbout << " n#{gen.level} = answer.thunks.length\n".freeze
|
82
|
+
|
83
|
+
r = expr.reachability
|
84
|
+
|
85
|
+
erbout << "#{gen.generate_code(expr, l, 2, false)} i#{gen.level} += 1\n if @position_offset != pos#{gen.level}".freeze
|
86
|
+
if max >= 0
|
87
|
+
erbout << " || i#{gen.level} < #{max}".freeze
|
88
|
+
end
|
89
|
+
erbout << "\n redo\n end\n pos#{gen.level} = nil\nend\n".freeze
|
90
|
+
|
91
|
+
if r != Packcr::CODE_REACH__ALWAYS_SUCCEED
|
92
|
+
erbout << "if pos#{gen.level}\n @position_offset = pos#{gen.level}\n".freeze
|
93
|
+
|
94
|
+
if gen.location
|
95
|
+
erbout << " @position_offset_loc = p_loc#{gen.level}\n".freeze
|
96
|
+
end
|
97
|
+
erbout << " answer.thunks[n#{gen.level}..-1] = []\nend\n".freeze
|
98
|
+
end
|
99
|
+
if min > 0
|
100
|
+
erbout << "if i#{gen.level} < #{min}\n @position_offset = q#{gen.level}\n".freeze
|
101
|
+
|
102
|
+
if gen.location
|
103
|
+
erbout << " @position_offset_loc = q_loc#{gen.level}\n".freeze
|
104
|
+
end
|
105
|
+
erbout << " answer.thunks[m#{gen.level}..-1] = []\n throw(#{onfail})\nend\n".freeze
|
106
|
+
end
|
107
|
+
erbout
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def get_one_code(gen, onfail, indent, bare, oncut)
|
112
|
+
case gen.lang
|
113
|
+
when :c
|
114
|
+
erbout = +""
|
115
|
+
erbout << "{\n".freeze
|
116
|
+
|
117
|
+
l = gen.next_label
|
118
|
+
erbout << " const size_t p = ctx->position_offset;\n".freeze
|
119
|
+
|
120
|
+
if gen.location
|
121
|
+
erbout << " const pcc_location_t p_loc = ctx->position_offset_loc;\n".freeze
|
122
|
+
end
|
123
|
+
erbout << " const size_t n = chunk->thunks.len;\n".freeze
|
124
|
+
|
125
|
+
r = expr.reachability
|
126
|
+
erbout << "#{gen.generate_code(expr, l, 4, false)}".freeze
|
127
|
+
if r != Packcr::CODE_REACH__ALWAYS_SUCCEED
|
128
|
+
m = gen.next_label
|
129
|
+
erbout << " goto L#{format("%04d", m)};\nL#{format("%04d", l)}:;\n".freeze
|
130
|
+
|
131
|
+
if gen.location
|
132
|
+
erbout << " ctx->position_offset_loc = p_loc;\n".freeze
|
133
|
+
end
|
134
|
+
erbout << " ctx->position_offset = p;\n pcc_thunk_array__revert(ctx->auxil, &chunk->thunks, n);\nL#{format("%04d", m)}:;\n".freeze
|
135
|
+
end
|
136
|
+
erbout << "}\n".freeze
|
137
|
+
|
138
|
+
erbout
|
139
|
+
when :rb
|
140
|
+
erbout = +""
|
141
|
+
l = gen.next_label
|
142
|
+
erbout << "pos#{gen.level} = @position_offset\n".freeze
|
143
|
+
|
144
|
+
if gen.location
|
145
|
+
erbout << "p_loc#{gen.level} = @position_offset_loc\n".freeze
|
146
|
+
end
|
147
|
+
erbout << "n#{gen.level} = answer.thunks.length\n".freeze
|
148
|
+
|
149
|
+
r = expr.reachability
|
150
|
+
if r == Packcr::CODE_REACH__ALWAYS_SUCCEED
|
151
|
+
|
152
|
+
erbout << "#{gen.generate_code(expr, l, 0, false)}".freeze
|
153
|
+
else
|
154
|
+
m = gen.next_label
|
155
|
+
erbout << "catch(#{m}) do\n catch(#{l}) do\n#{gen.generate_code(expr, l, 4, false)} throw(#{m})\n end\n".freeze
|
156
|
+
|
157
|
+
if gen.location
|
158
|
+
erbout << " @position_offset_loc = p_loc#{gen.level}\n".freeze
|
159
|
+
end
|
160
|
+
erbout << " @position_offset = pos#{gen.level}\n answer.thunks[n#{gen.level}..-1] = []\nend\n".freeze
|
161
|
+
end
|
162
|
+
erbout
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class ReferenceNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
if index.nil?
|
9
|
+
erbout << "{\n pcc_rule_set_t *l = NULL;\n if (limits && ctx->position_offset == offset && pcc_rule_set__index(ctx->auxil, limits, pcc_evaluate_rule_#{name}) == PCC_VOID_VALUE) {\n l = limits;\n }\n if (!pcc_apply_rule(ctx, pcc_evaluate_rule_#{name}, &chunk->thunks, NULL, offset".freeze
|
10
|
+
else
|
11
|
+
erbout << "{\n pcc_rule_set_t *l = NULL;\n if (limits && ctx->position_offset == offset && pcc_rule_set__index(ctx->auxil, limits, pcc_evaluate_rule_#{name}) == PCC_VOID_VALUE) {\n l = limits;\n }\n if (!pcc_apply_rule(ctx, pcc_evaluate_rule_#{name}, &chunk->thunks, &(chunk->values.buf[#{index}]), offset".freeze
|
12
|
+
|
13
|
+
end
|
14
|
+
if gen.location
|
15
|
+
erbout << ", offset_loc".freeze
|
16
|
+
end
|
17
|
+
erbout << ", l)) goto L#{format("%04d", onfail)};\n}\n".freeze
|
18
|
+
erbout
|
19
|
+
when :rb
|
20
|
+
erbout = +""
|
21
|
+
if index.nil?
|
22
|
+
erbout << "if limits && @position_offset == offset && !limits[:evaluate_rule_#{name}]\n if !apply_rule(:evaluate_rule_#{name}, answer.thunks, nil, 0, offset".freeze
|
23
|
+
if gen.location
|
24
|
+
erbout << ", offset_loc".freeze
|
25
|
+
end
|
26
|
+
erbout << ", limits: limits)\n throw(#{onfail})\n end\nelse\n if !apply_rule(:evaluate_rule_#{name}, answer.thunks, nil, 0, offset".freeze
|
27
|
+
else
|
28
|
+
erbout << "if limits && @position_offset == offset && !limits[:evaluate_rule_#{name}]\n if !apply_rule(:evaluate_rule_#{name}, answer.thunks, answer.values, #{index}, offset".freeze
|
29
|
+
if gen.location
|
30
|
+
erbout << ", offset_loc".freeze
|
31
|
+
end
|
32
|
+
erbout << ", limits: limits)\n throw(#{onfail})\n end\nelse\n if !apply_rule(:evaluate_rule_#{name}, answer.thunks, answer.values, #{index}, offset".freeze
|
33
|
+
|
34
|
+
end
|
35
|
+
if gen.location
|
36
|
+
erbout << ", offset_loc".freeze
|
37
|
+
end
|
38
|
+
erbout << ")\n throw(#{onfail})\n end\nend\n".freeze
|
39
|
+
erbout
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def get_reverse_code(gen, onsuccess, indent, bare, oncut)
|
44
|
+
case gen.lang
|
45
|
+
when :rb
|
46
|
+
erbout = +""
|
47
|
+
if index.nil?
|
48
|
+
erbout << "if limits && @position_offset == offset && !limits[:evaluate_rule_#{name}]\n if apply_rule(:evaluate_rule_#{name}, answer.thunks, nil, 0, offset".freeze
|
49
|
+
if gen.location
|
50
|
+
erbout << ", offset_loc".freeze
|
51
|
+
end
|
52
|
+
erbout << ", limits: limits)\n throw(#{onsuccess})\n end\nelse\n if apply_rule(:evaluate_rule_#{name}, answer.thunks, nil, 0, offset".freeze
|
53
|
+
else
|
54
|
+
erbout << "if limits && @position_offset == offset && !limits[:evaluate_rule_#{name}]\n if apply_rule(:evaluate_rule_#{name}, answer.thunks, answer.values, #{index}, offset".freeze
|
55
|
+
if gen.location
|
56
|
+
erbout << ", offset_loc".freeze
|
57
|
+
end
|
58
|
+
erbout << ", limits: limits)\n throw(#{onsuccess})\n end\nelse\n if apply_rule(:evaluate_rule_#{name}, answer.thunks, answer.values, #{index}, offset".freeze
|
59
|
+
|
60
|
+
end
|
61
|
+
if gen.location
|
62
|
+
erbout << ", offset_loc".freeze
|
63
|
+
end
|
64
|
+
erbout << ")\n throw(#{onsuccess})\n end\nend\n".freeze
|
65
|
+
erbout
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class RuleNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "static pcc_thunk_chunk_t *pcc_evaluate_rule_#{name}(pcc_context_t *ctx, size_t offset".freeze
|
9
|
+
if gen.location
|
10
|
+
erbout << ", pcc_location_t offset_loc".freeze
|
11
|
+
end
|
12
|
+
erbout << ", pcc_rule_set_t *limits) {\n pcc_thunk_chunk_t *const chunk = pcc_thunk_chunk__create(ctx);\n chunk->pos = ctx->position_offset;\n".freeze
|
13
|
+
|
14
|
+
if gen.location
|
15
|
+
erbout << " chunk->pos_loc = ctx->position_offset_loc;\n".freeze
|
16
|
+
end
|
17
|
+
erbout << " PCC_DEBUG(ctx->auxil, PCC_DBG_EVALUATE, \"#{name}\", ctx->level, chunk->pos, (ctx->buffer.buf + chunk->pos), (ctx->buffer.len - chunk->pos));\n ctx->level++;\n pcc_value_table__resize(ctx->auxil, &chunk->values, #{vars.length});\n pcc_capture_table__resize(ctx->auxil, &chunk->capts, #{capts.length});\n".freeze
|
18
|
+
|
19
|
+
if !vars.empty?
|
20
|
+
erbout << " pcc_value_table__clear(ctx->auxil, &chunk->values);\n".freeze
|
21
|
+
end
|
22
|
+
r = expr.reachability
|
23
|
+
|
24
|
+
erbout << "#{gen.generate_code(expr, 0, 4, false)} ctx->level--;\n PCC_DEBUG(ctx->auxil, PCC_DBG_MATCH, \"#{name}\", ctx->level, chunk->pos, (ctx->buffer.buf + chunk->pos), (ctx->position_offset - chunk->pos));\n return chunk;\n".freeze
|
25
|
+
|
26
|
+
if r != Packcr::CODE_REACH__ALWAYS_SUCCEED
|
27
|
+
erbout << "L0000:;\n ctx->level--;\n PCC_DEBUG(ctx->auxil, PCC_DBG_NOMATCH, \"#{name}\", ctx->level, chunk->pos, (ctx->buffer.buf + chunk->pos), (ctx->position_offset - chunk->pos));\n pcc_thunk_chunk__destroy(ctx, chunk);\n return NULL;\n".freeze
|
28
|
+
end
|
29
|
+
erbout << "}\n".freeze
|
30
|
+
|
31
|
+
erbout
|
32
|
+
when :rb
|
33
|
+
erbout = +""
|
34
|
+
erbout << "def evaluate_rule_#{name}(offset".freeze
|
35
|
+
if gen.location
|
36
|
+
erbout << ", offset_loc".freeze
|
37
|
+
end
|
38
|
+
erbout << ", limits: nil)\n answer = ThunkChunk.new\n answer.pos = @position_offset\n".freeze
|
39
|
+
|
40
|
+
if gen.location
|
41
|
+
erbout << " answer.pos_loc = @position_offset_loc\n".freeze
|
42
|
+
end
|
43
|
+
erbout << " debug { warn \"\#{ \" \" * @level}EVAL #{name} \#{answer.pos} \#{@buffer[answer.pos..-1].inspect}\" }\n @level += 1\n answer.resize_captures(#{capts.length})\n".freeze
|
44
|
+
|
45
|
+
if !vars.empty?
|
46
|
+
erbout << " answer.values = {}\n".freeze
|
47
|
+
end
|
48
|
+
r = expr.reachability
|
49
|
+
if r == Packcr::CODE_REACH__ALWAYS_SUCCEED
|
50
|
+
|
51
|
+
erbout << "#{gen.generate_code(expr, 0, 2, false)} @level -= 1\n debug { warn \"\#{ \" \" * @level}MATCH #{name} \#{answer.pos} \#{@buffer[answer.pos...@position_offset].inspect}\" }\n return answer\n".freeze
|
52
|
+
|
53
|
+
else
|
54
|
+
erbout << " catch(0) do\n#{gen.generate_code(expr, 0, 4, false)} @level -= 1\n debug { warn \"\#{ \" \" * @level}MATCH #{name} \#{answer.pos} \#{@buffer[answer.pos...@position_offset].inspect}\" }\n return answer\n end\n @level -= 1\n debug { warn \"\#{ \" \" * @level}NOMATCH #{name} \#{answer.pos} \#{@buffer[answer.pos...@position_offset].inspect}\" }\n return nil\n".freeze
|
55
|
+
end
|
56
|
+
erbout << "end\n".freeze
|
57
|
+
|
58
|
+
erbout
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class SequenceNode
|
4
|
+
def get_code(gen, onfail, indent, bare, oncut)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
if @cut && oncut
|
9
|
+
onfail = oncut
|
10
|
+
oncut = nil
|
11
|
+
end
|
12
|
+
nodes.each_with_index do |expr, i|
|
13
|
+
erbout << "#{gen.generate_code(expr, onfail, 0, false, oncut: oncut)}".freeze
|
14
|
+
next unless expr.reachability == Packcr::CODE_REACH__ALWAYS_FAIL
|
15
|
+
|
16
|
+
if i + 1 < nodes.length
|
17
|
+
erbout << "/* unreachable codes omitted */\n".freeze
|
18
|
+
end
|
19
|
+
break
|
20
|
+
end
|
21
|
+
erbout
|
22
|
+
when :rb
|
23
|
+
erbout = +""
|
24
|
+
if @cut && oncut
|
25
|
+
onfail = oncut
|
26
|
+
oncut = nil
|
27
|
+
end
|
28
|
+
nodes.each_with_index do |expr, i|
|
29
|
+
erbout << "#{gen.generate_code(expr, onfail, 0, false, oncut: oncut)}".freeze
|
30
|
+
next unless expr.reachability == Packcr::CODE_REACH__ALWAYS_FAIL
|
31
|
+
|
32
|
+
if i + 1 < nodes.length
|
33
|
+
erbout << "# unreachable codes omitted\n".freeze
|
34
|
+
end
|
35
|
+
break
|
36
|
+
end
|
37
|
+
erbout
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Node
|
3
|
+
class StringNode
|
4
|
+
def get_many_code(gen, onfail, indent, bare, oncut, n)
|
5
|
+
case gen.lang
|
6
|
+
when :c
|
7
|
+
erbout = +""
|
8
|
+
erbout << "if (\n pcc_refill_buffer(ctx, #{n}) < #{n} ||\n".freeze
|
9
|
+
|
10
|
+
(n - 1).times do |i|
|
11
|
+
erbout << " (ctx->buffer.buf + ctx->position_offset)[#{i}] != '#{Packcr.escape_character(value[i])}' ||\n".freeze
|
12
|
+
end
|
13
|
+
erbout << " (ctx->buffer.buf + ctx->position_offset)[#{n - 1}] != '#{Packcr.escape_character(value[n - 1])}'\n) goto L#{format("%04d", onfail)};\n".freeze
|
14
|
+
|
15
|
+
if gen.location
|
16
|
+
erbout << "pcc_location_forward(&ctx->position_offset_loc, ctx->buffer.buf + ctx->position_offset, n);\n".freeze
|
17
|
+
end
|
18
|
+
erbout << "ctx->position_offset += #{n};\n".freeze
|
19
|
+
|
20
|
+
erbout
|
21
|
+
when :rb
|
22
|
+
erbout = +""
|
23
|
+
erbout << "if (\n refill_buffer(#{n}) < #{n} ||\n @buffer[@position_offset, #{n}] != #{value[0, n].dump}\n)\n throw(#{onfail})\nend\n".freeze
|
24
|
+
|
25
|
+
if gen.location
|
26
|
+
erbout << "@position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, #{n})\n".freeze
|
27
|
+
end
|
28
|
+
erbout << "@position_offset += #{n}\n".freeze
|
29
|
+
|
30
|
+
erbout
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
def get_one_code(gen, onfail, indent, bare, oncut, n)
|
35
|
+
case gen.lang
|
36
|
+
when :c
|
37
|
+
erbout = +""
|
38
|
+
erbout << "if (\n pcc_refill_buffer(ctx, 1) < 1 ||\n ctx->buffer.buf[ctx->position_offset] != '#{Packcr.escape_character(value[0])}'\n) goto L#{format("%04d", onfail)};\n".freeze
|
39
|
+
|
40
|
+
if gen.location
|
41
|
+
erbout << " pcc_location_forward(&ctx->position_offset_loc, ctx->buffer.buf + ctx->position_offset, 1);\n".freeze
|
42
|
+
end
|
43
|
+
erbout << "ctx->position_offset++;\n".freeze
|
44
|
+
|
45
|
+
erbout
|
46
|
+
when :rb
|
47
|
+
erbout = +""
|
48
|
+
erbout << "if (\n refill_buffer(1) < 1 ||\n @buffer[@position_offset] != \"#{Packcr.escape_character(value[0])}\"\n)\n throw(#{onfail})\nend\n".freeze
|
49
|
+
|
50
|
+
if gen.location
|
51
|
+
erbout << "@position_offset_loc = @position_offset_loc.forward(@buffer, @position_offset, 1)\n".freeze
|
52
|
+
end
|
53
|
+
erbout << "@position_offset += 1\n".freeze
|
54
|
+
|
55
|
+
erbout
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
data/lib/packcr/generator.rb
CHANGED
@@ -34,7 +34,7 @@ class Packcr
|
|
34
34
|
end
|
35
35
|
|
36
36
|
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
37
|
-
gen.write Packcr.
|
37
|
+
gen.write Packcr.format_code(get_code(gen, onfail, indent, bare, oncut), indent: indent, unwrap: bare)
|
38
38
|
end
|
39
39
|
|
40
40
|
def reachability
|
@@ -45,7 +45,7 @@ class Packcr
|
|
45
45
|
@vars = vars
|
46
46
|
end
|
47
47
|
|
48
|
-
def verify_captures(
|
48
|
+
def verify_captures(_ctx, capts)
|
49
49
|
@capts = capts
|
50
50
|
end
|
51
51
|
|
@@ -65,3 +65,5 @@ class Packcr
|
|
65
65
|
end
|
66
66
|
end
|
67
67
|
end
|
68
|
+
|
69
|
+
require "packcr/generated/node/action_node"
|
@@ -28,7 +28,7 @@ class Packcr
|
|
28
28
|
end
|
29
29
|
|
30
30
|
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
31
|
-
gen.write Packcr.
|
31
|
+
gen.write Packcr.format_code(get_code(gen, onfail, indent, bare, oncut), indent: indent, unwrap: bare)
|
32
32
|
end
|
33
33
|
|
34
34
|
def reachability
|
@@ -82,3 +82,5 @@ class Packcr
|
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
85
|
+
|
86
|
+
require "packcr/generated/node/alternate_node"
|
@@ -16,7 +16,7 @@ class Packcr
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def generate_code(gen, onfail, indent, bare, oncut: nil)
|
19
|
-
gen.write Packcr.
|
19
|
+
gen.write Packcr.format_code(get_code(gen, onfail, indent, bare, oncut), indent: indent)
|
20
20
|
end
|
21
21
|
|
22
22
|
def reachability
|
@@ -46,3 +46,5 @@ class Packcr
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
|
+
|
50
|
+
require "packcr/generated/node/capture_node"
|