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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c7f6f8510a8922ec8a3f379de4470af6889a01a0f98aebf46b69f16e2c398c64
|
4
|
+
data.tar.gz: aa728bb984a9a343c71099fe6652b7a37c5a3a20b535ad6d5cbc29feaaa776d0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ceee0d72c7fa96a8a71fd76d8015591f70c4ba321242966ed295522d55e37e2ce71cf8ab51bda644971f5b0ad675c4c0dbdd225e8f2eded2d5eb8f5a3957922f
|
7
|
+
data.tar.gz: fd819a73b1b16827316ddef020068383952cf6d188ac728f5d06157330b49b0010561552676fce3652cc90b0f838f7750242622b83d0677335e6bc6235199d4f
|
data/lib/packcr/cli.rb
CHANGED
@@ -1,25 +1,27 @@
|
|
1
1
|
require "packcr"
|
2
2
|
require "optparse"
|
3
3
|
|
4
|
-
class Packcr
|
5
|
-
class
|
6
|
-
|
7
|
-
|
4
|
+
class Packcr
|
5
|
+
class Cli
|
6
|
+
class << self
|
7
|
+
def run(argv)
|
8
|
+
new.run(argv)
|
9
|
+
end
|
8
10
|
end
|
9
|
-
end
|
10
11
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
def run(argv)
|
13
|
+
lang = nil
|
14
|
+
debug = false
|
15
|
+
ascii = false
|
16
|
+
opt = OptionParser.new
|
17
|
+
opt.on("-l", "--lang=VAL") { |v| lang = v.to_sym }
|
18
|
+
opt.on("-d", "--debug") { |_v| debug = true }
|
19
|
+
opt.on("-a", "--ascii") { |_v| ascii = true }
|
19
20
|
|
20
|
-
|
21
|
-
|
22
|
-
|
21
|
+
opt.parse!(argv)
|
22
|
+
argv.each do |ifile|
|
23
|
+
::Packcr.new(ifile, lang: lang, debug: debug, ascii: ascii).run
|
24
|
+
end
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
data/lib/packcr/code_block.rb
CHANGED
data/lib/packcr/context.rb
CHANGED
@@ -34,15 +34,15 @@ class Packcr
|
|
34
34
|
@lang = lang.to_sym
|
35
35
|
case @lang
|
36
36
|
when :c
|
37
|
-
@hname = path
|
37
|
+
@hname = "#{path}.h"
|
38
38
|
@patterns = {
|
39
|
-
|
40
|
-
|
39
|
+
get_source_code: "#{path}.c",
|
40
|
+
get_header_code: @hname,
|
41
41
|
}
|
42
42
|
@hid = File.basename(@hname).upcase.gsub(/[^A-Z0-9]/, "_")
|
43
43
|
when :rb
|
44
44
|
@patterns = {
|
45
|
-
|
45
|
+
get_source_code: "#{path}.rb",
|
46
46
|
}
|
47
47
|
else
|
48
48
|
raise "unexpected lang: #{@lang}"
|
@@ -57,9 +57,9 @@ class Packcr
|
|
57
57
|
@codes = {}
|
58
58
|
@root = Node::RootNode.new
|
59
59
|
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
return unless block_given?
|
61
|
+
|
62
|
+
yield(self)
|
63
63
|
end
|
64
64
|
|
65
65
|
def code(name)
|
@@ -67,7 +67,7 @@ class Packcr
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def inspect
|
70
|
-
"
|
70
|
+
format("#<%s:0x%016x>", self.class, object_id)
|
71
71
|
end
|
72
72
|
|
73
73
|
def error(line, col, message)
|
@@ -97,7 +97,7 @@ class Packcr
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def class_name
|
100
|
-
prefix.gsub(/(?:_|^|(\W))([a-z])/) { "#{
|
100
|
+
prefix.gsub(/(?:_|^|(\W))([a-z])/) { "#{::Regexp.last_match(1)}#{::Regexp.last_match(2)}".upcase }
|
101
101
|
end
|
102
102
|
|
103
103
|
def auxil_def
|
@@ -141,24 +141,24 @@ class Packcr
|
|
141
141
|
def generate
|
142
142
|
results = []
|
143
143
|
|
144
|
-
@patterns.each do |
|
144
|
+
@patterns.each do |meth, ofile|
|
145
145
|
result = Tempfile.new
|
146
146
|
result.unlink
|
147
147
|
results << [ofile, result]
|
148
148
|
stream = Packcr::Stream.new(result, ofile, @lines ? 0 : nil)
|
149
|
-
stream.write Packcr.
|
149
|
+
stream.write Packcr.format_code(public_send(meth, @lang, stream)), rewrite_line_directive: true
|
150
150
|
|
151
|
-
if
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
return false
|
151
|
+
next if @errnum.zero?
|
152
|
+
|
153
|
+
results.each do |_, r|
|
154
|
+
r.close
|
156
155
|
end
|
156
|
+
return false
|
157
157
|
end
|
158
158
|
|
159
159
|
results.each do |(name, result)|
|
160
160
|
result.rewind
|
161
|
-
open(name, "wt") do |f|
|
161
|
+
File.open(name, "wt") do |f|
|
162
162
|
IO.copy_stream(result, f)
|
163
163
|
end
|
164
164
|
end
|
@@ -166,3 +166,5 @@ class Packcr
|
|
166
166
|
end
|
167
167
|
end
|
168
168
|
end
|
169
|
+
|
170
|
+
require "packcr/generated/context"
|
@@ -0,0 +1,440 @@
|
|
1
|
+
class Packcr
|
2
|
+
class Context
|
3
|
+
def get_header_code(lang, stream)
|
4
|
+
case lang
|
5
|
+
when :c
|
6
|
+
erbout = +""
|
7
|
+
erbout << "/* A packrat parser generated by PackCR #{Packcr::VERSION} */\n\n".freeze
|
8
|
+
|
9
|
+
code(:eheader).each do |code|
|
10
|
+
erbout << "#{stream.get_code_block(code, 0, @iname)}".freeze
|
11
|
+
end
|
12
|
+
if !code(:eheader).empty?
|
13
|
+
erbout << "\n".freeze
|
14
|
+
end
|
15
|
+
erbout << "#ifndef PCC_INCLUDED_#{@hid}\n#define PCC_INCLUDED_#{@hid}\n\n".freeze
|
16
|
+
|
17
|
+
code(:header).each do |code|
|
18
|
+
erbout << "#{stream.get_code_block(code, 0, @iname)}".freeze
|
19
|
+
end
|
20
|
+
erbout << "#ifdef __cplusplus\nextern \"C\" {\n#endif\n\ntypedef struct #{prefix}_context_tag #{prefix}_context_t;\n\n#{prefix}_context_t *#{prefix}_create(#{auxil_def}auxil);\nint #{prefix}_parse(#{prefix}_context_t *ctx, #{value_def}*ret);\nvoid #{prefix}_destroy(#{prefix}_context_t *ctx);\n\n#ifdef __cplusplus\n}\n#endif\n\n#endif /* !PCC_INCLUDED_#{@hid} */\n".freeze
|
21
|
+
|
22
|
+
erbout
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def get_source_code(lang, stream)
|
27
|
+
case lang
|
28
|
+
when :c
|
29
|
+
erbout = +""
|
30
|
+
erbout << "/* A packrat parser generated by PackCR #{Packcr::VERSION} */\n\n".freeze
|
31
|
+
|
32
|
+
code(:esource).each do |code|
|
33
|
+
erbout << "#{stream.get_code_block(code, 0, @iname)}".freeze
|
34
|
+
end
|
35
|
+
if !code(:esource).empty?
|
36
|
+
erbout << "\n".freeze
|
37
|
+
end
|
38
|
+
erbout << "#ifdef _MSC_VER\n#undef _CRT_SECURE_NO_WARNINGS\n#define _CRT_SECURE_NO_WARNINGS\n#endif /* _MSC_VER */\n#include <stdio.h>\n#include <stdlib.h>\n#include <string.h>\n\n#ifndef _MSC_VER\n#if defined __GNUC__ && defined _WIN32 /* MinGW */\n#ifndef PCC_USE_SYSTEM_STRNLEN\n#define strnlen(str, maxlen) pcc_strnlen(str, maxlen)\nstatic size_t pcc_strnlen(const char *str, size_t maxlen) {\n size_t i;\n for (i = 0; i < maxlen && str[i]; i++);\n return i;\n}\n#endif /* !PCC_USE_SYSTEM_STRNLEN */\n#endif /* defined __GNUC__ && defined _WIN32 */\n#endif /* !_MSC_VER */\n\n#include \"#{@hname}\"\n".freeze
|
39
|
+
|
40
|
+
if !code(:location).empty?
|
41
|
+
erbout << "\n".freeze
|
42
|
+
|
43
|
+
code(:location).each do |code|
|
44
|
+
erbout << "#{stream.get_code_block(code, 4, @iname)}".freeze
|
45
|
+
end
|
46
|
+
end
|
47
|
+
erbout << "\n".freeze
|
48
|
+
|
49
|
+
code(:source).each do |code|
|
50
|
+
erbout << "#{stream.get_code_block(code, 0, @iname)}".freeze
|
51
|
+
end
|
52
|
+
erbout << "#if !defined __has_attribute || defined _MSC_VER\n#define __attribute__(x)\n#endif\n\n#ifdef _MSC_VER\n#define MARK_FUNC_AS_USED __pragma(warning(suppress:4505))\n#else\n#define MARK_FUNC_AS_USED __attribute__((__unused__))\n#endif\n\n#ifndef PCC_BUFFER_MIN_SIZE\n#define PCC_BUFFER_MIN_SIZE 256\n#endif /* !PCC_BUFFER_MIN_SIZE */\n\n#ifndef PCC_ARRAY_MIN_SIZE\n#define PCC_ARRAY_MIN_SIZE 2\n#endif /* !PCC_ARRAY_MIN_SIZE */\n\n#ifndef PCC_POOL_MIN_SIZE\n#define PCC_POOL_MIN_SIZE 65536\n#endif /* !PCC_POOL_MIN_SIZE */\n\n#define PCC_DBG_EVALUATE 0\n#define PCC_DBG_MATCH 1\n#define PCC_DBG_NOMATCH 2\n\n#define PCC_VOID_VALUE (~(size_t)0)\n\ntypedef enum pcc_bool_tag {\n PCC_FALSE = 0,\n PCC_TRUE\n} pcc_bool_t;\n\ntypedef struct pcc_char_array_tag {\n char *buf;\n size_t max;\n size_t len;\n} pcc_char_array_t;\n\ntypedef struct pcc_range_tag {\n size_t start;\n size_t end;\n".freeze
|
53
|
+
|
54
|
+
if @location
|
55
|
+
erbout << " pcc_location_t start_loc;\n pcc_location_t end_loc;\n".freeze
|
56
|
+
end
|
57
|
+
erbout << "} pcc_range_t;\n\ntypedef #{value_def}pcc_value_t;\n\ntypedef #{auxil_def}pcc_auxil_t;\n\n".freeze
|
58
|
+
|
59
|
+
if prefix != "pcc"
|
60
|
+
erbout << "typedef #{prefix}_context_t pcc_context_t;\n\n".freeze
|
61
|
+
end
|
62
|
+
erbout << "typedef struct pcc_value_table_tag {\n pcc_value_t *buf;\n size_t max;\n size_t len;\n} pcc_value_table_t;\n\ntypedef struct pcc_value_refer_table_tag {\n pcc_value_t **buf;\n size_t max;\n size_t len;\n} pcc_value_refer_table_t;\n\ntypedef struct pcc_capture_tag {\n pcc_range_t range;\n char *string; /* mutable */\n} pcc_capture_t;\n\ntypedef struct pcc_capture_table_tag {\n pcc_capture_t *buf;\n size_t max;\n size_t len;\n} pcc_capture_table_t;\n\ntypedef struct pcc_capture_const_table_tag {\n const pcc_capture_t **buf;\n size_t max;\n size_t len;\n} pcc_capture_const_table_t;\n\ntypedef struct pcc_thunk_tag pcc_thunk_t;\ntypedef struct pcc_thunk_array_tag pcc_thunk_array_t;\n\ntypedef void (*pcc_action_t)(pcc_context_t *, pcc_thunk_t *, pcc_value_t *);\n\ntypedef enum pcc_thunk_type_tag {\n PCC_THUNK_LEAF,\n PCC_THUNK_NODE\n} pcc_thunk_type_t;\n\ntypedef struct pcc_thunk_leaf_tag {\n pcc_value_refer_table_t values;\n pcc_capture_const_table_t capts;\n pcc_capture_t capt0;\n pcc_action_t action;\n} pcc_thunk_leaf_t;\n\ntypedef struct pcc_thunk_node_tag {\n const pcc_thunk_array_t *thunks; /* just a reference */\n pcc_value_t *value; /* just a reference */\n} pcc_thunk_node_t;\n\ntypedef union pcc_thunk_data_tag {\n pcc_thunk_leaf_t leaf;\n pcc_thunk_node_t node;\n} pcc_thunk_data_t;\n\nstruct pcc_thunk_tag {\n pcc_thunk_type_t type;\n pcc_thunk_data_t data;\n};\n\nstruct pcc_thunk_array_tag {\n pcc_thunk_t **buf;\n size_t max;\n size_t len;\n};\n\ntypedef struct pcc_thunk_chunk_tag {\n pcc_value_table_t values;\n pcc_capture_table_t capts;\n pcc_thunk_array_t thunks;\n size_t pos; /* the starting position in the character buffer */\n".freeze
|
63
|
+
|
64
|
+
if @location
|
65
|
+
erbout << " pcc_location_t pos_loc;\n".freeze
|
66
|
+
end
|
67
|
+
erbout << "} pcc_thunk_chunk_t;\n\ntypedef struct pcc_lr_memo_tag pcc_lr_memo_t;\n\nstruct pcc_lr_memo_tag {\n size_t offset;\n".freeze
|
68
|
+
|
69
|
+
if @location
|
70
|
+
erbout << " pcc_location_t offset_loc;\n".freeze
|
71
|
+
end
|
72
|
+
erbout << " pcc_lr_memo_t *hold;\n pcc_thunk_chunk_t *chunk;\n pcc_bool_t fail;\n pcc_bool_t grow;\n};\n\ntypedef struct pcc_rule_set_tag pcc_rule_set_t;\n\ntypedef pcc_thunk_chunk_t *(*pcc_rule_t)(pcc_context_t *, size_t".freeze
|
73
|
+
if @location
|
74
|
+
erbout << ", pcc_location_t".freeze
|
75
|
+
end
|
76
|
+
erbout << ", pcc_rule_set_t*);\n\ntypedef struct pcc_rule_set_tag {\n pcc_rule_t *buf;\n size_t max;\n size_t len;\n} pcc_rule_set_t;\n\ntypedef struct pcc_lr_memo_map_entry_tag {\n pcc_rule_t rule;\n pcc_lr_memo_t *memo;\n} pcc_lr_memo_map_entry_t;\n\ntypedef struct pcc_lr_memo_map_tag {\n pcc_lr_memo_map_entry_t *buf;\n size_t max;\n size_t len;\n} pcc_lr_memo_map_t;\n\ntypedef struct pcc_lr_table_tag {\n pcc_lr_memo_map_t **buf;\n size_t max;\n size_t len;\n size_t ofs;\n} pcc_lr_table_t;\n\ntypedef struct pcc_memory_entry_tag pcc_memory_entry_t;\ntypedef struct pcc_memory_pool_tag pcc_memory_pool_t;\n\nstruct pcc_memory_entry_tag {\n pcc_memory_entry_t *next;\n};\n\nstruct pcc_memory_pool_tag {\n pcc_memory_pool_t *next;\n size_t allocated;\n size_t unused;\n};\n\ntypedef struct pcc_memory_recycler_tag {\n pcc_memory_pool_t *pool_list;\n pcc_memory_entry_t *entry_list;\n size_t element_size;\n} pcc_memory_recycler_t;\n\nstruct #{prefix}_context_tag {\n size_t buffer_start_position; /* the position in the input of the first character currently buffered */\n size_t position_offset; /* the current parsing position in the character buffer */\n".freeze
|
77
|
+
|
78
|
+
if @location
|
79
|
+
erbout << " pcc_location_t buffer_start_position_loc;\n pcc_location_t position_offset_loc;\n".freeze
|
80
|
+
end
|
81
|
+
erbout << " size_t level;\n pcc_char_array_t buffer;\n pcc_lr_table_t lrtable;\n pcc_thunk_array_t thunks;\n pcc_auxil_t auxil;\n pcc_memory_recycler_t thunk_chunk_recycler;\n pcc_memory_recycler_t lr_memo_recycler;\n};\n\n#ifndef PCC_ERROR\n#define PCC_ERROR(auxil) pcc_error()\nMARK_FUNC_AS_USED\nstatic void pcc_error(void) {\n fprintf(stderr, \"Syntax error\\n\");\n exit(1);\n}\n#endif /* !PCC_ERROR */\n\n#ifndef PCC_GETCHAR\n#define PCC_GETCHAR(auxil) getchar()\n#endif /* !PCC_GETCHAR */\n\n#ifndef PCC_MALLOC\n#define PCC_MALLOC(auxil, size) pcc_malloc_e(size)\nstatic void *pcc_malloc_e(size_t size) {\n void *const p = malloc(size);\n if (p == NULL) {\n fprintf(stderr, \"Out of memory\\n\");\n exit(1);\n }\n return p;\n}\n#endif /* !PCC_MALLOC */\n\n#ifndef PCC_REALLOC\n#define PCC_REALLOC(auxil, ptr, size) pcc_realloc_e(ptr, size)\nstatic void *pcc_realloc_e(void *ptr, size_t size) {\n void *const p = realloc(ptr, size);\n if (p == NULL) {\n fprintf(stderr, \"Out of memory\\n\");\n exit(1);\n }\n return p;\n}\n#endif /* !PCC_REALLOC */\n\n#ifndef PCC_FREE\n#define PCC_FREE(auxil, ptr) free(ptr)\n#endif /* !PCC_FREE */\n\n#ifndef PCC_DEBUG\n#define PCC_DEBUG(auxil, event, rule, level, pos, buffer, length) ((void)0)\n#endif /* !PCC_DEBUG */\n\nstatic char *pcc_strndup_e(pcc_auxil_t auxil, const char *str, size_t len) {\n const size_t m = strnlen(str, len);\n char *const s = (char *)PCC_MALLOC(auxil, m + 1);\n memcpy(s, str, m);\n s[m] = '\\0';\n return s;\n}\n\nstatic void pcc_char_array__init(pcc_auxil_t auxil, pcc_char_array_t *array) {\n array->len = 0;\n array->max = 0;\n array->buf = NULL;\n}\n\nstatic void pcc_char_array__add(pcc_auxil_t auxil, pcc_char_array_t *array, char ch) {\n if (array->max <= array->len) {\n const size_t n = array->len + 1;\n size_t m = array->max;\n if (m == 0) m = PCC_BUFFER_MIN_SIZE;\n while (m < n && m != 0) m <<= 1;\n if (m == 0) m = n;\n array->buf = (char *)PCC_REALLOC(auxil, array->buf, m);\n array->max = m;\n }\n array->buf[array->len++] = ch;\n}\n\nstatic void pcc_char_array__term(pcc_auxil_t auxil, pcc_char_array_t *array) {\n PCC_FREE(auxil, array->buf);\n}\n\nstatic void pcc_value_table__init(pcc_auxil_t auxil, pcc_value_table_t *table) {\n table->len = 0;\n table->max = 0;\n table->buf = NULL;\n}\n\nMARK_FUNC_AS_USED\nstatic void pcc_value_table__resize(pcc_auxil_t auxil, pcc_value_table_t *table, size_t len) {\n if (table->max < len) {\n size_t m = table->max;\n if (m == 0) m = PCC_ARRAY_MIN_SIZE;\n while (m < len && m != 0) m <<= 1;\n if (m == 0) m = len;\n table->buf = (pcc_value_t *)PCC_REALLOC(auxil, table->buf, sizeof(pcc_value_t) * m);\n table->max = m;\n }\n table->len = len;\n}\n\nMARK_FUNC_AS_USED\nstatic void pcc_value_table__clear(pcc_auxil_t auxil, pcc_value_table_t *table) {\n memset(table->buf, 0, sizeof(pcc_value_t) * table->len);\n}\n\nstatic void pcc_value_table__term(pcc_auxil_t auxil, pcc_value_table_t *table) {\n PCC_FREE(auxil, table->buf);\n}\n\nstatic void pcc_value_refer_table__init(pcc_auxil_t auxil, pcc_value_refer_table_t *table) {\n table->len = 0;\n table->max = 0;\n table->buf = NULL;\n}\n\nstatic void pcc_value_refer_table__resize(pcc_auxil_t auxil, pcc_value_refer_table_t *table, size_t len) {\n size_t i;\n if (table->max < len) {\n size_t m = table->max;\n if (m == 0) m = PCC_ARRAY_MIN_SIZE;\n while (m < len && m != 0) m <<= 1;\n if (m == 0) m = len;\n table->buf = (pcc_value_t **)PCC_REALLOC(auxil, table->buf, sizeof(pcc_value_t *) * m);\n table->max = m;\n }\n for (i = table->len; i < len; i++) table->buf[i] = NULL;\n table->len = len;\n}\n\nstatic void pcc_value_refer_table__term(pcc_auxil_t auxil, pcc_value_refer_table_t *table) {\n PCC_FREE(auxil, table->buf);\n}\n\nstatic void pcc_capture_table__init(pcc_auxil_t auxil, pcc_capture_table_t *table) {\n table->len = 0;\n table->max = 0;\n table->buf = NULL;\n}\n\nMARK_FUNC_AS_USED\nstatic void pcc_capture_table__resize(pcc_auxil_t auxil, pcc_capture_table_t *table, size_t len) {\n size_t i;\n for (i = len; i < table->len; i++) PCC_FREE(auxil, table->buf[i].string);\n if (table->max < len) {\n size_t m = table->max;\n if (m == 0) m = PCC_ARRAY_MIN_SIZE;\n while (m < len && m != 0) m <<= 1;\n if (m == 0) m = len;\n table->buf = (pcc_capture_t *)PCC_REALLOC(auxil, table->buf, sizeof(pcc_capture_t) * m);\n table->max = m;\n }\n for (i = table->len; i < len; i++) {\n table->buf[i].range.start = 0;\n table->buf[i].range.end = 0;\n".freeze
|
82
|
+
|
83
|
+
if @location
|
84
|
+
erbout << " pcc_location_init(&table->buf[i].range.start_loc);\n pcc_location_init(&table->buf[i].range.end_loc);\n".freeze
|
85
|
+
end
|
86
|
+
erbout << " table->buf[i].string = NULL;\n }\n table->len = len;\n}\n\nstatic void pcc_capture_table__term(pcc_auxil_t auxil, pcc_capture_table_t *table) {\n while (table->len > 0) {\n table->len--;\n PCC_FREE(auxil, table->buf[table->len].string);\n }\n PCC_FREE(auxil, table->buf);\n}\n\nstatic void pcc_capture_const_table__init(pcc_auxil_t auxil, pcc_capture_const_table_t *table) {\n table->len = 0;\n table->max = 0;\n table->buf = NULL;\n}\n\nstatic void pcc_capture_const_table__resize(pcc_auxil_t auxil, pcc_capture_const_table_t *table, size_t len) {\n size_t i;\n if (table->max < len) {\n size_t m = table->max;\n if (m == 0) m = PCC_ARRAY_MIN_SIZE;\n while (m < len && m != 0) m <<= 1;\n if (m == 0) m = len;\n table->buf = (const pcc_capture_t **)PCC_REALLOC(auxil, (pcc_capture_t **)table->buf, sizeof(const pcc_capture_t *) * m);\n table->max = m;\n }\n for (i = table->len; i < len; i++) table->buf[i] = NULL;\n table->len = len;\n}\n\nstatic void pcc_capture_const_table__term(pcc_auxil_t auxil, pcc_capture_const_table_t *table) {\n PCC_FREE(auxil, (void *)table->buf);\n}\n\nMARK_FUNC_AS_USED\nstatic pcc_thunk_t *pcc_thunk__create_leaf(pcc_auxil_t auxil, pcc_action_t action, size_t valuec, size_t captc) {\n pcc_thunk_t *const thunk = (pcc_thunk_t *)PCC_MALLOC(auxil, sizeof(pcc_thunk_t));\n thunk->type = PCC_THUNK_LEAF;\n pcc_value_refer_table__init(auxil, &thunk->data.leaf.values);\n pcc_value_refer_table__resize(auxil, &thunk->data.leaf.values, valuec);\n pcc_capture_const_table__init(auxil, &thunk->data.leaf.capts);\n pcc_capture_const_table__resize(auxil, &thunk->data.leaf.capts, captc);\n thunk->data.leaf.capt0.range.start = 0;\n thunk->data.leaf.capt0.range.end = 0;\n".freeze
|
87
|
+
|
88
|
+
if @location
|
89
|
+
erbout << " pcc_location_init(&thunk->data.leaf.capt0.range.start_loc);\n pcc_location_init(&thunk->data.leaf.capt0.range.end_loc);\n".freeze
|
90
|
+
end
|
91
|
+
erbout << " thunk->data.leaf.capt0.string = NULL;\n thunk->data.leaf.action = action;\n return thunk;\n}\n\nstatic pcc_thunk_t *pcc_thunk__create_node(pcc_auxil_t auxil, const pcc_thunk_array_t *thunks, pcc_value_t *value) {\n pcc_thunk_t *const thunk = (pcc_thunk_t *)PCC_MALLOC(auxil, sizeof(pcc_thunk_t));\n thunk->type = PCC_THUNK_NODE;\n thunk->data.node.thunks = thunks;\n thunk->data.node.value = value;\n return thunk;\n}\n\nstatic void pcc_thunk__destroy(pcc_auxil_t auxil, pcc_thunk_t *thunk) {\n if (thunk == NULL) return;\n switch (thunk->type) {\n case PCC_THUNK_LEAF:\n PCC_FREE(auxil, thunk->data.leaf.capt0.string);\n pcc_capture_const_table__term(auxil, &thunk->data.leaf.capts);\n pcc_value_refer_table__term(auxil, &thunk->data.leaf.values);\n break;\n case PCC_THUNK_NODE:\n break;\n default: /* unknown */\n break;\n }\n PCC_FREE(auxil, thunk);\n}\n\nstatic void pcc_thunk_array__init(pcc_auxil_t auxil, pcc_thunk_array_t *array) {\n array->len = 0;\n array->max = 0;\n array->buf = NULL;\n}\n\nstatic void pcc_thunk_array__add(pcc_auxil_t auxil, pcc_thunk_array_t *array, pcc_thunk_t *thunk) {\n if (array->max <= array->len) {\n const size_t n = array->len + 1;\n size_t m = array->max;\n if (m == 0) m = PCC_ARRAY_MIN_SIZE;\n while (m < n && m != 0) m <<= 1;\n if (m == 0) m = n;\n array->buf = (pcc_thunk_t **)PCC_REALLOC(auxil, array->buf, sizeof(pcc_thunk_t *) * m);\n array->max = m;\n }\n array->buf[array->len++] = thunk;\n}\n\nstatic void pcc_thunk_array__revert(pcc_auxil_t auxil, pcc_thunk_array_t *array, size_t len) {\n while (array->len > len) {\n array->len--;\n pcc_thunk__destroy(auxil, array->buf[array->len]);\n }\n}\n\nstatic void pcc_thunk_array__term(pcc_auxil_t auxil, pcc_thunk_array_t *array) {\n while (array->len > 0) {\n array->len--;\n pcc_thunk__destroy(auxil, array->buf[array->len]);\n }\n PCC_FREE(auxil, array->buf);\n}\n\nstatic void pcc_memory_recycler__init(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler, size_t element_size) {\n recycler->pool_list = NULL;\n recycler->entry_list = NULL;\n recycler->element_size = element_size;\n}\n\nstatic void *pcc_memory_recycler__supply(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler) {\n if (recycler->entry_list) {\n pcc_memory_entry_t *const tmp = recycler->entry_list;\n recycler->entry_list = tmp->next;\n return tmp;\n }\n if (!recycler->pool_list || recycler->pool_list->unused == 0) {\n size_t size = PCC_POOL_MIN_SIZE;\n if (recycler->pool_list) {\n size = recycler->pool_list->allocated << 1;\n if (size == 0) size = recycler->pool_list->allocated;\n }\n {\n pcc_memory_pool_t *const pool = (pcc_memory_pool_t *)PCC_MALLOC(\n auxil, sizeof(pcc_memory_pool_t) + recycler->element_size * size\n );\n pool->allocated = size;\n pool->unused = size;\n pool->next = recycler->pool_list;\n recycler->pool_list = pool;\n }\n }\n recycler->pool_list->unused--;\n return (char *)recycler->pool_list + sizeof(pcc_memory_pool_t) + recycler->element_size * recycler->pool_list->unused;\n}\n\nstatic void pcc_memory_recycler__recycle(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler, void *ptr) {\n pcc_memory_entry_t *const tmp = (pcc_memory_entry_t *)ptr;\n tmp->next = recycler->entry_list;\n recycler->entry_list = tmp;\n}\n\nstatic void pcc_memory_recycler__term(pcc_auxil_t auxil, pcc_memory_recycler_t *recycler) {\n while (recycler->pool_list) {\n pcc_memory_pool_t *const tmp = recycler->pool_list;\n recycler->pool_list = tmp->next;\n PCC_FREE(auxil, tmp);\n }\n}\n\nMARK_FUNC_AS_USED\nstatic pcc_thunk_chunk_t *pcc_thunk_chunk__create(pcc_context_t *ctx) {\n pcc_thunk_chunk_t *const chunk = (pcc_thunk_chunk_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->thunk_chunk_recycler);\n pcc_value_table__init(ctx->auxil, &chunk->values);\n pcc_capture_table__init(ctx->auxil, &chunk->capts);\n pcc_thunk_array__init(ctx->auxil, &chunk->thunks);\n chunk->pos = 0;\n return chunk;\n}\n\nstatic void pcc_thunk_chunk__destroy(pcc_context_t *ctx, pcc_thunk_chunk_t *chunk) {\n if (chunk == NULL) return;\n pcc_thunk_array__term(ctx->auxil, &chunk->thunks);\n pcc_capture_table__term(ctx->auxil, &chunk->capts);\n pcc_value_table__term(ctx->auxil, &chunk->values);\n pcc_memory_recycler__recycle(ctx->auxil, &ctx->thunk_chunk_recycler, chunk);\n}\n\nstatic void pcc_rule_set__init(pcc_auxil_t auxil, pcc_rule_set_t *set) {\n set->len = 0;\n set->max = 0;\n set->buf = NULL;\n}\n\nstatic size_t pcc_rule_set__index(pcc_auxil_t auxil, const pcc_rule_set_t *set, pcc_rule_t rule) {\n size_t i;\n for (i = 0; i < set->len; i++) {\n if (set->buf[i] == rule) return i;\n }\n return PCC_VOID_VALUE;\n}\n\nstatic pcc_bool_t pcc_rule_set__add(pcc_auxil_t auxil, pcc_rule_set_t *set, pcc_rule_t rule) {\n const size_t i = pcc_rule_set__index(auxil, set, rule);\n if (i != PCC_VOID_VALUE) return PCC_FALSE;\n if (set->max <= set->len) {\n const size_t n = set->len + 1;\n size_t m = set->max;\n if (m == 0) m = PCC_ARRAY_MIN_SIZE;\n while (m < n && m != 0) m <<= 1;\n if (m == 0) m = n;\n set->buf = (pcc_rule_t *)PCC_REALLOC(auxil, set->buf, sizeof(pcc_rule_t) * m);\n set->max = m;\n }\n set->buf[set->len++] = rule;\n return PCC_TRUE;\n}\n\nstatic void pcc_rule_set__term(pcc_auxil_t auxil, pcc_rule_set_t *set) {\n PCC_FREE(auxil, set->buf);\n}\n\nstatic pcc_lr_memo_t *pcc_lr_memo__create(pcc_context_t *ctx, size_t offset".freeze
|
92
|
+
if @location
|
93
|
+
erbout << ", pcc_location_t offset_loc".freeze
|
94
|
+
end
|
95
|
+
erbout << ") {\n pcc_lr_memo_t *memo = (pcc_lr_memo_t *)pcc_memory_recycler__supply(ctx->auxil, &ctx->lr_memo_recycler);\n memo->offset = offset;\n".freeze
|
96
|
+
|
97
|
+
if @location
|
98
|
+
erbout << " memo->offset_loc = offset_loc;\n".freeze
|
99
|
+
end
|
100
|
+
erbout << " memo->chunk = NULL;\n memo->fail = PCC_TRUE;\n memo->grow = PCC_FALSE;\n memo->hold = NULL;\n return memo;\n}\n\nstatic void pcc_lr_memo__set_chunk(pcc_context_t *ctx, pcc_lr_memo_t *memo, pcc_thunk_chunk_t *chunk) {\n if (memo->chunk) {\n pcc_lr_memo_t *const a = pcc_lr_memo__create(ctx, memo->offset".freeze
|
101
|
+
|
102
|
+
if @location
|
103
|
+
erbout << ", memo->offset_loc".freeze
|
104
|
+
end
|
105
|
+
erbout << ");\n a->chunk = memo->chunk;\n a->hold = memo->hold;\n memo->hold = a;\n }\n memo->chunk = chunk;\n memo->fail = PCC_FALSE;\n}\n\nstatic void pcc_lr_memo__destroy(pcc_context_t *ctx, pcc_lr_memo_t *memo) {\n while (memo != NULL) {\n pcc_lr_memo_t *const a = memo->hold;\n pcc_thunk_chunk__destroy(ctx, memo->chunk);\n pcc_memory_recycler__recycle(ctx->auxil, &ctx->lr_memo_recycler, memo);\n memo = a;\n }\n}\n\nstatic void pcc_lr_memo_map__init(pcc_auxil_t auxil, pcc_lr_memo_map_t *map) {\n map->len = 0;\n map->max = 0;\n map->buf = NULL;\n}\n\nstatic size_t pcc_lr_memo_map__index(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule) {\n size_t i;\n for (i = 0; i < map->len; i++) {\n if (map->buf[i].rule == rule) return i;\n }\n return PCC_VOID_VALUE;\n}\n\nstatic void pcc_lr_memo_map__put(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule, pcc_lr_memo_t *memo) {\n const size_t i = pcc_lr_memo_map__index(ctx, map, rule);\n if (i != PCC_VOID_VALUE) {\n pcc_lr_memo__destroy(ctx, map->buf[i].memo);\n map->buf[i].memo = memo;\n }\n else {\n if (map->max <= map->len) {\n const size_t n = map->len + 1;\n size_t m = map->max;\n if (m == 0) m = PCC_ARRAY_MIN_SIZE;\n while (m < n && m != 0) m <<= 1;\n if (m == 0) m = n;\n map->buf = (pcc_lr_memo_map_entry_t *)PCC_REALLOC(ctx->auxil, map->buf, sizeof(pcc_lr_memo_map_entry_t) * m);\n map->max = m;\n }\n map->buf[map->len].rule = rule;\n map->buf[map->len].memo = memo;\n map->len++;\n }\n}\n\nstatic pcc_lr_memo_t *pcc_lr_memo_map__get(pcc_context_t *ctx, pcc_lr_memo_map_t *map, pcc_rule_t rule) {\n const size_t i = pcc_lr_memo_map__index(ctx, map, rule);\n return (i != PCC_VOID_VALUE) ? map->buf[i].memo : NULL;\n}\n\nstatic void pcc_lr_memo_map__term(pcc_context_t *ctx, pcc_lr_memo_map_t *map) {\n while (map->len > 0) {\n map->len--;\n pcc_lr_memo__destroy(ctx, map->buf[map->len].memo);\n }\n PCC_FREE(ctx->auxil, map->buf);\n}\n\nstatic pcc_lr_memo_map_t *pcc_lr_memo_map__create(pcc_context_t *ctx) {\n pcc_lr_memo_map_t *const memo = (pcc_lr_memo_map_t *)PCC_MALLOC(ctx->auxil, sizeof(pcc_lr_memo_map_t));\n pcc_lr_memo_map__init(ctx->auxil, memo);\n return memo;\n}\n\nstatic void pcc_lr_memo_map__destroy(pcc_context_t *ctx, pcc_lr_memo_map_t *memo) {\n if (memo == NULL) return;\n pcc_lr_memo_map__term(ctx, memo);\n PCC_FREE(ctx->auxil, memo);\n}\n\nstatic void pcc_lr_table__init(pcc_auxil_t auxil, pcc_lr_table_t *table) {\n table->ofs = 0;\n table->len = 0;\n table->max = 0;\n table->buf = NULL;\n}\n\nstatic void pcc_lr_table__resize(pcc_context_t *ctx, pcc_lr_table_t *table, size_t len) {\n size_t i;\n for (i = len; i < table->len; i++) pcc_lr_memo_map__destroy(ctx, table->buf[i]);\n if (table->max < len) {\n size_t m = table->max;\n if (m == 0) m = PCC_ARRAY_MIN_SIZE;\n while (m < len && m != 0) m <<= 1;\n if (m == 0) m = len;\n table->buf = (pcc_lr_memo_map_t **)PCC_REALLOC(ctx->auxil, table->buf, sizeof(pcc_lr_memo_map_t *) * m);\n table->max = m;\n }\n for (i = table->len; i < len; i++) table->buf[i] = NULL;\n table->len = len;\n}\n\nstatic void pcc_lr_table__set_memo(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_rule_t rule, pcc_lr_memo_t *memo) {\n index += table->ofs;\n if (index >= table->len) pcc_lr_table__resize(ctx, table, index + 1);\n if (table->buf[index] == NULL) table->buf[index] = pcc_lr_memo_map__create(ctx);\n pcc_lr_memo_map__put(ctx, table->buf[index], rule, memo);\n}\n\nstatic pcc_lr_memo_t *pcc_lr_table__get_memo(pcc_context_t *ctx, pcc_lr_table_t *table, size_t index, pcc_rule_t rule) {\n index += table->ofs;\n if (index >= table->len || table->buf[index] == NULL) return NULL;\n return pcc_lr_memo_map__get(ctx, table->buf[index], rule);\n}\n\nstatic void pcc_lr_table__shift(pcc_context_t *ctx, pcc_lr_table_t *table, size_t count) {\n size_t i;\n if (count > table->len - table->ofs) count = table->len - table->ofs;\n for (i = 0; i < count; i++) pcc_lr_memo_map__destroy(ctx, table->buf[table->ofs++]);\n if (table->ofs > (table->max >> 1)) {\n memmove(table->buf, table->buf + table->ofs, sizeof(pcc_lr_memo_map_t *) * (table->len - table->ofs));\n table->len -= table->ofs;\n table->ofs = 0;\n }\n}\n\nstatic void pcc_lr_table__term(pcc_context_t *ctx, pcc_lr_table_t *table) {\n while (table->len > table->ofs) {\n table->len--;\n pcc_lr_memo_map__destroy(ctx, table->buf[table->len]);\n }\n PCC_FREE(ctx->auxil, table->buf);\n}\n\nstatic pcc_context_t *pcc_context__create(pcc_auxil_t auxil) {\n pcc_context_t *const ctx = (pcc_context_t *)PCC_MALLOC(auxil, sizeof(pcc_context_t));\n ctx->buffer_start_position = 0;\n ctx->position_offset = 0;\n".freeze
|
106
|
+
|
107
|
+
if @location
|
108
|
+
erbout << " pcc_location_init(&ctx->buffer_start_position_loc);\n pcc_location_init(&ctx->position_offset_loc);\n".freeze
|
109
|
+
end
|
110
|
+
erbout << " ctx->level = 0;\n pcc_char_array__init(auxil, &ctx->buffer);\n pcc_lr_table__init(auxil, &ctx->lrtable);\n pcc_thunk_array__init(auxil, &ctx->thunks);\n pcc_memory_recycler__init(auxil, &ctx->thunk_chunk_recycler, sizeof(pcc_thunk_chunk_t));\n pcc_memory_recycler__init(auxil, &ctx->lr_memo_recycler, sizeof(pcc_lr_memo_t));\n ctx->auxil = auxil;\n return ctx;\n}\n\nstatic void pcc_context__destroy(pcc_context_t *ctx) {\n if (ctx == NULL) return;\n pcc_thunk_array__term(ctx->auxil, &ctx->thunks);\n pcc_lr_table__term(ctx, &ctx->lrtable);\n pcc_char_array__term(ctx->auxil, &ctx->buffer);\n pcc_memory_recycler__term(ctx->auxil, &ctx->thunk_chunk_recycler);\n pcc_memory_recycler__term(ctx->auxil, &ctx->lr_memo_recycler);\n PCC_FREE(ctx->auxil, ctx);\n}\n\nstatic size_t pcc_refill_buffer(pcc_context_t *ctx, size_t num) {\n if (ctx->buffer.len >= ctx->position_offset + num) return ctx->buffer.len - ctx->position_offset;\n while (ctx->buffer.len < ctx->position_offset + num) {\n const int c = PCC_GETCHAR(ctx->auxil);\n if (c < 0) break;\n pcc_char_array__add(ctx->auxil, &ctx->buffer, (char)c);\n }\n return ctx->buffer.len - ctx->position_offset;\n}\n\nMARK_FUNC_AS_USED\nstatic void pcc_commit_buffer(pcc_context_t *ctx) {\n memmove(ctx->buffer.buf, ctx->buffer.buf + ctx->position_offset, ctx->buffer.len - ctx->position_offset);\n ctx->buffer.len -= ctx->position_offset;\n ctx->buffer_start_position += ctx->position_offset;\n pcc_lr_table__shift(ctx, &ctx->lrtable, ctx->position_offset);\n ctx->position_offset = 0;\n".freeze
|
111
|
+
|
112
|
+
if @location
|
113
|
+
erbout << " ctx->buffer_start_position_loc = pcc_location_add(ctx->buffer_start_position_loc, ctx->position_offset_loc);\n pcc_location_init(&ctx->position_offset_loc);\n".freeze
|
114
|
+
end
|
115
|
+
erbout << "}\n\nMARK_FUNC_AS_USED\nstatic const char *pcc_get_capture_string(pcc_context_t *ctx, const pcc_capture_t *capt) {\n if (capt->string == NULL)\n ((pcc_capture_t *)capt)->string =\n pcc_strndup_e(ctx->auxil, ctx->buffer.buf + capt->range.start, capt->range.end - capt->range.start);\n return capt->string;\n}\n\n".freeze
|
116
|
+
|
117
|
+
if @utf8
|
118
|
+
erbout << "static size_t pcc_get_char_as_utf32(pcc_context_t *ctx, int *out) { /* with checking UTF-8 validity */\n int c, u;\n size_t n;\n if (pcc_refill_buffer(ctx, 1) < 1) return 0;\n c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset];\n n = (c < 0x80) ? 1 :\n ((c & 0xe0) == 0xc0) ? 2 :\n ((c & 0xf0) == 0xe0) ? 3 :\n ((c & 0xf8) == 0xf0) ? 4 : 0;\n if (n < 1) return 0;\n if (pcc_refill_buffer(ctx, n) < n) return 0;\n switch (n) {\n case 1:\n u = c;\n break;\n case 2:\n u = c & 0x1f;\n c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];\n if ((c & 0xc0) != 0x80) return 0;\n u <<= 6; u |= c & 0x3f;\n if (u < 0x80) return 0;\n break;\n case 3:\n u = c & 0x0f;\n c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];\n if ((c & 0xc0) != 0x80) return 0;\n u <<= 6; u |= c & 0x3f;\n c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 2];\n if ((c & 0xc0) != 0x80) return 0;\n u <<= 6; u |= c & 0x3f;\n if (u < 0x800) return 0;\n break;\n case 4:\n u = c & 0x07;\n c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 1];\n if ((c & 0xc0) != 0x80) return 0;\n u <<= 6; u |= c & 0x3f;\n c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 2];\n if ((c & 0xc0) != 0x80) return 0;\n u <<= 6; u |= c & 0x3f;\n c = (int)(unsigned char)ctx->buffer.buf[ctx->position_offset + 3];\n if ((c & 0xc0) != 0x80) return 0;\n u <<= 6; u |= c & 0x3f;\n if (u < 0x10000 || u > 0x10ffff) return 0;\n break;\n default:\n return 0;\n }\n if (out) *out = u;\n return n;\n}\n\n".freeze
|
119
|
+
end
|
120
|
+
erbout << "static void pcc_grow_lr(pcc_context_t *ctx, pcc_rule_t rule, size_t offset".freeze
|
121
|
+
if @location
|
122
|
+
erbout << ", pcc_location_t offset_loc".freeze
|
123
|
+
end
|
124
|
+
erbout << ") {\n while(1) {\n const size_t old_offset = ctx->position_offset;\n pcc_thunk_chunk_t *chunk;\n pcc_lr_memo_t *memo;\n pcc_rule_set_t limits;\n ctx->position_offset = offset;\n".freeze
|
125
|
+
|
126
|
+
if @location
|
127
|
+
erbout << " ctx->position_offset_loc = offset_loc;\n".freeze
|
128
|
+
end
|
129
|
+
erbout << " pcc_rule_set__init(ctx->auxil, &limits);\n pcc_rule_set__add(ctx->auxil, &limits, rule);\n chunk = rule(ctx, offset".freeze
|
130
|
+
|
131
|
+
if @location
|
132
|
+
erbout << ", offset_loc".freeze
|
133
|
+
end
|
134
|
+
erbout << ", &limits);\n pcc_rule_set__term(ctx->auxil, &limits);\n if (!chunk)\n break;\n if (ctx->position_offset <= old_offset) {\n pcc_thunk_chunk__destroy(ctx, chunk);\n break;\n }\n memo = pcc_lr_table__get_memo(ctx, &ctx->lrtable, offset, rule);\n pcc_lr_memo__set_chunk(ctx, memo, chunk);\n memo->offset = ctx->position_offset;\n".freeze
|
135
|
+
|
136
|
+
if @location
|
137
|
+
erbout << " memo->offset_loc = ctx->position_offset_loc;\n".freeze
|
138
|
+
end
|
139
|
+
erbout << " }\n}\n\nMARK_FUNC_AS_USED\nstatic pcc_thunk_chunk_t *pcc_get_rule_thunk_chunk(pcc_context_t *ctx, pcc_rule_t rule) {\n pcc_thunk_chunk_t *c = NULL;\n size_t offset = ctx->position_offset;\n".freeze
|
140
|
+
|
141
|
+
if @location
|
142
|
+
erbout << " pcc_location_t offset_loc = ctx->position_offset_loc;\n".freeze
|
143
|
+
end
|
144
|
+
erbout << " pcc_lr_memo_t *a = pcc_lr_table__get_memo(ctx, &ctx->lrtable, offset, rule);\n\n if (a == NULL) {\n a = pcc_lr_memo__create(ctx, offset".freeze
|
145
|
+
|
146
|
+
if @location
|
147
|
+
erbout << ", offset_loc".freeze
|
148
|
+
end
|
149
|
+
erbout << ");\n pcc_lr_table__set_memo(ctx, &ctx->lrtable, offset, rule, a);\n c = rule(ctx, offset".freeze
|
150
|
+
|
151
|
+
if @location
|
152
|
+
erbout << ", offset_loc".freeze
|
153
|
+
end
|
154
|
+
erbout << ", NULL);\n pcc_lr_memo__set_chunk(ctx, a, c);\n a->offset = ctx->position_offset;\n".freeze
|
155
|
+
|
156
|
+
if @location
|
157
|
+
erbout << " a->offset_loc = ctx->position_offset_loc;\n".freeze
|
158
|
+
end
|
159
|
+
erbout << " if (a->grow) {\n pcc_grow_lr(ctx, rule, offset".freeze
|
160
|
+
|
161
|
+
if @location
|
162
|
+
erbout << ", offset_loc".freeze
|
163
|
+
end
|
164
|
+
erbout << ");\n a->grow = PCC_FALSE;\n ctx->position_offset = a->offset;\n return a->chunk;\n }\n return c;\n } else if (a->fail) {\n pcc_lr_memo__set_chunk(ctx, a, NULL);\n a->grow = PCC_TRUE;\n return NULL;\n }\n ctx->position_offset = a->offset;\n return a->chunk;\n}\n\nMARK_FUNC_AS_USED\nstatic pcc_bool_t pcc_apply_rule(pcc_context_t *ctx, pcc_rule_t rule, pcc_thunk_array_t *thunks, pcc_value_t *value, size_t offset".freeze
|
165
|
+
|
166
|
+
if @location
|
167
|
+
erbout << ", pcc_location_t offset_loc".freeze
|
168
|
+
end
|
169
|
+
erbout << ", pcc_rule_set_t *limits) {\n static pcc_value_t null;\n pcc_thunk_chunk_t *c;\n if (limits != NULL) {\n pcc_lr_memo_t *a;\n pcc_rule_set__add(ctx->auxil, limits, rule);\n c = rule(ctx, offset".freeze
|
170
|
+
|
171
|
+
if @location
|
172
|
+
erbout << ", offset_loc".freeze
|
173
|
+
end
|
174
|
+
erbout << ", limits);\n a = pcc_lr_table__get_memo(ctx, &ctx->lrtable, offset, rule);\n if (a == NULL || ctx->position_offset <= a->offset) {\n c = a->chunk;\n ctx->position_offset = a->offset;\n } else {\n pcc_lr_memo__set_chunk(ctx, a, c);\n a->offset = ctx->position_offset;\n }\n } else {\n c = pcc_get_rule_thunk_chunk(ctx, rule);\n }\n if (c == NULL) return PCC_FALSE;\n if (value == NULL) value = &null;\n memset(value, 0, sizeof(pcc_value_t)); /* in case */\n pcc_thunk_array__add(ctx->auxil, thunks, pcc_thunk__create_node(ctx->auxil, &c->thunks, value));\n return PCC_TRUE;\n}\n\nMARK_FUNC_AS_USED\nstatic void pcc_do_action(pcc_context_t *ctx, const pcc_thunk_array_t *thunks, pcc_value_t *value) {\n size_t i;\n for (i = 0; i < thunks->len; i++) {\n pcc_thunk_t *const thunk = thunks->buf[i];\n switch (thunk->type) {\n case PCC_THUNK_LEAF:\n thunk->data.leaf.action(ctx, thunk, value);\n break;\n case PCC_THUNK_NODE:\n pcc_do_action(ctx, thunk->data.node.thunks, thunk->data.node.value);\n break;\n default: /* unknown */\n break;\n }\n }\n}\n\n".freeze
|
175
|
+
|
176
|
+
@root.rules.each do |rule|
|
177
|
+
rule.codes.each do |code|
|
178
|
+
erbout << "static void pcc_action_#{rule.name}_#{code.index}(#{prefix}_context_t *__pcc_ctx, pcc_thunk_t *__pcc_in, pcc_value_t *__pcc_out) {\n#define auxil (__pcc_ctx->auxil)\n#define __ (*__pcc_out)\n".freeze
|
179
|
+
|
180
|
+
code.vars.each do |ref|
|
181
|
+
erbout << "#define #{ref.var} (*__pcc_in->data.leaf.values.buf[#{ref.index}])\n".freeze
|
182
|
+
end
|
183
|
+
erbout << "#define _0 pcc_get_capture_string(__pcc_ctx, &__pcc_in->data.leaf.capt0)\n#define _0s ((const size_t)(__pcc_ctx->buffer_start_position + __pcc_in->data.leaf.capt0.range.start))\n#define _0e ((const size_t)(__pcc_ctx->buffer_start_position + __pcc_in->data.leaf.capt0.range.end))\n".freeze
|
184
|
+
|
185
|
+
if @location
|
186
|
+
erbout << "#define _0sl ((const pcc_location_t)(pcc_location_add(__pcc_ctx->buffer_start_position_loc, __pcc_in->data.leaf.capt0.range.start_loc)))\n#define _0el ((const pcc_location_t)(pcc_location_add(__pcc_ctx->buffer_start_position_loc, __pcc_in->data.leaf.capt0.range.end_loc)))\n".freeze
|
187
|
+
end
|
188
|
+
if @capture_in_code
|
189
|
+
erbout << "#define _0c __pcc_in->data.leaf.capt0\n".freeze
|
190
|
+
end
|
191
|
+
code.capts.each do |capture|
|
192
|
+
erbout << "#define _#{capture.index + 1} pcc_get_capture_string(__pcc_ctx, __pcc_in->data.leaf.capts.buf[#{capture.index}])\n#define _#{capture.index + 1}s ((const size_t)(__pcc_ctx->buffer_start_position + __pcc_in->data.leaf.capts.buf[#{capture.index}]->range.start))\n#define _#{capture.index + 1}e ((const size_t)(__pcc_ctx->buffer_start_position + __pcc_in->data.leaf.capts.buf[#{capture.index}]->range.end))\n".freeze
|
193
|
+
|
194
|
+
if @location
|
195
|
+
erbout << "#define _#{capture.index + 1}sl ((const pcc_location_t)(pcc_location_add(__pcc_ctx->buffer_start_position_loc, __pcc_in->data.leaf.capts.buf[#{capture.index}]->range.start_loc)))\n#define _#{capture.index + 1}el ((const pcc_location_t)(pcc_location_add(__pcc_ctx->buffer_start_position_loc, __pcc_in->data.leaf.capts.buf[#{capture.index}]->range.end_loc)))\n".freeze
|
196
|
+
end
|
197
|
+
next unless @capture_in_code
|
198
|
+
|
199
|
+
erbout << "#define _#{capture.index + 1}c (*__pcc_in->data.leaf.capts.buf[#{capture.index}])\n".freeze
|
200
|
+
end
|
201
|
+
erbout << "#{stream.get_code_block(code.code, 4, @iname)}".freeze
|
202
|
+
code.capts.reverse_each do |capture|
|
203
|
+
if @location
|
204
|
+
erbout << "#undef _#{capture.index + 1}el\n#undef _#{capture.index + 1}sl\n".freeze
|
205
|
+
end
|
206
|
+
erbout << "#undef _#{capture.index + 1}e\n#undef _#{capture.index + 1}s\n#undef _#{capture.index + 1}\n".freeze
|
207
|
+
end
|
208
|
+
erbout << "#undef _0e\n#undef _0s\n#undef _0\n".freeze
|
209
|
+
|
210
|
+
code.vars.reverse_each do |ref|
|
211
|
+
erbout << "#undef #{ref.var}\n".freeze
|
212
|
+
end
|
213
|
+
erbout << "#undef __\n#undef auxil\n}\n\n".freeze
|
214
|
+
end
|
215
|
+
end
|
216
|
+
@root.rules.each do |rule|
|
217
|
+
erbout << "static pcc_thunk_chunk_t *pcc_evaluate_rule_#{rule.name}(pcc_context_t *ctx, size_t offset".freeze
|
218
|
+
if @location
|
219
|
+
erbout << ", pcc_location_t offset_loc".freeze
|
220
|
+
end
|
221
|
+
erbout << ", pcc_rule_set_t *limits);\n".freeze
|
222
|
+
end
|
223
|
+
erbout << "\n".freeze
|
224
|
+
|
225
|
+
@root.rules.each do |rule|
|
226
|
+
gen = ::Packcr::Generator.new(rule, @ascii, @location)
|
227
|
+
erbout << "#{gen.generate_code(rule, 0, 0, false)}\n".freeze
|
228
|
+
end
|
229
|
+
erbout << "#{prefix}_context_t *#{prefix}_create(#{auxil_def}auxil) {\n return pcc_context__create(auxil);\n}\n\nint #{prefix}_parse(#{prefix}_context_t *ctx, #{value_def}*ret) {\n size_t pos = ctx->buffer_start_position;\n".freeze
|
230
|
+
|
231
|
+
if !@root.rules.empty?
|
232
|
+
erbout << " if (pcc_apply_rule(ctx, pcc_evaluate_rule_#{@root.rules[0].name}, &ctx->thunks, ret, ctx->position_offset".freeze
|
233
|
+
if @location
|
234
|
+
erbout << ", ctx->position_offset_loc".freeze
|
235
|
+
end
|
236
|
+
erbout << ", NULL))\n pcc_do_action(ctx, &ctx->thunks, ret);\n else\n PCC_ERROR(ctx->auxil);\n pcc_commit_buffer(ctx);\n".freeze
|
237
|
+
end
|
238
|
+
erbout << " pcc_thunk_array__revert(ctx->auxil, &ctx->thunks, 0);\n return pos != ctx->buffer_start_position && pcc_refill_buffer(ctx, 1) >= 1;\n}\n\nvoid #{prefix}_destroy(#{prefix}_context_t *ctx) {\n pcc_context__destroy(ctx);\n}\n".freeze
|
239
|
+
|
240
|
+
if !code(:lsource).empty?
|
241
|
+
erbout << "\n".freeze
|
242
|
+
|
243
|
+
code(:lsource).each do |code|
|
244
|
+
erbout << "#{stream.get_code_block(code, 0, @iname)}".freeze
|
245
|
+
end
|
246
|
+
end
|
247
|
+
erbout
|
248
|
+
when :rb
|
249
|
+
erbout = +""
|
250
|
+
erbout << "# A packrat parser generated by PackCR #{Packcr::VERSION}\n".freeze
|
251
|
+
|
252
|
+
if !code(:source).empty?
|
253
|
+
erbout << "\n".freeze
|
254
|
+
|
255
|
+
code(:source).each do |code|
|
256
|
+
erbout << "#{stream.get_code_block(code, 0, @iname)}".freeze
|
257
|
+
end
|
258
|
+
end
|
259
|
+
erbout << "\nclass #{class_name}\n def initialize(".freeze
|
260
|
+
if @auxil_type
|
261
|
+
erbout << "#{auxil_type}, ".freeze
|
262
|
+
end
|
263
|
+
erbout << "debug: false)\n".freeze
|
264
|
+
|
265
|
+
if @utf8
|
266
|
+
erbout << " @buffer = +\"\"\n".freeze
|
267
|
+
|
268
|
+
else
|
269
|
+
erbout << " @buffer = +\"\".b\n".freeze
|
270
|
+
end
|
271
|
+
erbout << "\n @buffer_start_position = 0\n @position_offset = 0\n @level = 0\n @thunk = ThunkNode.new([], nil, 0)\n @memos = LrMemoTable.new\n @debug = debug\n @global_values = {}\n".freeze
|
272
|
+
|
273
|
+
if @location
|
274
|
+
erbout << " @buffer_start_position_loc = Location.new\n @position_offset_loc = Location.new\n".freeze
|
275
|
+
end
|
276
|
+
code(:init).each do |code|
|
277
|
+
erbout << "#{stream.get_code_block(code, 4, @iname)}".freeze
|
278
|
+
end
|
279
|
+
erbout << " end\n\n def debug\n yield if @debug\n end\n\n def getc\n".freeze
|
280
|
+
|
281
|
+
if @utf8
|
282
|
+
erbout << " $stdin.getc\n".freeze
|
283
|
+
|
284
|
+
else
|
285
|
+
erbout << " $stdin.getc&.b\n".freeze
|
286
|
+
end
|
287
|
+
erbout << " end\n\n def refill_buffer(num, mode = nil)\n len = @buffer.length\n if len >= @position_offset + num\n return len - @position_offset\n end\n while len < @position_offset + num\n c = getc\n break if !c\n @buffer << c\n len = @buffer.length\n end\n return len - @position_offset\n end\n\n def commit_buffer\n @buffer = @buffer[@position_offset, @buffer.length - @position_offset]\n @buffer_start_position += @position_offset\n @memos.clear\n @position_offset = 0\n".freeze
|
288
|
+
|
289
|
+
if @location
|
290
|
+
erbout << " @buffer_start_position_loc = @buffer_start_position_loc + @position_offset_loc\n @position_offset_loc = Location.new\n".freeze
|
291
|
+
end
|
292
|
+
erbout << " end\n\n def parse\n pos = @buffer_start_position\n".freeze
|
293
|
+
|
294
|
+
if !@root.rules.empty?
|
295
|
+
erbout << " if apply_rule(:evaluate_rule_#{@root.rules[0].name}, @thunk.thunks, nil, 0, @buffer_start_position".freeze
|
296
|
+
if @location
|
297
|
+
erbout << ", @buffer_start_position_loc".freeze
|
298
|
+
end
|
299
|
+
erbout << ")\n @thunk.do_action(self, nil, 0)\n else\n raise SyntaxError, \"can't parse\"\n end\n commit_buffer\n".freeze
|
300
|
+
end
|
301
|
+
erbout << " @thunk.clear\n refill_buffer(1) >= 1 && pos != @buffer_start_position\n end\n\n def run\n nil while parse\n end\n\n".freeze
|
302
|
+
|
303
|
+
@root.rules.each do |rule|
|
304
|
+
rule.codes.each do |code|
|
305
|
+
erbout << " def action_#{rule.name}_#{code.index}(__pcc_in, __pcc_vars, __pcc_index)\n ____ = (__pcc_vars[__pcc_index] ||= Value.new).value if __pcc_vars\n".freeze
|
306
|
+
|
307
|
+
code.vars.each do |ref|
|
308
|
+
erbout << " #{ref.var} = (__pcc_in.value_refs[#{ref.index}] ||= Value.new).value\n".freeze
|
309
|
+
end
|
310
|
+
erbout << " __0 = __pcc_in.capt0.capture_string(@buffer)\n __0s = @buffer_start_position + __pcc_in.capt0.range_start\n __0e = @buffer_start_position + __pcc_in.capt0.range_end\n".freeze
|
311
|
+
|
312
|
+
if @location
|
313
|
+
erbout << " __0sl = @buffer_start_position_loc + __pcc_in.capt0.start_loc\n __0el = @buffer_start_position_loc + __pcc_in.capt0.end_loc\n".freeze
|
314
|
+
end
|
315
|
+
if @capture_in_code
|
316
|
+
erbout << " __0c = __pcc_in.capt0\n".freeze
|
317
|
+
end
|
318
|
+
code.capts.each do |capture|
|
319
|
+
erbout << " __#{capture.index + 1} = __pcc_in.capts[#{capture.index}].capture_string(@buffer)\n __#{capture.index + 1}s = @buffer_start_position + __pcc_in.capts[#{capture.index}].range_start\n __#{capture.index + 1}e = @buffer_start_position + __pcc_in.capts[#{capture.index}].range_end\n".freeze
|
320
|
+
|
321
|
+
if @location
|
322
|
+
erbout << " __#{capture.index + 1}sl = @buffer_start_position_loc + __pcc_in.capts[#{capture.index}].start_loc\n __#{capture.index + 1}el = @buffer_start_position_loc + __pcc_in.capts[#{capture.index}].end_loc\n".freeze
|
323
|
+
end
|
324
|
+
next unless @capture_in_code
|
325
|
+
|
326
|
+
erbout << " __#{capture.index + 1}c = __pcc_in.capts[#{capture.index}]\n".freeze
|
327
|
+
end
|
328
|
+
|
329
|
+
erbout << "#{stream.get_code_block(code.code, 4, @iname)}\n __pcc_vars[__pcc_index].value = ____ if __pcc_vars\n end\n\n".freeze
|
330
|
+
end
|
331
|
+
end
|
332
|
+
@root.rules.each do |rule|
|
333
|
+
gen = ::Packcr::Generator.new(rule, @ascii, @location, :rb)
|
334
|
+
|
335
|
+
erbout << "#{gen.generate_code(rule, 0, 2, false)}\n".freeze
|
336
|
+
end
|
337
|
+
erbout << " def grow_lr(rule, offset".freeze
|
338
|
+
if @location
|
339
|
+
erbout << ", offset_loc".freeze
|
340
|
+
end
|
341
|
+
erbout << ")\n while true\n old_offset = @position_offset\n @position_offset = offset\n".freeze
|
342
|
+
|
343
|
+
if @location
|
344
|
+
erbout << " @position_offset_loc = offset_loc\n".freeze
|
345
|
+
end
|
346
|
+
erbout << " answer = public_send(rule, offset".freeze
|
347
|
+
if @location
|
348
|
+
erbout << ", offset_loc".freeze
|
349
|
+
end
|
350
|
+
erbout << ", limits: {rule => true})\n if !answer || @position_offset <= old_offset\n break\n end\n memo = @memos[offset, rule]\n memo.answer = answer\n memo.offset = @position_offset\n".freeze
|
351
|
+
|
352
|
+
if @location
|
353
|
+
erbout << " memo.offset_loc = @position_offset_loc\n".freeze
|
354
|
+
end
|
355
|
+
erbout << " end\n end\n\n def rule_answer(rule)\n offset = @position_offset\n".freeze
|
356
|
+
|
357
|
+
if @location
|
358
|
+
erbout << " offset_loc = @position_offset_loc\n".freeze
|
359
|
+
end
|
360
|
+
erbout << " memo = @memos[offset, rule]\n\n if !memo\n memo = LrMemo.new(offset".freeze
|
361
|
+
|
362
|
+
if @location
|
363
|
+
erbout << ", offset_loc".freeze
|
364
|
+
end
|
365
|
+
erbout << ")\n @memos[offset, rule] = memo\n answer = public_send(rule, offset".freeze
|
366
|
+
|
367
|
+
if @location
|
368
|
+
erbout << ", offset_loc".freeze
|
369
|
+
end
|
370
|
+
erbout << ")\n memo.answer = answer\n memo.offset = @position_offset\n".freeze
|
371
|
+
|
372
|
+
if @location
|
373
|
+
erbout << " memo.offset_loc = @position_offset_loc\n".freeze
|
374
|
+
end
|
375
|
+
erbout << " if memo.grow\n grow_lr(rule, offset".freeze
|
376
|
+
|
377
|
+
if @location
|
378
|
+
erbout << ", offset_loc".freeze
|
379
|
+
end
|
380
|
+
erbout << ")\n memo.grow = false\n answer = memo.answer\n @position_offset = memo.offset\n end\n return answer\n elsif memo.fail\n memo.answer = nil\n memo.grow = true\n return nil\n else\n @position_offset = memo.offset\n return memo.answer\n end\n end\n\n def apply_rule(rule, thunks, values, index, offset".freeze
|
381
|
+
if @location
|
382
|
+
erbout << ", offset_loc".freeze
|
383
|
+
end
|
384
|
+
erbout << ", limits: nil)\n if limits\n limits = limits.merge(rule => true)\n answer = public_send(rule, offset".freeze
|
385
|
+
|
386
|
+
if @location
|
387
|
+
erbout << ", offset_loc".freeze
|
388
|
+
end
|
389
|
+
erbout << ", limits: limits)\n memo = @memos[offset, rule]\n if !answer || @position_offset <= memo.offset\n answer = memo.answer\n @position_offset = memo.offset\n else\n memo.answer = answer\n memo.offset = @position_offset\n end\n else\n answer = rule_answer(rule)\n end\n\n if !answer\n return false\n end\n values ||= @global_values\n thunks << ThunkNode.new(answer.thunks, values, index)\n return true\n end\n\n def do_action(thunks, values, index)\n thunks.each do |thunk|\n thunk.do_action(self, values, index)\n end\n end\n\n".freeze
|
390
|
+
|
391
|
+
code(:location).each do |code|
|
392
|
+
erbout << "#{stream.get_code_block(code, 2, @iname)}\n".freeze
|
393
|
+
end
|
394
|
+
erbout << " class LrMemoTable\n def initialize\n @memos = {}\n end\n\n def clear\n @memos.clear\n end\n\n def []=(index, rule_name, memo)\n entry = @memos[index] ||= {}\n entry[rule_name] = memo\n end\n\n def [](index, rule_name)\n @memos.dig(index, rule_name)\n end\n end\n\n class LrMemo\n attr_accessor :grow, :answer, :offset, :fail\n".freeze
|
395
|
+
|
396
|
+
if @location
|
397
|
+
erbout << " attr_accessor :offset_loc\n".freeze
|
398
|
+
end
|
399
|
+
erbout << "\n def initialize(offset".freeze
|
400
|
+
if @location
|
401
|
+
erbout << ", offset_loc".freeze
|
402
|
+
end
|
403
|
+
erbout << ")\n @offset = offset\n".freeze
|
404
|
+
|
405
|
+
if @location
|
406
|
+
erbout << " @offset_loc = offset_loc\n".freeze
|
407
|
+
end
|
408
|
+
erbout << " @fail = true\n @grow = false\n end\n\n def answer=(answer)\n @fail = nil\n @answer = answer\n end\n end\n\n class ThunkChunk\n attr_accessor :thunks, :capts, :pos, :values\n".freeze
|
409
|
+
|
410
|
+
if @location
|
411
|
+
erbout << " attr_accessor :pos_loc\n".freeze
|
412
|
+
end
|
413
|
+
erbout << "\n def initialize\n super\n @thunks = []\n @capts = {}\n @pos = 0\n @values = {}\n end\n\n def resize_captures(len)\n len.times do |i|\n @capts[i] = Capture.new\n end\n end\n end\n\n class ThunkLeaf\n attr_accessor :capt0, :capts, :value_refs, :action\n\n def initialize(action, capt0 = Capture.new, value_refs = {}, capts = {})\n @value_refs = value_refs\n @capts = capts\n @capt0 = capt0\n @action = action\n end\n\n def do_action(ctx, values, index)\n ctx.public_send(action, self, values, index)\n end\n end\n\n class ThunkNode\n attr_accessor :thunks, :values, :index\n\n def initialize(thunks, values, index)\n @thunks = thunks\n @values = values\n @index = index\n values[index] ||= Value.new if values\n end\n\n def do_action(ctx, _values, _index)\n @thunks.each do |thunk|\n thunk.do_action(ctx, @values, @index)\n end\n end\n\n def clear\n @thunks.clear\n end\n end\n\n class Capture\n attr_accessor :range_start, :range_end\n".freeze
|
414
|
+
|
415
|
+
if @location
|
416
|
+
erbout << " attr_accessor :start_loc, :end_loc\n".freeze
|
417
|
+
end
|
418
|
+
erbout << "\n def initialize(range_start = 0, range_end = 0".freeze
|
419
|
+
if @location
|
420
|
+
erbout << ", start_loc = nil, end_loc = nil".freeze
|
421
|
+
end
|
422
|
+
erbout << ")\n @range_start = range_start\n @range_end = range_end\n".freeze
|
423
|
+
|
424
|
+
if @location
|
425
|
+
erbout << " @start_loc = start_loc || Location.new\n @end_loc = end_loc || Location.new\n".freeze
|
426
|
+
end
|
427
|
+
erbout << " end\n\n def capture_string(buffer)\n @capture_string ||= buffer[@range_start, @range_end - @range_start]\n end\n end\n\n class Value\n attr_accessor :value\n end\nend\n".freeze
|
428
|
+
|
429
|
+
if !code(:lsource).empty?
|
430
|
+
erbout << "\n".freeze
|
431
|
+
|
432
|
+
code(:lsource).each do |code|
|
433
|
+
erbout << "#{stream.get_code_block(code, 0, @iname)}".freeze
|
434
|
+
end
|
435
|
+
end
|
436
|
+
erbout
|
437
|
+
end
|
438
|
+
end
|
439
|
+
end
|
440
|
+
end
|