packcr 0.0.6 → 0.0.7

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 (81) hide show
  1. checksums.yaml +4 -4
  2. data/lib/packcr/cli.rb +18 -16
  3. data/lib/packcr/code_block.rb +0 -1
  4. data/lib/packcr/context.rb +19 -17
  5. data/lib/packcr/generated/context.rb +440 -0
  6. data/lib/packcr/generated/node/action_node.rb +60 -0
  7. data/lib/packcr/generated/node/alternate_node.rb +98 -0
  8. data/lib/packcr/generated/node/capture_node.rb +39 -0
  9. data/lib/packcr/generated/node/charclass_node.rb +372 -0
  10. data/lib/packcr/generated/node/eof_node.rb +20 -0
  11. data/lib/packcr/generated/node/error_node.rb +67 -0
  12. data/lib/packcr/generated/node/expand_node.rb +30 -0
  13. data/lib/packcr/generated/node/predicate_node.rb +140 -0
  14. data/lib/packcr/generated/node/quantity_node.rb +167 -0
  15. data/lib/packcr/generated/node/reference_node.rb +70 -0
  16. data/lib/packcr/generated/node/rule_node.rb +63 -0
  17. data/lib/packcr/generated/node/sequence_node.rb +42 -0
  18. data/lib/packcr/generated/node/string_node.rb +60 -0
  19. data/lib/packcr/generator.rb +2 -1
  20. data/lib/packcr/node/action_node.rb +4 -2
  21. data/lib/packcr/node/alternate_node.rb +3 -1
  22. data/lib/packcr/node/capture_node.rb +3 -1
  23. data/lib/packcr/node/charclass_node.rb +24 -28
  24. data/lib/packcr/node/eof_node.rb +4 -2
  25. data/lib/packcr/node/error_node.rb +3 -1
  26. data/lib/packcr/node/expand_node.rb +8 -5
  27. data/lib/packcr/node/predicate_node.rb +4 -2
  28. data/lib/packcr/node/quantity_node.rb +12 -10
  29. data/lib/packcr/node/reference_node.rb +11 -5
  30. data/lib/packcr/node/root_node.rb +1 -0
  31. data/lib/packcr/node/rule_node.rb +7 -4
  32. data/lib/packcr/node/sequence_node.rb +3 -1
  33. data/lib/packcr/node/string_node.rb +9 -6
  34. data/lib/packcr/node.rb +3 -5
  35. data/lib/packcr/parser.rb +4375 -4056
  36. data/lib/packcr/stream.rb +17 -12
  37. data/lib/packcr/templates/context/source.c.erb +187 -410
  38. data/lib/packcr/templates/context/source.rb.erb +91 -156
  39. data/lib/packcr/templates/node/action.c.erb +3 -3
  40. data/lib/packcr/templates/node/action.rb.erb +2 -2
  41. data/lib/packcr/templates/node/alternate.c.erb +8 -8
  42. data/lib/packcr/templates/node/alternate.rb.erb +4 -5
  43. data/lib/packcr/templates/node/capture.c.erb +6 -6
  44. data/lib/packcr/templates/node/capture.rb.erb +4 -4
  45. data/lib/packcr/templates/node/charclass.c.erb +12 -12
  46. data/lib/packcr/templates/node/charclass.rb.erb +6 -6
  47. data/lib/packcr/templates/node/charclass_any.c.erb +3 -3
  48. data/lib/packcr/templates/node/charclass_any.rb.erb +2 -2
  49. data/lib/packcr/templates/node/charclass_fail.c.erb +1 -1
  50. data/lib/packcr/templates/node/charclass_one.c.erb +8 -8
  51. data/lib/packcr/templates/node/charclass_one.rb.erb +6 -6
  52. data/lib/packcr/templates/node/charclass_utf8.c.erb +7 -7
  53. data/lib/packcr/templates/node/charclass_utf8.rb.erb +3 -3
  54. data/lib/packcr/templates/node/charclass_utf8_reverse.rb.erb +5 -5
  55. data/lib/packcr/templates/node/eof.c.erb +1 -1
  56. data/lib/packcr/templates/node/error.c.erb +7 -7
  57. data/lib/packcr/templates/node/error.rb.erb +2 -2
  58. data/lib/packcr/templates/node/expand.c.erb +5 -5
  59. data/lib/packcr/templates/node/expand.rb.erb +3 -3
  60. data/lib/packcr/templates/node/predicate.c.erb +10 -10
  61. data/lib/packcr/templates/node/predicate.rb.erb +6 -6
  62. data/lib/packcr/templates/node/predicate_neg.c.erb +8 -8
  63. data/lib/packcr/templates/node/predicate_neg.rb.erb +6 -6
  64. data/lib/packcr/templates/node/{quantify_many.c.erb → quantity_many.c.erb} +11 -11
  65. data/lib/packcr/templates/node/{quantify_many.rb.erb → quantity_many.rb.erb} +9 -9
  66. data/lib/packcr/templates/node/{quantify_one.c.erb → quantity_one.c.erb} +7 -7
  67. data/lib/packcr/templates/node/{quantify_one.rb.erb → quantity_one.rb.erb} +4 -4
  68. data/lib/packcr/templates/node/reference.c.erb +14 -2
  69. data/lib/packcr/templates/node/reference.rb.erb +16 -4
  70. data/lib/packcr/templates/node/reference_reverse.rb.erb +16 -4
  71. data/lib/packcr/templates/node/rule.c.erb +9 -2
  72. data/lib/packcr/templates/node/rule.rb.erb +26 -19
  73. data/lib/packcr/templates/node/string_many.c.erb +5 -5
  74. data/lib/packcr/templates/node/string_many.rb.erb +3 -3
  75. data/lib/packcr/templates/node/string_one.c.erb +4 -4
  76. data/lib/packcr/templates/node/string_one.rb.erb +3 -3
  77. data/lib/packcr/util.rb +21 -16
  78. data/lib/packcr/version.rb +1 -1
  79. data/lib/packcr.rb +8 -11
  80. metadata +37 -9
  81. 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