at_coder_friends 0.6.2 → 0.6.3
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/CHANGELOG.md +20 -0
- data/Gemfile.lock +2 -2
- data/docs/CONFIGURATION.md +2 -4
- data/lib/at_coder_friends/generator/base.rb +41 -0
- data/lib/at_coder_friends/generator/cxx_builtin.rb +196 -143
- data/lib/at_coder_friends/generator/main.rb +7 -2
- data/lib/at_coder_friends/generator/ruby_builtin.rb +97 -51
- data/lib/at_coder_friends/parser/input_format.rb +387 -188
- data/lib/at_coder_friends/parser/input_type.rb +91 -0
- data/lib/at_coder_friends/parser/main.rb +1 -0
- data/lib/at_coder_friends/problem.rb +81 -6
- data/lib/at_coder_friends/version.rb +1 -1
- data/lib/at_coder_friends.rb +2 -0
- data/tasks/regression/check_const.rake +15 -14
- data/tasks/regression/check_diff.rake +2 -2
- data/tasks/regression/check_fmt.rake +18 -15
- data/tasks/regression/check_parse.rake +3 -4
- data/tasks/regression/list_handler.rb +46 -0
- data/tasks/regression/regression.rb +7 -41
- data/tasks/regression/report_handler.rb +20 -0
- data/tasks/regression/section_list.rake +1 -1
- data/templates/{cxx_builtin_interactive.cxx → cxx_builtin.cxx.erb} +33 -2
- data/templates/{ruby_builtin_interactive.rb → ruby_builtin.rb.erb} +17 -2
- metadata +8 -6
- data/templates/cxx_builtin_default.cxx +0 -26
- data/templates/ruby_builtin_default.rb +0 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9a7432316e843545fb879309e242139dc2c0405c
|
4
|
+
data.tar.gz: 9e22a2dcde9e98a171ed393365de8fd308957996
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 70e350831761899ee4178e65f8563cbd328a0b8e70971e4620015d623484c0297fa60a6a5ce447bb349d3b2fa06799b336fb270913a34b8efb857dc97e9dfaa3
|
7
|
+
data.tar.gz: ff84c2c7fb80dda6105561d82d94c697c7e5133e91219c9f6530f8e7db083192a5ac8a5148a204fd5740c3cf470d53fd56ac5026b908738f12ccb671d824dd39
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,26 @@
|
|
2
2
|
|
3
3
|
## master (unreleased)
|
4
4
|
|
5
|
+
## 0.6.3 (2020-01-05)
|
6
|
+
### Added
|
7
|
+
- 'vertical array + matrix' input format support.
|
8
|
+
- 'matrix + vertical array' input format support.
|
9
|
+
- 'vertically expanded matrices' input format support.
|
10
|
+
- 'horizontally expanded matrices' input format support.
|
11
|
+
- decimal type support.
|
12
|
+
- input data with delimiter(- : /) support.
|
13
|
+
- input data of mixed type support.
|
14
|
+
- input of N-1 lines support.
|
15
|
+
|
16
|
+
### Changed
|
17
|
+
- Change template file format to ERB.
|
18
|
+
- Template file integration
|
19
|
+
|
20
|
+
### Deleted
|
21
|
+
- Template file for interactive problems.
|
22
|
+
- '### OUTPUT ###' embedding pattern.
|
23
|
+
- '### URL ###' embedding pattern.
|
24
|
+
|
5
25
|
## 0.6.2 (2019-11-18)
|
6
26
|
### Added
|
7
27
|
- add ```check-and-go``` command.
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
at_coder_friends (0.6.
|
4
|
+
at_coder_friends (0.6.3)
|
5
5
|
colorize (~> 0.8.1)
|
6
6
|
launchy (~> 2.4.3)
|
7
7
|
mechanize (~> 2.0)
|
@@ -41,7 +41,7 @@ GEM
|
|
41
41
|
net-http-digest_auth (1.4.1)
|
42
42
|
net-http-persistent (3.1.0)
|
43
43
|
connection_pool (~> 2.2)
|
44
|
-
nokogiri (1.10.
|
44
|
+
nokogiri (1.10.5)
|
45
45
|
mini_portile2 (~> 2.4.0)
|
46
46
|
ntlm-http (0.1.1)
|
47
47
|
public_suffix (4.0.1)
|
data/docs/CONFIGURATION.md
CHANGED
@@ -198,14 +198,12 @@ ext_settings:
|
|
198
198
|
### Settings for RubyBuiltin generator
|
199
199
|
| Setting | Description | Default |
|
200
200
|
|---------|-------------|---------|
|
201
|
-
|default_template|Source template file path|[/templates/
|
202
|
-
|interactive_template|Source template file path for interactive problems|[/templates/ruby_builtin_interactive.rb](/templates/ruby_builtin_interactive.rb)|
|
201
|
+
|default_template|Source template file path|[/templates/ruby_builtin.rb.erb](/templates/ruby_builtin.rb.erb)|
|
203
202
|
|
204
203
|
### Settings for CxxBuiltin generator
|
205
204
|
| Setting | Description | Default |
|
206
205
|
|---------|-------------|---------|
|
207
|
-
|default_template|Source template file path|[/templates/
|
208
|
-
|interactive_template|Source template file path for interactive problems|[/templates/cxx_builtin_interactive.cxx](/templates/cxx_builtin_interactive.cxx)|
|
206
|
+
|default_template|Source template file path|[/templates/cxx_builtin.cxx.erb](/templates/cxx_builtin.cxx.erb)|
|
209
207
|
|
210
208
|
### Language ID list (2019/09/16)
|
211
209
|
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'erb'
|
4
|
+
|
5
|
+
module AtCoderFriends
|
6
|
+
module Generator
|
7
|
+
Attributes = Struct.new(:file_ext, :default_template)
|
8
|
+
|
9
|
+
# common behavior of generators
|
10
|
+
class Base
|
11
|
+
attr_reader :cfg, :pbm
|
12
|
+
|
13
|
+
def initialize(cfg = nil)
|
14
|
+
@cfg = cfg || {}
|
15
|
+
end
|
16
|
+
|
17
|
+
def process(pbm)
|
18
|
+
pbm.add_src(attrs.file_ext, generate(pbm))
|
19
|
+
end
|
20
|
+
|
21
|
+
def generate(pbm)
|
22
|
+
@pbm = pbm
|
23
|
+
src = File.read(select_template)
|
24
|
+
src = ERB.new(src).result(binding)
|
25
|
+
render(src)
|
26
|
+
end
|
27
|
+
|
28
|
+
def select_template
|
29
|
+
cfg['default_template'] || attrs.default_template
|
30
|
+
end
|
31
|
+
|
32
|
+
def embed_lines(src, pat, lines)
|
33
|
+
re = Regexp.escape(pat)
|
34
|
+
src.gsub(
|
35
|
+
/^(.*)#{re}(.*)$\n/,
|
36
|
+
lines.compact.map { |s| "\\1#{s}\\2\n" }.join
|
37
|
+
)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -2,96 +2,8 @@
|
|
2
2
|
|
3
3
|
module AtCoderFriends
|
4
4
|
module Generator
|
5
|
-
|
6
|
-
|
7
|
-
TMPL_DIR = File.join(ACF_HOME, 'templates')
|
8
|
-
DEFAULT_TMPL = File.join(TMPL_DIR, 'cxx_builtin_default.cxx')
|
9
|
-
INTERACTIVE_TMPL = File.join(TMPL_DIR, 'cxx_builtin_interactive.cxx')
|
10
|
-
SCANF_FMTS = [
|
11
|
-
'scanf("%<fmt>s", %<addr>s);',
|
12
|
-
'REP(i, %<sz1>s) scanf("%<fmt>s", %<addr>s);',
|
13
|
-
'REP(i, %<sz1>s) REP(j, %<sz2>s) scanf("%<fmt>s", %<addr>s);'
|
14
|
-
].freeze
|
15
|
-
FMT_FMTS = { number: '%d', string: '%s', char: '%s' }.freeze
|
16
|
-
ADDR_FMTS = {
|
17
|
-
single: {
|
18
|
-
number: '&%<v>s',
|
19
|
-
string: '%<v>s'
|
20
|
-
},
|
21
|
-
harray: {
|
22
|
-
number: '%<v>s + i',
|
23
|
-
string: '%<v>s[i]',
|
24
|
-
char: '%<v>s'
|
25
|
-
},
|
26
|
-
varray: {
|
27
|
-
number: '%<v>s + i',
|
28
|
-
string: '%<v>s[i]'
|
29
|
-
},
|
30
|
-
matrix: {
|
31
|
-
number: '&%<v>s[i][j]',
|
32
|
-
string: '%<v>s[i][j]',
|
33
|
-
char: '%<v>s[i]'
|
34
|
-
}
|
35
|
-
}.freeze
|
36
|
-
DEFAULT_OUTPUT = <<~TEXT
|
37
|
-
int ans = 0;
|
38
|
-
printf("%d\\n", ans);
|
39
|
-
TEXT
|
40
|
-
BINARY_OUTPUT_FMT = <<~TEXT
|
41
|
-
bool cond = false;
|
42
|
-
puts(cond ? "%s" : "%s");
|
43
|
-
TEXT
|
44
|
-
end
|
45
|
-
|
46
|
-
# generates C++ source from problem description
|
47
|
-
class CxxBuiltin
|
48
|
-
include CxxBuiltinConstants
|
49
|
-
|
50
|
-
attr_reader :cfg, :pbm
|
51
|
-
|
52
|
-
def initialize(cfg = nil)
|
53
|
-
@cfg = cfg || {}
|
54
|
-
end
|
55
|
-
|
56
|
-
def process(pbm)
|
57
|
-
src = generate(pbm)
|
58
|
-
pbm.add_src(:cxx, src)
|
59
|
-
end
|
60
|
-
|
61
|
-
def generate(pbm)
|
62
|
-
@pbm = pbm
|
63
|
-
src = File.read(select_template)
|
64
|
-
src = embed_lines(src, '/*** URL ***/', [pbm.url])
|
65
|
-
src = embed_lines(src, '/*** CONSTS ***/', gen_consts)
|
66
|
-
src = embed_lines(src, '/*** DCLS ***/', gen_decls)
|
67
|
-
src = embed_lines(src, '/*** INPUTS ***/', gen_inputs)
|
68
|
-
embed_lines(src, '/*** OUTPUT ***/', gen_output.split("\n"))
|
69
|
-
end
|
70
|
-
|
71
|
-
def embed_lines(src, pat, lines)
|
72
|
-
re = Regexp.escape(pat)
|
73
|
-
src.gsub(
|
74
|
-
/^(.*)#{re}(.*)$/,
|
75
|
-
lines.map { |s| '\1' + s + '\2' }.join("\n")
|
76
|
-
)
|
77
|
-
end
|
78
|
-
|
79
|
-
def select_template(interactive = pbm.options.interactive)
|
80
|
-
interactive ? interactive_template : default_template
|
81
|
-
end
|
82
|
-
|
83
|
-
def default_template
|
84
|
-
cfg['default_template'] || DEFAULT_TMPL
|
85
|
-
end
|
86
|
-
|
87
|
-
def interactive_template
|
88
|
-
cfg['interactive_template'] || INTERACTIVE_TMPL
|
89
|
-
end
|
90
|
-
|
91
|
-
def gen_consts(constants = pbm.constants)
|
92
|
-
constants.map { |c| gen_const(c) }
|
93
|
-
end
|
94
|
-
|
5
|
+
# generates C++ constants
|
6
|
+
module CxxBuiltinConstGen
|
95
7
|
def gen_const(c)
|
96
8
|
v = cnv_const_value(c.value)
|
97
9
|
if c.type == :max
|
@@ -107,98 +19,239 @@ module AtCoderFriends
|
|
107
19
|
.sub(/\b2\^/, '1<<')
|
108
20
|
.gsub(',', "'")
|
109
21
|
end
|
22
|
+
end
|
110
23
|
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
24
|
+
# generates C++ variable declarations
|
25
|
+
module CxxBuiltinDeclGen
|
26
|
+
TYPE_TBL = {
|
27
|
+
number: 'int',
|
28
|
+
decimal: 'double',
|
29
|
+
string: 'char',
|
30
|
+
char: 'char'
|
31
|
+
}.tap { |h| h.default = 'int' }
|
115
32
|
def gen_decl(inpdef)
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
33
|
+
if inpdef.components
|
34
|
+
inpdef.components.map { |cmp| gen_decl(cmp) }
|
35
|
+
else
|
36
|
+
case inpdef.container
|
37
|
+
when :single
|
38
|
+
gen_single_decl(inpdef)
|
39
|
+
when :harray
|
40
|
+
gen_harray_decl(inpdef)
|
41
|
+
when :varray
|
42
|
+
gen_varray_decl(inpdef)
|
43
|
+
when :matrix, :vmatrix, :hmatrix
|
44
|
+
gen_matrix_decl(inpdef)
|
45
|
+
end
|
125
46
|
end
|
126
47
|
end
|
127
48
|
|
128
49
|
def gen_single_decl(inpdef)
|
129
|
-
names = inpdef.
|
130
|
-
|
131
|
-
|
50
|
+
names, cols = inpdef.vars.transpose
|
51
|
+
if cols.uniq.size == 1 && cols[0] != :string
|
52
|
+
type = TYPE_TBL[cols[0]]
|
132
53
|
dcl = names.join(', ')
|
133
|
-
"
|
134
|
-
|
135
|
-
|
54
|
+
"#{type} #{dcl};"
|
55
|
+
else
|
56
|
+
inpdef.vars.map do |v, item|
|
57
|
+
type = TYPE_TBL[item]
|
58
|
+
dcl = v
|
59
|
+
dcl += "[#{v.upcase}_MAX + 1]" if item == :string
|
60
|
+
"#{type} #{dcl};"
|
61
|
+
end
|
136
62
|
end
|
137
63
|
end
|
138
64
|
|
139
65
|
def gen_harray_decl(inpdef)
|
66
|
+
type = TYPE_TBL[inpdef.item]
|
140
67
|
v = inpdef.names[0]
|
141
68
|
sz = gen_arr_size(inpdef.size)[0]
|
142
69
|
case inpdef.item
|
143
|
-
when :number
|
144
|
-
"
|
70
|
+
when :number, :decimal
|
71
|
+
"#{type} #{v}[#{sz}];"
|
145
72
|
when :string
|
146
|
-
"
|
73
|
+
"#{type} #{v}[#{sz}][#{v.upcase}_MAX + 1];"
|
147
74
|
when :char
|
148
|
-
"
|
75
|
+
"#{type} #{v}[#{sz} + 1];"
|
149
76
|
end
|
150
77
|
end
|
151
78
|
|
152
79
|
def gen_varray_decl(inpdef)
|
153
|
-
names = inpdef.names
|
154
80
|
sz = gen_arr_size(inpdef.size)[0]
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
81
|
+
inpdef.vars.map do |v, item|
|
82
|
+
type = TYPE_TBL[item]
|
83
|
+
dcl = "#{v}[#{sz}]"
|
84
|
+
dcl += "[#{v.upcase}_MAX + 1]" if item == :string
|
85
|
+
"#{type} #{dcl};"
|
160
86
|
end
|
161
87
|
end
|
162
88
|
|
163
89
|
def gen_matrix_decl(inpdef)
|
164
|
-
v = inpdef.names[0]
|
165
90
|
sz1, sz2 = gen_arr_size(inpdef.size)
|
166
|
-
|
167
|
-
|
168
|
-
"
|
169
|
-
|
170
|
-
"
|
171
|
-
|
172
|
-
"char #{v}[#{sz1}][#{sz2} + 1];"
|
91
|
+
inpdef.vars.map do |v, item|
|
92
|
+
type = TYPE_TBL[item]
|
93
|
+
dcl = "#{v}[#{sz1}]"
|
94
|
+
dcl += item == :char ? "[#{sz2} + 1]" : "[#{sz2}]"
|
95
|
+
dcl += "[#{v.upcase}_MAX + 1]" if item == :string
|
96
|
+
"#{type} #{dcl};"
|
173
97
|
end
|
174
98
|
end
|
175
99
|
|
176
100
|
def gen_arr_size(szs)
|
177
101
|
szs.map { |sz| sz.gsub(/([a-z][a-z0-9_]*)/i, '\1_MAX').upcase }
|
178
102
|
end
|
103
|
+
end
|
179
104
|
|
180
|
-
|
181
|
-
|
182
|
-
|
105
|
+
# generates C++ input source
|
106
|
+
module CxxBuiltinInputGen
|
107
|
+
SCANF_FMTS = [
|
108
|
+
'scanf("%<fmt>s", %<addr>s);',
|
109
|
+
'REP(i, %<sz1>s) scanf("%<fmt>s", %<addr>s);',
|
110
|
+
'REP(i, %<sz1>s) REP(j, %<sz2>s) scanf("%<fmt>s", %<addr>s);'
|
111
|
+
].freeze
|
112
|
+
SCANF_FMTS_CMB = {
|
113
|
+
varray_matrix:
|
114
|
+
[
|
115
|
+
<<~TEXT,
|
116
|
+
REP(i, %<sz1>s) {
|
117
|
+
scanf("%<fmt1>s", %<addr1>s);
|
118
|
+
scanf("%<fmt2>s", %<addr2>s);
|
119
|
+
}
|
120
|
+
TEXT
|
121
|
+
<<~TEXT
|
122
|
+
REP(i, %<sz1>s) {
|
123
|
+
scanf("%<fmt1>s", %<addr1>s);
|
124
|
+
REP(j, %<sz2>s[i]) scanf("%<fmt2>s", %<addr2>s);
|
125
|
+
}
|
126
|
+
TEXT
|
127
|
+
],
|
128
|
+
matrix_varray:
|
129
|
+
[
|
130
|
+
<<~TEXT,
|
131
|
+
REP(i, %<sz1>s) {
|
132
|
+
scanf("%<fmt1>s", %<addr1>s);
|
133
|
+
scanf("%<fmt2>s", %<addr2>s);
|
134
|
+
}
|
135
|
+
TEXT
|
136
|
+
<<~TEXT
|
137
|
+
REP(i, %<sz1>s) {
|
138
|
+
REP(j, %<sz2>s) scanf("%<fmt1>s", %<addr1>s);
|
139
|
+
scanf("%<fmt2>s", %<addr2>s);
|
140
|
+
}
|
141
|
+
TEXT
|
142
|
+
]
|
143
|
+
}.tap { |h| h.default = h[:varray_matrix] }
|
144
|
+
FMT_FMTS = {
|
145
|
+
number: '%d',
|
146
|
+
decimal: '%lf',
|
147
|
+
string: '%s',
|
148
|
+
char: '%s'
|
149
|
+
}.tap { |h| h.default = h[:number] }
|
150
|
+
SINGLE_ADDR_FMTS = {
|
151
|
+
number: '&%<v>s',
|
152
|
+
decimal: '&%<v>s',
|
153
|
+
string: '%<v>s'
|
154
|
+
}.tap { |h| h.default = h[:number] }
|
155
|
+
ARRAY_ADDR_FMTS = {
|
156
|
+
number: '%<v>s + i',
|
157
|
+
decimal: '%<v>s + i',
|
158
|
+
string: '%<v>s[i]',
|
159
|
+
char: '%<v>s'
|
160
|
+
}.tap { |h| h.default = h[:number] }
|
161
|
+
MATRIX_ADDR_FMTS = {
|
162
|
+
number: '&%<v>s[i][j]',
|
163
|
+
decimal: '&%<v>s[i][j]',
|
164
|
+
string: '%<v>s[i][j]',
|
165
|
+
char: '%<v>s[i]'
|
166
|
+
}.tap { |h| h.default = h[:number] }
|
167
|
+
ADDR_FMTS = {
|
168
|
+
single: SINGLE_ADDR_FMTS,
|
169
|
+
harray: ARRAY_ADDR_FMTS,
|
170
|
+
varray: ARRAY_ADDR_FMTS,
|
171
|
+
matrix: MATRIX_ADDR_FMTS,
|
172
|
+
vmatrix: MATRIX_ADDR_FMTS,
|
173
|
+
hmatrix: MATRIX_ADDR_FMTS
|
174
|
+
}.tap { |h| h.default = h[:single] }
|
183
175
|
|
184
|
-
# rubocop:disable Metrics/AbcSize
|
185
176
|
def gen_input(inpdef)
|
186
|
-
|
187
|
-
|
177
|
+
if inpdef.components
|
178
|
+
gen_cmb_input(inpdef)
|
179
|
+
else
|
180
|
+
gen_plain_input(inpdef)
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
def gen_plain_input(inpdef)
|
185
|
+
scanf = SCANF_FMTS[inpdef.size.size - (inpdef.item == :char ? 1 : 0)]
|
188
186
|
sz1, sz2 = inpdef.size
|
189
|
-
fmt =
|
190
|
-
addr_fmt = ADDR_FMTS[inpdef.container][inpdef.item]
|
191
|
-
addr = inpdef.names.map { |v| format(addr_fmt, v: v) }.join(', ')
|
187
|
+
fmt, addr = scanf_params(inpdef)
|
192
188
|
format(scanf, sz1: sz1, sz2: sz2, fmt: fmt, addr: addr)
|
193
189
|
end
|
194
|
-
# rubocop:enable Metrics/AbcSize
|
195
190
|
|
196
|
-
def
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
191
|
+
def gen_cmb_input(inpdef)
|
192
|
+
scanf = SCANF_FMTS_CMB.dig(
|
193
|
+
inpdef.container, inpdef.item == :char ? 0 : 1
|
194
|
+
)
|
195
|
+
sz1 = inpdef.size[0]
|
196
|
+
sz2 = inpdef.size[1].split('_')[0]
|
197
|
+
fmt1, addr1, fmt2, addr2 =
|
198
|
+
inpdef.components.map { |cmp| scanf_params(cmp) }.flatten
|
199
|
+
format(
|
200
|
+
scanf,
|
201
|
+
sz1: sz1, sz2: sz2,
|
202
|
+
fmt1: fmt1, addr1: addr1,
|
203
|
+
fmt2: fmt2, addr2: addr2
|
204
|
+
).split("\n")
|
205
|
+
end
|
206
|
+
|
207
|
+
def scanf_params(inpdef)
|
208
|
+
[scanf_fmt(inpdef), scanf_addr(inpdef)]
|
209
|
+
end
|
210
|
+
|
211
|
+
def scanf_fmt(inpdef)
|
212
|
+
inpdef.vars.map { |(_v, item)| FMT_FMTS[item] }.join
|
213
|
+
end
|
214
|
+
|
215
|
+
def scanf_addr(inpdef)
|
216
|
+
inpdef.vars.map do |(v, item)|
|
217
|
+
addr_fmt = ADDR_FMTS.dig(inpdef.container, item)
|
218
|
+
format(addr_fmt, v: v)
|
219
|
+
end.join(', ')
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
# generates C++ source from problem description
|
224
|
+
class CxxBuiltin < Base
|
225
|
+
include CxxBuiltinConstGen
|
226
|
+
include CxxBuiltinDeclGen
|
227
|
+
include CxxBuiltinInputGen
|
228
|
+
|
229
|
+
ACF_HOME = File.realpath(File.join(__dir__, '..', '..', '..'))
|
230
|
+
TMPL_DIR = File.join(ACF_HOME, 'templates')
|
231
|
+
DEFAULT_TMPL = File.join(TMPL_DIR, 'cxx_builtin.cxx.erb')
|
232
|
+
ATTRS = Attributes.new(:cxx, DEFAULT_TMPL)
|
233
|
+
|
234
|
+
def attrs
|
235
|
+
ATTRS
|
236
|
+
end
|
237
|
+
|
238
|
+
def render(src)
|
239
|
+
src = embed_lines(src, '/*** CONSTS ***/', gen_consts)
|
240
|
+
src = embed_lines(src, '/*** DCLS ***/', gen_decls)
|
241
|
+
src = embed_lines(src, '/*** INPUTS ***/', gen_inputs)
|
242
|
+
src
|
243
|
+
end
|
244
|
+
|
245
|
+
def gen_consts(constants = pbm.constants)
|
246
|
+
constants.map { |c| gen_const(c) }
|
247
|
+
end
|
248
|
+
|
249
|
+
def gen_decls(inpdefs = pbm.formats)
|
250
|
+
inpdefs.map { |inpdef| gen_decl(inpdef) }.flatten
|
251
|
+
end
|
252
|
+
|
253
|
+
def gen_inputs(inpdefs = pbm.formats)
|
254
|
+
inpdefs.map { |inpdef| gen_input(inpdef) }.flatten
|
202
255
|
end
|
203
256
|
end
|
204
257
|
end
|
@@ -14,8 +14,13 @@ module AtCoderFriends
|
|
14
14
|
def process(pbm)
|
15
15
|
generators = ctx.config.dig('generators') || []
|
16
16
|
generators.each do |gen_name|
|
17
|
-
|
18
|
-
|
17
|
+
begin
|
18
|
+
gen_obj = load_obj(gen_name)
|
19
|
+
gen_obj.process(pbm)
|
20
|
+
rescue StandardError => e
|
21
|
+
puts "an error occurred in generator:#{gen_name}."
|
22
|
+
p e
|
23
|
+
end
|
19
24
|
end
|
20
25
|
end
|
21
26
|
|