packcr 0.1.0 → 0.1.1
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/README.md +1 -1
- data/lib/packcr/generated/context.rb +8 -13
- data/lib/packcr/generated/node/action_node.rb +4 -6
- data/lib/packcr/generated/node/alternate_node.rb +11 -17
- data/lib/packcr/generated/node/capture_node.rb +1 -1
- data/lib/packcr/generated/node/charclass_node.rb +8 -8
- data/lib/packcr/generated/node/eof_node.rb +1 -1
- data/lib/packcr/generated/node/error_node.rb +1 -1
- data/lib/packcr/generated/node/expand_node.rb +1 -1
- data/lib/packcr/generated/node/predicate_node.rb +9 -7
- data/lib/packcr/generated/node/quantity_node.rb +16 -16
- data/lib/packcr/generated/node/reference_node.rb +3 -8
- data/lib/packcr/generated/node/rule_node.rb +6 -6
- data/lib/packcr/generated/node/sequence_node.rb +1 -1
- data/lib/packcr/generated/node/string_node.rb +28 -4
- data/lib/packcr/generator.rb +4 -3
- data/lib/packcr/node/action_node.rb +2 -2
- data/lib/packcr/node/alternate_node.rb +2 -2
- data/lib/packcr/node/capture_node.rb +2 -2
- data/lib/packcr/node/charclass_node.rb +15 -15
- data/lib/packcr/node/eof_node.rb +2 -2
- data/lib/packcr/node/error_node.rb +2 -2
- data/lib/packcr/node/expand_node.rb +2 -2
- data/lib/packcr/node/predicate_node.rb +3 -3
- data/lib/packcr/node/quantity_node.rb +4 -4
- data/lib/packcr/node/reference_node.rb +4 -4
- data/lib/packcr/node/rule_node.rb +2 -2
- data/lib/packcr/node/sequence_node.rb +2 -2
- data/lib/packcr/node/string_node.rb +17 -3
- data/lib/packcr/parser.rb +1 -1
- data/lib/packcr/templates/context/source.rs.erb +93 -91
- data/lib/packcr/templates/node/action.rs.erb +5 -5
- data/lib/packcr/templates/node/alternate.rs.erb +28 -29
- data/lib/packcr/templates/node/charclass_utf8.rs.erb +3 -3
- data/lib/packcr/templates/node/predicate_neg.rs.erb +6 -6
- data/lib/packcr/templates/node/quantity_many.rs.erb +55 -28
- data/lib/packcr/templates/node/reference.rs.erb +2 -2
- data/lib/packcr/templates/node/rule.rs.erb +20 -11
- data/lib/packcr/templates/node/string_many.rs.erb +4 -4
- data/lib/packcr/templates/node/string_many_reverse.rs.erb +7 -0
- data/lib/packcr/templates/node/string_one.rs.erb +3 -3
- data/lib/packcr/templates/node/string_one_reverse.rs.erb +6 -0
- data/lib/packcr/version.rb +1 -1
- metadata +6 -4
@@ -33,8 +33,8 @@ class Packcr
|
|
33
33
|
end
|
34
34
|
end
|
35
35
|
|
36
|
-
def generate_code(gen, onfail, indent,
|
37
|
-
|
36
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
37
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
38
38
|
end
|
39
39
|
|
40
40
|
def reachability
|
@@ -27,8 +27,8 @@ class Packcr
|
|
27
27
|
m
|
28
28
|
end
|
29
29
|
|
30
|
-
def generate_code(gen, onfail, indent,
|
31
|
-
|
30
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
31
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
32
32
|
end
|
33
33
|
|
34
34
|
def reachability
|
@@ -15,8 +15,8 @@ class Packcr
|
|
15
15
|
$stdout.print "#{" " * indent}}\n"
|
16
16
|
end
|
17
17
|
|
18
|
-
def generate_code(gen, onfail, indent,
|
19
|
-
|
18
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
19
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
20
20
|
end
|
21
21
|
|
22
22
|
def reachability
|
@@ -17,16 +17,16 @@ class Packcr
|
|
17
17
|
gen.lang == :rb && !gen.ascii
|
18
18
|
end
|
19
19
|
|
20
|
-
def generate_code(gen, onfail, indent,
|
21
|
-
return generate_ascii_code(gen, onfail, indent,
|
20
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
21
|
+
return generate_ascii_code(gen, onfail, indent, unwrap) if gen.ascii
|
22
22
|
|
23
|
-
generate_utf8_charclass_code(gen, onfail, indent,
|
23
|
+
generate_utf8_charclass_code(gen, onfail, indent, unwrap)
|
24
24
|
end
|
25
25
|
|
26
|
-
def generate_reverse_code(gen, onsuccess, indent,
|
26
|
+
def generate_reverse_code(gen, onsuccess, indent, unwrap, oncut: nil)
|
27
27
|
raise "unexpected" if gen.ascii
|
28
28
|
|
29
|
-
generate_utf8_charclass_reverse_code(gen, onsuccess, indent,
|
29
|
+
generate_utf8_charclass_reverse_code(gen, onsuccess, indent, unwrap)
|
30
30
|
end
|
31
31
|
|
32
32
|
def reachability
|
@@ -39,20 +39,20 @@ class Packcr
|
|
39
39
|
|
40
40
|
private
|
41
41
|
|
42
|
-
def generate_utf8_charclass_code(gen, onfail, indent,
|
42
|
+
def generate_utf8_charclass_code(gen, onfail, indent, unwrap)
|
43
43
|
charclass = value
|
44
44
|
if charclass && charclass.encoding != Encoding::UTF_8
|
45
45
|
charclass = charclass.dup.force_encoding(Encoding::UTF_8)
|
46
46
|
end
|
47
47
|
n = charclass&.length || 0
|
48
48
|
if charclass.nil? || n > 0
|
49
|
-
|
49
|
+
get_utf8_code(gen, onfail, indent, unwrap, charclass, n)
|
50
50
|
else
|
51
|
-
|
51
|
+
get_fail_code(gen, onfail, indent, unwrap)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
55
|
-
def generate_utf8_charclass_reverse_code(gen, onsuccess, indent,
|
55
|
+
def generate_utf8_charclass_reverse_code(gen, onsuccess, indent, unwrap)
|
56
56
|
charclass = value
|
57
57
|
if charclass && charclass.encoding != Encoding::UTF_8
|
58
58
|
charclass = charclass.dup.force_encoding(Encoding::UTF_8)
|
@@ -60,10 +60,10 @@ class Packcr
|
|
60
60
|
n = charclass&.length || 0
|
61
61
|
return unless charclass.nil? || n > 0
|
62
62
|
|
63
|
-
|
63
|
+
get_utf8_reverse_code(gen, onsuccess, indent, unwrap, charclass, n)
|
64
64
|
end
|
65
65
|
|
66
|
-
def generate_ascii_code(gen, onfail, indent,
|
66
|
+
def generate_ascii_code(gen, onfail, indent, unwrap)
|
67
67
|
charclass = value
|
68
68
|
if charclass
|
69
69
|
n = charclass.length
|
@@ -74,15 +74,15 @@ class Packcr
|
|
74
74
|
end
|
75
75
|
if n > 0
|
76
76
|
if n > 1
|
77
|
-
|
77
|
+
get_code(gen, onfail, indent, unwrap, charclass, n, a)
|
78
78
|
else
|
79
|
-
|
79
|
+
get_one_code(gen, onfail, indent, unwrap, charclass, n, a)
|
80
80
|
end
|
81
81
|
else
|
82
|
-
|
82
|
+
get_fail_code(gen, onfail, indent, unwrap)
|
83
83
|
end
|
84
84
|
else
|
85
|
-
|
85
|
+
get_any_code(gen, onfail, indent, unwrap, charclass)
|
86
86
|
end
|
87
87
|
end
|
88
88
|
|
data/lib/packcr/node/eof_node.rb
CHANGED
@@ -5,8 +5,8 @@ class Packcr
|
|
5
5
|
$stdout.print "#{" " * indent}Eof()\n"
|
6
6
|
end
|
7
7
|
|
8
|
-
def generate_code(gen, onfail, indent,
|
9
|
-
|
8
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
9
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
10
10
|
end
|
11
11
|
|
12
12
|
def reachability
|
@@ -29,8 +29,8 @@ class Packcr
|
|
29
29
|
$stdout.print "#{" " * indent}}\n"
|
30
30
|
end
|
31
31
|
|
32
|
-
def generate_code(gen, onfail, indent,
|
33
|
-
|
32
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
33
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
34
34
|
end
|
35
35
|
|
36
36
|
def reachability
|
@@ -15,8 +15,8 @@ class Packcr
|
|
15
15
|
$stdout.print ")\n"
|
16
16
|
end
|
17
17
|
|
18
|
-
def generate_code(gen, onfail, indent,
|
19
|
-
|
18
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
19
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
20
20
|
end
|
21
21
|
|
22
22
|
def reachability
|
@@ -15,11 +15,11 @@ class Packcr
|
|
15
15
|
$stdout.print "#{" " * indent}}\n"
|
16
16
|
end
|
17
17
|
|
18
|
-
def generate_code(gen, onfail, indent,
|
18
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
19
19
|
if neg
|
20
|
-
|
20
|
+
get_neg_code(gen, onfail, indent, unwrap, oncut)
|
21
21
|
else
|
22
|
-
|
22
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -16,14 +16,14 @@ class Packcr
|
|
16
16
|
$stdout.print "#{" " * indent}}\n"
|
17
17
|
end
|
18
18
|
|
19
|
-
def generate_code(gen, onfail, indent,
|
19
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
20
20
|
if max > 1 || max < 0
|
21
|
-
|
21
|
+
get_many_code(gen, onfail, indent, unwrap, oncut)
|
22
22
|
elsif max == 1
|
23
23
|
if min > 0
|
24
|
-
gen.
|
24
|
+
gen.generate_code(expr, onfail, indent, unwrap, oncut: oncut)
|
25
25
|
else
|
26
|
-
|
26
|
+
get_one_code(gen, onfail, indent, unwrap, oncut)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -20,12 +20,12 @@ class Packcr
|
|
20
20
|
gen.lang == :rb
|
21
21
|
end
|
22
22
|
|
23
|
-
def generate_code(gen, onfail, indent,
|
24
|
-
|
23
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
24
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
25
25
|
end
|
26
26
|
|
27
|
-
def generate_reverse_code(gen, onsuccess, indent,
|
28
|
-
|
27
|
+
def generate_reverse_code(gen, onsuccess, indent, unwrap, oncut: nil)
|
28
|
+
get_reverse_code(gen, onsuccess, indent, unwrap, oncut)
|
29
29
|
end
|
30
30
|
|
31
31
|
def reachability
|
@@ -22,8 +22,8 @@ class Packcr
|
|
22
22
|
$stdout.print "#{" " * indent}}\n"
|
23
23
|
end
|
24
24
|
|
25
|
-
def generate_code(gen, onfail, indent,
|
26
|
-
|
25
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
26
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
27
27
|
end
|
28
28
|
|
29
29
|
def reachability
|
@@ -53,8 +53,8 @@ class Packcr
|
|
53
53
|
m
|
54
54
|
end
|
55
55
|
|
56
|
-
def generate_code(gen, onfail, indent,
|
57
|
-
|
56
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
57
|
+
get_code(gen, onfail, indent, unwrap, oncut)
|
58
58
|
end
|
59
59
|
|
60
60
|
def reachability
|
@@ -17,14 +17,28 @@ class Packcr
|
|
17
17
|
$stdout.print "')\n"
|
18
18
|
end
|
19
19
|
|
20
|
-
def
|
20
|
+
def reversible?(gen)
|
21
|
+
gen.lang == :rs
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate_code(gen, onfail, indent, unwrap, oncut: nil)
|
21
25
|
n = value&.length || 0
|
22
26
|
return unless n > 0
|
23
27
|
|
24
28
|
if n > 1
|
25
|
-
|
29
|
+
get_many_code(gen, onfail, indent, unwrap, oncut, n)
|
30
|
+
else
|
31
|
+
get_one_code(gen, onfail, indent, unwrap, oncut, n)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def generate_reverse_code(gen, onsuccess, indent, unwrap, oncut: nil)
|
36
|
+
n = value&.length || 0
|
37
|
+
|
38
|
+
if n > 1
|
39
|
+
get_many_reverse_code(gen, onsuccess, indent, unwrap, oncut, n)
|
26
40
|
else
|
27
|
-
|
41
|
+
get_one_reverse_code(gen, onsuccess, indent, unwrap, oncut, n)
|
28
42
|
end
|
29
43
|
end
|
30
44
|
|
data/lib/packcr/parser.rb
CHANGED
@@ -4,7 +4,6 @@ use std::cell::RefCell;
|
|
4
4
|
use std::collections::{HashMap, HashSet};
|
5
5
|
use std::io::Read;
|
6
6
|
use std::rc::Rc;
|
7
|
-
|
8
7
|
<%- if !code(:esource).empty? -%>
|
9
8
|
|
10
9
|
<%- code(:esource).each do |code| -%>
|
@@ -35,12 +34,10 @@ impl LrMemoTable {
|
|
35
34
|
fn get(&mut self, index: usize, rule: Rule) -> &mut LrMemo {
|
36
35
|
self.memos.get_mut(&index).unwrap().get_mut(&rule).unwrap()
|
37
36
|
}
|
38
|
-
fn has(&
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
}
|
43
|
-
memo_opt.unwrap().contains_key(&rule)
|
37
|
+
fn has(&self, index: usize, rule: Rule) -> bool {
|
38
|
+
self.memos
|
39
|
+
.get(&index)
|
40
|
+
.is_some_and(|memo_map| memo_map.contains_key(&rule))
|
44
41
|
}
|
45
42
|
}
|
46
43
|
|
@@ -60,21 +57,20 @@ impl LrMemo {
|
|
60
57
|
}
|
61
58
|
|
62
59
|
fn start_grow(&mut self) -> bool {
|
63
|
-
if self.grow
|
64
|
-
|
60
|
+
if !self.grow && self.answer.is_none() {
|
61
|
+
self.grow = true;
|
62
|
+
true
|
63
|
+
} else {
|
64
|
+
false
|
65
65
|
}
|
66
|
-
self.answer = None;
|
67
|
-
self.grow = true;
|
68
|
-
true
|
69
66
|
}
|
70
67
|
|
71
|
-
fn
|
68
|
+
fn update(&mut self, answer: Option<ThunkChunk>, offset: usize) {
|
72
69
|
self.answer = answer.map(|c| Rc::new(RefCell::new(c)));
|
73
70
|
self.offset = offset;
|
74
71
|
}
|
75
72
|
|
76
|
-
fn
|
77
|
-
self.answer.as_ref()?;
|
73
|
+
fn clone_answer(&mut self) -> Option<Rc<RefCell<ThunkChunk>>> {
|
78
74
|
self.answer.as_ref().map(Rc::clone)
|
79
75
|
}
|
80
76
|
}
|
@@ -128,7 +124,7 @@ enum Thunk {
|
|
128
124
|
Node(ThunkNode),
|
129
125
|
}
|
130
126
|
impl Thunk {
|
131
|
-
fn do_action(&self, processor: &ThunkProcessor, value: ValueRef) {
|
127
|
+
fn do_action(&self, processor: &ThunkProcessor, value: ValueRef) -> Value {
|
132
128
|
match self {
|
133
129
|
Thunk::Leaf(leaf) => leaf.do_action(processor, value),
|
134
130
|
Thunk::Node(node) => node.do_action(processor),
|
@@ -159,10 +155,11 @@ impl ThunkLeaf {
|
|
159
155
|
}
|
160
156
|
}
|
161
157
|
|
162
|
-
fn do_action(&self, processor: &ThunkProcessor, mut value: ValueRef) {
|
158
|
+
fn do_action(&self, processor: &ThunkProcessor, mut value: ValueRef) -> Value {
|
163
159
|
value.with_mut(|v| {
|
164
160
|
processor.call_action(self.action, self, v);
|
165
161
|
});
|
162
|
+
value.get()
|
166
163
|
}
|
167
164
|
<%- if use_value -%>
|
168
165
|
|
@@ -177,10 +174,12 @@ struct ThunkNode {
|
|
177
174
|
value: ValueRef,
|
178
175
|
}
|
179
176
|
impl ThunkNode {
|
180
|
-
fn do_action(&self, processor: &ThunkProcessor) {
|
181
|
-
|
182
|
-
|
177
|
+
fn do_action(&self, processor: &ThunkProcessor) -> Value {
|
178
|
+
let mut v = 0;
|
179
|
+
for thunk in self.thunks.borrow_mut().iter_mut() {
|
180
|
+
v = thunk.do_action(processor, self.value.clone());
|
183
181
|
}
|
182
|
+
v
|
184
183
|
}
|
185
184
|
}
|
186
185
|
|
@@ -241,11 +240,9 @@ impl ValueRef {
|
|
241
240
|
self.values.with_mut(self.index, f);
|
242
241
|
}
|
243
242
|
|
244
|
-
<%- if use_value -%>
|
245
243
|
fn get(&self) -> i32 {
|
246
244
|
*self.values.table.borrow().get(&self.index).unwrap_or(&0)
|
247
245
|
}
|
248
|
-
<%- end -%>
|
249
246
|
}
|
250
247
|
impl Clone for ValueRef {
|
251
248
|
fn clone(&self) -> Self {
|
@@ -262,6 +259,7 @@ struct CaptureTable {
|
|
262
259
|
}
|
263
260
|
|
264
261
|
type RuleSet = HashSet<Rule>;
|
262
|
+
type RuleLimit = Option<RuleSet>;
|
265
263
|
|
266
264
|
type LrMemoMap = HashMap<Rule, LrMemo>;
|
267
265
|
|
@@ -308,6 +306,7 @@ struct Input {
|
|
308
306
|
start_position: usize,
|
309
307
|
position_offset: usize,
|
310
308
|
buffer: String,
|
309
|
+
closed: bool,
|
311
310
|
}
|
312
311
|
|
313
312
|
impl Input {
|
@@ -317,6 +316,7 @@ impl Input {
|
|
317
316
|
start_position: 0,
|
318
317
|
position_offset: 0,
|
319
318
|
buffer: String::new(),
|
319
|
+
closed: false,
|
320
320
|
}
|
321
321
|
}
|
322
322
|
|
@@ -378,7 +378,20 @@ impl Input {
|
|
378
378
|
|
379
379
|
fn back_to(&mut self, memo: &mut LrMemo) -> Option<Rc<RefCell<ThunkChunk>>> {
|
380
380
|
self.position_offset = memo.offset;
|
381
|
-
memo.
|
381
|
+
memo.clone_answer()
|
382
|
+
}
|
383
|
+
}
|
384
|
+
|
385
|
+
const NOP: Result<usize, usize> = Ok(0);
|
386
|
+
const fn throw(label: usize) -> Result<usize, usize> {
|
387
|
+
Err(label)
|
388
|
+
}
|
389
|
+
|
390
|
+
fn catch(label: usize, f: impl FnOnce() -> Result<usize, usize>) -> Result<usize, usize> {
|
391
|
+
match f() {
|
392
|
+
Ok(_) => NOP,
|
393
|
+
Err(e) if e == label => NOP,
|
394
|
+
Err(e) => throw(e),
|
382
395
|
}
|
383
396
|
}
|
384
397
|
|
@@ -397,49 +410,32 @@ impl <%= class_name %> {
|
|
397
410
|
}
|
398
411
|
}
|
399
412
|
|
400
|
-
fn
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
fn refill_buffer(&mut self, num: usize) -> usize {
|
406
|
-
self.input.refill_buffer(num)
|
407
|
-
}
|
408
|
-
|
409
|
-
fn commit_buffer(&mut self) {
|
410
|
-
self.input.commit_buffer();
|
411
|
-
self.memos.clear();
|
412
|
-
}
|
413
|
+
fn parse(&mut self) -> Option<Value> {
|
414
|
+
if self.input.closed {
|
415
|
+
return None;
|
416
|
+
}
|
413
417
|
|
414
|
-
fn parse(&mut self) -> bool {
|
415
418
|
let mut answer = ThunkChunk::new(0);
|
416
419
|
let pos = self.input.start_position;
|
417
|
-
|
418
420
|
<%- if !@root.rules.empty? -%>
|
419
|
-
let apply_result = self.apply_rule(
|
420
|
-
Rule::<%= Packcr.camelize(@root.rules[0].name) %>,
|
421
|
-
&mut answer,
|
422
|
-
0,
|
423
|
-
self.input.position_offset,
|
424
|
-
None,
|
425
|
-
);
|
426
|
-
|
427
|
-
if apply_result {
|
428
|
-
if let Thunk::Node(node) = answer.thunks.borrow_mut().last().unwrap() {
|
429
|
-
node.do_action(&ThunkProcessor::new(&self.input.buffer));
|
430
|
-
}
|
431
|
-
} else {
|
432
|
-
self.error();
|
433
|
-
}
|
434
421
|
|
422
|
+
let value = {
|
423
|
+
let node = self.rule_thunk_node(
|
424
|
+
Rule::<%= Packcr.camelize(@root.rules[0].name) %>,
|
425
|
+
&mut answer,
|
426
|
+
0,
|
427
|
+
self.input.position_offset,
|
428
|
+
&None,
|
429
|
+
);
|
430
|
+
self.memos.clear();
|
431
|
+
node.map(|node| node.do_action(&ThunkProcessor::new(&self.input.buffer)))
|
432
|
+
};
|
433
|
+
self.input.commit_buffer();
|
434
|
+
if pos == self.input.start_position || self.input.refill_buffer(1) < 1 {
|
435
|
+
self.input.closed = true;
|
436
|
+
}
|
437
|
+
value
|
435
438
|
<%- end -%>
|
436
|
-
self.commit_buffer();
|
437
|
-
pos != self.input.start_position && self.refill_buffer(1) >= 1
|
438
|
-
}
|
439
|
-
|
440
|
-
#[allow(dead_code)]
|
441
|
-
fn get_char_as_utf32(&mut self) -> (i32, usize) {
|
442
|
-
self.input.get_char_as_utf32()
|
443
439
|
}
|
444
440
|
|
445
441
|
fn grow_lr(&mut self, rule: Rule, offset: usize) {
|
@@ -448,16 +444,19 @@ impl <%= class_name %> {
|
|
448
444
|
self.input.position_offset = offset;
|
449
445
|
|
450
446
|
let answer = self.call_rule(rule, offset, Some(RuleSet::new()));
|
451
|
-
|
452
|
-
|
447
|
+
match answer {
|
448
|
+
Some(answer) if self.input.position_offset > old_offset => {
|
449
|
+
let memo = self.memos.get(offset, rule);
|
450
|
+
memo.update(Some(answer), self.input.position_offset);
|
451
|
+
}
|
452
|
+
_ => {
|
453
|
+
return;
|
454
|
+
}
|
453
455
|
}
|
454
|
-
|
455
|
-
let memo = self.memos.get(offset, rule);
|
456
|
-
memo.start_match(answer, self.input.position_offset);
|
457
456
|
}
|
458
457
|
}
|
459
458
|
|
460
|
-
fn
|
459
|
+
fn rule_answer_without_limits(&mut self, rule: Rule) -> Option<Rc<RefCell<ThunkChunk>>> {
|
461
460
|
let offset = self.input.position_offset;
|
462
461
|
if !self.memos.has(offset, rule) {
|
463
462
|
let memo = LrMemo::new(offset);
|
@@ -465,7 +464,7 @@ impl <%= class_name %> {
|
|
465
464
|
let answer = self.call_rule(rule, offset, None);
|
466
465
|
|
467
466
|
let memo = self.memos.get(offset, rule);
|
468
|
-
memo.
|
467
|
+
memo.update(answer, self.input.position_offset);
|
469
468
|
if !memo.grow {
|
470
469
|
return self.input.back_to(memo);
|
471
470
|
}
|
@@ -491,16 +490,13 @@ impl <%= class_name %> {
|
|
491
490
|
let offset = self.input.position_offset;
|
492
491
|
let answer = self.call_rule(rule, offset, Some(limits));
|
493
492
|
if !self.memos.has(offset, rule) {
|
494
|
-
answer.
|
495
|
-
return Some(Rc::new(RefCell::new(answer.unwrap())));
|
493
|
+
return answer.map(|answer| Rc::new(RefCell::new(answer)));
|
496
494
|
}
|
497
|
-
let memo = self.memos.get(offset, rule);
|
498
495
|
|
496
|
+
let memo = self.memos.get(offset, rule);
|
499
497
|
if self.input.position_offset > memo.offset {
|
500
|
-
memo.
|
501
|
-
return memo.answer_as_deref_mut();
|
498
|
+
memo.update(answer, self.input.position_offset);
|
502
499
|
}
|
503
|
-
|
504
500
|
self.input.back_to(memo)
|
505
501
|
}
|
506
502
|
|
@@ -510,35 +506,42 @@ impl <%= class_name %> {
|
|
510
506
|
parent: &mut ThunkChunk,
|
511
507
|
value_index: usize,
|
512
508
|
offset: usize,
|
513
|
-
limits:
|
509
|
+
limits: &RuleLimit,
|
514
510
|
) -> bool {
|
515
|
-
let
|
511
|
+
let node = self.rule_thunk_node(rule, parent, value_index, offset, limits);
|
512
|
+
node.is_some_and(|node| {
|
513
|
+
parent.thunks.borrow_mut().push(Thunk::Node(node));
|
514
|
+
true
|
515
|
+
})
|
516
|
+
}
|
517
|
+
|
518
|
+
fn rule_thunk_node(
|
519
|
+
&mut self,
|
520
|
+
rule: Rule,
|
521
|
+
parent: &ThunkChunk,
|
522
|
+
value_index: usize,
|
523
|
+
offset: usize,
|
524
|
+
limits: &RuleLimit,
|
525
|
+
) -> Option<ThunkNode> {
|
526
|
+
match limits {
|
516
527
|
Some(limit_set)
|
517
528
|
if self.input.position_offset == offset && !limit_set.contains(&rule) =>
|
518
529
|
{
|
519
|
-
self.rule_answer_with_limits(rule, limits.unwrap())
|
530
|
+
self.rule_answer_with_limits(rule, limits.clone().unwrap())
|
520
531
|
}
|
521
|
-
_ => self.
|
522
|
-
}
|
523
|
-
|
524
|
-
let Some(answer) = answer else {
|
525
|
-
return false;
|
526
|
-
};
|
527
|
-
|
528
|
-
let new_node = Thunk::Node(ThunkNode {
|
532
|
+
_ => self.rule_answer_without_limits(rule),
|
533
|
+
}
|
534
|
+
.map(|answer| ThunkNode {
|
529
535
|
thunks: answer.borrow().thunks.clone(),
|
530
536
|
value: parent.value_ref(value_index),
|
531
|
-
})
|
532
|
-
parent.thunks.borrow_mut().push(new_node);
|
533
|
-
|
534
|
-
true
|
537
|
+
})
|
535
538
|
}
|
536
539
|
|
537
540
|
fn call_rule(
|
538
541
|
&mut self,
|
539
542
|
rule: Rule,
|
540
543
|
offset: usize,
|
541
|
-
mut limits:
|
544
|
+
mut limits: RuleLimit,
|
542
545
|
) -> Option<ThunkChunk> {
|
543
546
|
if let Some(ref mut limits) = limits {
|
544
547
|
limits.insert(rule);
|
@@ -549,7 +552,6 @@ impl <%= class_name %> {
|
|
549
552
|
<%- end -%>
|
550
553
|
}
|
551
554
|
}
|
552
|
-
|
553
555
|
<%- @root.rules.each do |rule| -%>
|
554
556
|
|
555
557
|
<%- gen = ::Packcr::Generator.new(rule, @ascii, @location, :rs) -%>
|
@@ -578,7 +580,7 @@ impl<'a> ThunkProcessor<'a> {
|
|
578
580
|
<%- @root.rules.each do |rule| -%>
|
579
581
|
<%- rule.codes.each do |code| -%>
|
580
582
|
|
581
|
-
#[allow(unused_variables,non_snake_case)]
|
583
|
+
#[allow(unused_variables, non_snake_case)]
|
582
584
|
fn action_<%= rule.name %>_<%= code.index %>(&self, leaf: &ThunkLeaf, out: &mut i32) {
|
583
585
|
<%- code.vars.each_with_index do |ref, i| -%>
|
584
586
|
<%- if i == 0 -%>
|
@@ -1,6 +1,6 @@
|
|
1
|
-
answer.push_leaf(
|
2
|
-
Action::<%= Packcr.camelize(gen.rule.name) %><%= index %>,
|
3
|
-
self.input.position_offset,
|
4
|
-
|
5
|
-
|
1
|
+
answer.push_leaf(<% -%>
|
2
|
+
<%- %>Action::<%= Packcr.camelize(gen.rule.name) %><%= index %>, <% -%>
|
3
|
+
<%- %>self.input.position_offset, <% -%>
|
4
|
+
<%- %>&[<% vars.each_with_index do |var, i| %><%= ", " if i > 0 %><%= var.index %><% end %>], <% -%>
|
5
|
+
<%- %>&[<% capts.each_with_index do |capt, i| %><%= ", " if i > 0 %><%= capt.index %><% end %>]<% -%>
|
6
6
|
);
|