17 internal->error_message.init ( \
18 "%s:%" PRIu64 ": parse error: ", file->name (), \
19 (uint64_t) file->lineno ()); \
20 return internal->error_message.append (__VA_ARGS__); \
27inline int Parser::parse_char () {
return file->get (); }
31inline const char *Parser::parse_string (
const char *str,
char prev) {
32 for (
const char *
p = str; *
p;
p++)
33 if (parse_char () == *
p)
36 PER (
"expected space after '%c'", prev);
38 PER (
"expected '%c' after '%c'", *
p, prev);
42inline const char *Parser::parse_positive_int (
int &ch,
int &res,
46 while (isdigit (ch = parse_char ())) {
48 if (INT_MAX / 10 < res || INT_MAX - digit < 10 * res)
49 PER (
"too large '%s' in header",
name);
50 res = 10 * res + digit;
55static const char *cube_token =
"unexpected 'a' in CNF";
57inline const char *Parser::parse_lit (
int &ch,
int &
lit,
int &vars,
63 if (!isdigit (ch = parse_char ()))
64 PER (
"expected digit after '-'");
66 }
else if (!isdigit (ch))
67 PER (
"expected digit or '-'");
71 while (isdigit (ch = parse_char ())) {
73 if (INT_MAX / 10 <
lit || INT_MAX - digit < 10 *
lit)
74 PER (
"literal too large");
79 if (ch !=
'c' && ch !=
' ' && ch !=
'\t' && ch !=
'\n' && ch != EOF)
80 PER (
"expected white space after '%d'",
sign *
lit);
83 PER (
"literal %d exceeds maximum variable %d",
sign *
lit, vars);
95const char *Parser::parse_dimacs_non_profiled (
int &vars,
int strict) {
98 double start = internal->time ();
101 bool found_inccnf_header =
false;
109 if (strict != STRICT)
110 if (ch ==
' ' || ch ==
'\n' || ch ==
'\t' || ch ==
'\r')
115 while ((ch = parse_char ()) !=
'\n')
117 PER (
"unexpected end-of-file in header comment");
121 for (o = buf.c_str (); *o && *o !=
'-'; o++)
125 PHASE (
"parse-dimacs",
"found option '%s'", o);
127 solver->set_long_option (o);
131 PER (
"expected 'c' or 'p'");
134 if (strict == STRICT) {
136 PER (
"expected space after 'p'");
138 }
else if (ch !=
' ' && ch !=
'\t')
139 PER (
"expected white space after 'p'");
143 while (ch ==
' ' || ch ==
'\t');
151 if (strict == STRICT) {
152 const char *err = parse_string (
"nf ",
'c');
157 PER (
"expected digit after 'p cnf '");
158 err = parse_positive_int (ch, vars,
"<max-var>");
162 PER (
"expected ' ' after 'p cnf %d'", vars);
163 if (!isdigit (ch = parse_char ()))
164 PER (
"expected digit after 'p cnf %d '", vars);
165 err = parse_positive_int (ch, clauses,
"<num-clauses>");
169 PER (
"expected new-line after 'p cnf %d %d'", vars, clauses);
171 if (parse_char () !=
'n')
172 PER (
"expected 'n' after 'p c'");
173 if (parse_char () !=
'f')
174 PER (
"expected 'f' after 'p cn'");
177 PER (
"expected space after 'p cnf'");
180 while (isspace (ch));
182 PER (
"expected digit after 'p cnf '");
183 const char *err = parse_positive_int (ch, vars,
"<max-var>");
187 PER (
"expected space after 'p cnf %d'", vars);
190 while (isspace (ch));
192 PER (
"expected digit after 'p cnf %d '", vars);
193 err = parse_positive_int (ch, clauses,
"<num-clauses>");
197 if (ch !=
'\r' && !isspace (ch))
198 PER (
"expected new-line after 'p cnf %d %d'", vars, clauses);
206 if (strict != FORCED)
207 solver->reserve (vars);
208 internal->reserve_ids (clauses);
209 }
else if (!parse_inccnf_too)
210 PER (
"expected 'c' after 'p '");
211 else if (ch ==
'i') {
212 found_inccnf_header =
true;
213 const char *err = parse_string (
"nccnf",
'i');
217 if (strict == STRICT) {
219 PER (
"expected new-line after 'p inccnf'");
222 if (ch !=
'\r' && !isspace (ch))
223 PER (
"expected new-line after 'p inccnf'");
233 PER (
"expected 'c' or 'i' after 'p '");
235 if (parse_inccnf_too)
236 *parse_inccnf_too =
false;
240 int lit = 0, parsed = 0;
241 while ((ch = parse_char ()) != EOF) {
242 if (ch ==
' ' || ch ==
'\n' || ch ==
'\t' || ch ==
'\r')
245 while ((ch = parse_char ()) !=
'\n' && ch != EOF)
251 if (ch ==
'a' && found_inccnf_header)
253 const char *err = parse_lit (ch,
lit, vars, strict);
257 while ((ch = parse_char ()) !=
'\n')
259 PER (
"unexpected end-of-file in comment");
262 if (!found_inccnf_header && !
lit && parsed++ >= clauses &&
264 PER (
"too many clauses");
268 PER (
"last clause without terminating '0'");
270 if (!found_inccnf_header && parsed < clauses && strict != FORCED)
271 PER (
"clause missing");
274 double end = internal->time ();
275 MSG (
"parsed %d clauses in %.2f seconds %s time", parsed, end - start,
276 internal->opts.realtime ?
"real" :
"process");
281 size_t num_cubes = 0;
286 if (!*parse_inccnf_too)
287 *parse_inccnf_too =
true;
290 if (ch ==
' ' || ch ==
'\n' || ch ==
'\t' || ch ==
'\r')
293 while ((ch = parse_char ()) !=
'\n' && ch != EOF)
299 const char *err = parse_lit (ch,
lit, vars, strict);
300 if (err == cube_token)
301 PER (
"two 'a' in a row");
305 while ((ch = parse_char ()) !=
'\n')
307 PER (
"unexpected end-of-file in comment");
310 cubes->push_back (
lit);
317 if (ch ==
' ' || ch ==
'\n' || ch ==
'\t' || ch ==
'\r')
320 while ((ch = parse_char ()) !=
'\n' && ch != EOF)
328 PER (
"expected 'a' or end-of-file after zero");
337 PER (
"last cube without terminating '0'");
340 if (found_inccnf_header) {
341 double end = internal->time ();
342 MSG (
"parsed %zd cubes in %.2f seconds %s time", num_cubes, end - start,
343 internal->opts.realtime ?
"real" :
"process");
354const char *Parser::parse_solution_non_profiled () {
355 external->solution =
new signed char[external->max_var + 1u];
356 external->solution_size = external->max_var;
357 clear_n (external->solution, external->max_var + 1u);
362 PER (
"missing 's' line");
363 else if (ch ==
'c') {
364 while ((ch = parse_char ()) !=
'\n')
366 PER (
"unexpected end-of-file in comment");
367 }
else if (ch ==
's')
370 PER (
"expected 'c' or 's'");
372 const char *err = parse_string (
" SATISFIABLE",
's');
375 if ((ch = parse_char ()) ==
'\r')
378 PER (
"expected new-line after 's SATISFIABLE'");
385 PER (
"expected 'v' at start-of-line");
386 if ((ch = parse_char ()) !=
' ')
387 PER (
"expected ' ' after 'v'");
391 if (ch ==
' ' || ch ==
'\t') {
395 err = parse_lit (ch,
lit, external->max_var,
false);
399 PER (
"unexpected comment");
402 if (external->solution[abs (
lit)])
403 PER (
"variable %d occurs twice", abs (
lit));
411 }
while (ch !=
'\n');
415 MSG (
"parsed %d values %.2f%%", count,
416 percent (count, external->max_var));
426 CADICAL_assert (strict == FORCED || strict == RELAXED || strict == STRICT);
428 const char *err = parse_dimacs_non_profiled (vars, strict);
435 const char *err = parse_solution_non_profiled ();
#define ABC_NAMESPACE_IMPL_START
#define ABC_NAMESPACE_IMPL_END
#define CADICAL_assert(ignore)
const char * parse_dimacs(int &vars, int strict)
const char * parse_solution()
const char * normal_code()
const char * green_code()
void clear_n(T *base, size_t n)
double percent(double a, double b)