示例#1
0
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;
}
示例#2
0
文件: btorbtor.c 项目: hellok/kint
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;
}
示例#3
0
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;
}