struct predicate * get_new_pred_chk_op (const struct parser_table *entry, const char *arg) { struct predicate *new_pred; static const struct parser_table *entry_and = NULL; /* Locate the entry in the parser table for the "and" operator */ if (NULL == entry_and) entry_and = find_parser ("and"); /* Check that it's actually there. If not, that is a bug.*/ assert (entry_and != NULL); if (last_pred) switch (last_pred->p_type) { case NO_TYPE: error (EXIT_FAILURE, 0, _("oops -- invalid default insertion of and!")); break; case PRIMARY_TYPE: case CLOSE_PAREN: /* We need to interpose the and operator. */ new_pred = get_new_pred_noarg (entry_and); new_pred->pred_func = pred_and; new_pred->p_name = "-a"; new_pred->p_type = BI_OP; new_pred->p_prec = AND_PREC; new_pred->need_stat = false; new_pred->need_type = false; new_pred->need_inum = false; new_pred->arg_text = NULL; new_pred->args.str = NULL; new_pred->side_effects = false; new_pred->no_default_print = false; break; default: break; } new_pred = get_new_pred (entry); new_pred->arg_text = arg; new_pred->parser_entry = entry; return new_pred; }
static const char * btor_parse_btor_parser (BtorBTORParser * parser, BtorCharStack * prefix, FILE * file, const char *name, BtorParseResult * res) { BtorOpParser op_parser; int ch, len; BtorNode *e; assert (name); assert (file); if (parser->verbosity > 0) btor_msg_btor ("parsing %s", name); parser->nprefix = 0; parser->prefix = prefix; parser->file = file; parser->name = name; parser->lineno = 1; parser->saved = 0; BTOR_CLR (res); NEXT: assert (!parser->error); ch = btor_nextch_btor (parser); if (isspace (ch)) /* also skip empty lines */ goto NEXT; if (ch == EOF) { DONE: if (res) { remove_regs_from_vars (parser); if (parser->found_arrays) res->logic = BTOR_LOGIC_QF_AUFBV; else res->logic = BTOR_LOGIC_QF_BV; res->status = BTOR_PARSE_SAT_STATUS_UNKNOWN; res->ninputs = BTOR_COUNT_STACK (parser->inputs); res->inputs = parser->inputs.start; res->noutputs = BTOR_COUNT_STACK (parser->outputs); res->outputs = parser->outputs.start; res->nregs = BTOR_COUNT_STACK (parser->regs); res->regs = parser->regs.start; res->nexts = parser->nexts.start; if (parser->verbosity > 0) { btor_msg_btor ("parsed %d inputs", res->ninputs); btor_msg_btor ("parsed %d registers", res->nregs); btor_msg_btor ("parsed %d outputs", res->noutputs); } } return 0; } if (ch == ';') /* skip comments */ { COMMENTS: while ((ch = btor_nextch_btor (parser)) != '\n') if (ch == EOF) goto DONE; goto NEXT; } if (!isdigit (ch)) return btor_perr_btor (parser, "expected ';' or digit"); btor_savech_btor (parser, ch); if (parse_positive_int (parser, &parser->idx)) return parser->error; while (BTOR_COUNT_STACK (parser->exps) <= parser->idx) { Info info; memset (&info, 0, sizeof info); BTOR_PUSH_STACK (parser->mem, parser->info, info); BTOR_PUSH_STACK (parser->mem, parser->exps, 0); } if (parser->exps.start[parser->idx]) return btor_perr_btor (parser, "'%d' defined twice", parser->idx); if (parse_space (parser)) return parser->error; assert (BTOR_EMPTY_STACK (parser->op)); while (!isspace (ch = btor_nextch_btor (parser)) && ch != EOF) BTOR_PUSH_STACK (parser->mem, parser->op, ch); BTOR_PUSH_STACK (parser->mem, parser->op, 0); BTOR_RESET_STACK (parser->op); btor_savech_btor (parser, ch); if (parse_space (parser)) return parser->error; if (parse_positive_int (parser, &len)) return parser->error; if (!(op_parser = find_parser (parser, parser->op.start))) return btor_perr_btor (parser, "invalid operator '%s'", parser->op.start); if (!(e = op_parser (parser, len))) { assert (parser->error); return parser->error; } assert (btor_get_exp_len (parser->btor, e) == len); parser->exps.start[parser->idx] = e; SKIP: ch = btor_nextch_btor (parser); if (ch == ' ' || ch == '\t') goto SKIP; if (ch == ';') goto COMMENTS; /* ... and force new line */ if (ch != '\n') return btor_perr_btor (parser, "expected new line"); goto NEXT; }
struct predicate* build_expression_tree (int argc, char *argv[], int end_of_leading_options) { const struct parser_table *parse_entry; /* Pointer to the parsing table entry for this expression. */ char *predicate_name; /* Name of predicate being parsed. */ struct predicate *cur_pred; const struct parser_table *entry_close, *entry_print, *entry_open; int i, oldi; predicates = NULL; /* Find where in ARGV the predicates begin by skipping the list of * start points. As a side effect, also figure out which is the * first and last start point. */ start_points = argv + end_of_leading_options; for (i = end_of_leading_options; i < argc && !looks_like_expression(argv[i], true); i++) { ++num_start_points; } /* Enclose the expression in `( ... )' so a default -print will apply to the whole expression. */ entry_open = find_parser ("("); entry_close = find_parser (")"); entry_print = find_parser ("print"); assert (entry_open != NULL); assert (entry_close != NULL); assert (entry_print != NULL); parse_openparen (entry_open, argv, &argc); last_pred->p_name = "("; predicates->artificial = true; parse_begin_user_args (argv, argc, last_pred, predicates); pred_sanity_check (last_pred); /* Build the input order list. */ while (i < argc ) { state.already_issued_stat_error_msg = false; if (!looks_like_expression (argv[i], false)) { error (0, 0, _("paths must precede expression: %s"), argv[i]); usage (stderr, 1, NULL); } predicate_name = argv[i]; parse_entry = find_parser (predicate_name); if (parse_entry == NULL) { /* Command line option not recognized */ error (EXIT_FAILURE, 0, _("unknown predicate `%s'"), predicate_name); } /* We have recognised a test of the form -foo. Eat that, * unless it is a predicate like -newerXY. */ if (parse_entry->type != ARG_SPECIAL_PARSE) { i++; } oldi = i; if (!(*(parse_entry->parser_func)) (parse_entry, argv, &i)) { if (argv[i]) { if ( (ARG_SPECIAL_PARSE == parse_entry->type) && (i == oldi) ) { /* The special parse function spat out the * predicate. It must be invalid, or not tasty. */ error (EXIT_FAILURE, 0, _("invalid predicate `%s'"), predicate_name); } else { error (EXIT_FAILURE, 0, _("invalid argument `%s' to `%s'"), argv[i], predicate_name); } } else { /* Command line option requires an argument */ error (EXIT_FAILURE, 0, _("missing argument to `%s'"), predicate_name); } } else { last_pred->p_name = predicate_name; /* If the parser consumed an argument, save it. */ if (i != oldi) last_pred->arg_text = argv[oldi]; else last_pred->arg_text = NULL; } pred_sanity_check(last_pred); pred_sanity_check(predicates); /* XXX: expensive */ } parse_end_user_args (argv, argc, last_pred, predicates); if (predicates->pred_next == NULL) { /* No predicates that do something other than set a global variable were given; remove the unneeded initial `(' and add `-print'. */ cur_pred = predicates; predicates = last_pred = predicates->pred_next; free (cur_pred); parse_print (entry_print, argv, &argc); last_pred->p_name = "-print"; pred_sanity_check(last_pred); pred_sanity_check(predicates); /* XXX: expensive */ } else if (!default_prints (predicates->pred_next)) { /* One or more predicates that produce output were given; remove the unneeded initial `('. */ cur_pred = predicates; predicates = predicates->pred_next; pred_sanity_check (predicates); /* XXX: expensive */ free (cur_pred); } else { /* `( user-supplied-expression ) -print'. */ parse_closeparen (entry_close, argv, &argc); last_pred->p_name = ")"; last_pred->artificial = true; pred_sanity_check (last_pred); parse_print (entry_print, argv, &argc); last_pred->p_name = "-print"; last_pred->artificial = true; pred_sanity_check (last_pred); pred_sanity_check (predicates); /* XXX: expensive */ } if (options.debug_options & (DebugExpressionTree|DebugTreeOpt)) { fprintf (stderr, "Predicate List:\n"); print_list (stderr, predicates); } /* do a sanity check */ check_option_combinations (predicates); pred_sanity_check (predicates); /* Done parsing the predicates. Build the evaluation tree. */ cur_pred = predicates; eval_tree = get_expr (&cur_pred, NO_PREC, NULL); calculate_derived_rates (eval_tree); /* Check if we have any left-over predicates (this fixes * Debian bug #185202). */ if (cur_pred != NULL) { /* cur_pred->p_name is often NULL here */ if (pred_is (cur_pred, pred_closeparen)) { /* e.g. "find \( -true \) \)" */ error (EXIT_FAILURE, 0, _("you have too many ')'")); } else { if (cur_pred->p_name) error (EXIT_FAILURE, 0, _("unexpected extra predicate '%s'"), cur_pred->p_name); else error (EXIT_FAILURE, 0, _("unexpected extra predicate")); } } if (options.debug_options & (DebugExpressionTree|DebugTreeOpt)) { fprintf (stderr, "Eval Tree:\n"); print_tree (stderr, eval_tree, 0); } estimate_costs (eval_tree); /* Rearrange the eval tree in optimal-predicate order. */ opt_expr (&eval_tree); /* Check that the tree is in normalised order (opt_expr does this) */ check_normalization (eval_tree, true); do_arm_swaps (eval_tree); /* Check that the tree is still in normalised order */ check_normalization (eval_tree, true); if (options.debug_options & (DebugExpressionTree|DebugTreeOpt)) { fprintf (stderr, "Optimized Eval Tree:\n"); print_tree (stderr, eval_tree, 0); fprintf (stderr, "Optimized command line:\n"); print_optlist (stderr, eval_tree); fprintf (stderr, "\n"); } return eval_tree; }