Esempio n. 1
0
int main(int argc, char *argv[])
{
    struct state_machine *sm;
    char *filename;

    int nstates;
    int i;
    int use_goto;

    use_goto = is_goto(argc, argv);

    sm = sm_make();

    sm->tokens = read_tokens();

    if (sm->tokens == NULL)
        panic("Invalid token input");

    read_nstates(sm);
    read_initial_state(sm);
    read_final_states(sm);

    setup_transitions(sm);

    printf("Output filename: ");
    fflush(stdout);

    filename = read_line();

    if (use_goto)
        write_output_goto(sm, filename);
    else
        write_output_func(sm, filename);

    sm_free(sm);

    return 0;
}
char *get_token(char *lexeme , int mode){
	char *token=(char*)calloc(strlen(lexeme)+50,sizeof(char));
	//printf("Getting token\n");
	if(is_long(lexeme)){
		sprintf(token,"%d",LONG);
	}
	else if(is_static(lexeme)){
		sprintf(token,"%d",STATIC);
	}
	else if(is_union(lexeme)){
		sprintf(token,"%d",UNION);
	}
	else if(is_default(lexeme)){
		sprintf(token,"%d",DEFAULT);
	}
	else if(is_break(lexeme)){
		sprintf(token,"%d",BREAK);
	}
	else if(is_case(lexeme)){
		sprintf(token,"%d",CASE);
	}
	else if(is_continue(lexeme)){
		sprintf(token,"%d",CONTINUE);
	}
	else if(is_goto(lexeme)){
		sprintf(token,"%d",GOTO);
	}
	else if(is_struct(lexeme)){
		sprintf(token,"%d",STRUCT);
	}
	else if(is_const(lexeme)){
		sprintf(token,"%d",CONST);
	}
	else if(is_void(lexeme)){
		sprintf(token,"%d",VOID);
	}
	else if(is_switch(lexeme)){
		sprintf(token,"%d",SWITCH);
	}
	else if(is_for(lexeme)){
		sprintf(token,"%d",FOR);
	}
	else if(is_while(lexeme)){
		sprintf(token,"%d",WHILE);
	}
	else if(is_do(lexeme)){
		sprintf(token,"%d",DO);
	}
	else if(is_return(lexeme)){
		sprintf(token,"%d",RETURN);
	}
	else if(is_bool(lexeme)){
		sprintf(token,"%d",BOOL);
	}
	else if(is_char(lexeme)){
		sprintf(token,"%d",CHAR);
	}
	else if(is_signed(lexeme)){
		sprintf(token,"%d",SIGNED);
	}
	else if(is_unsigned(lexeme)){
		sprintf(token,"%d",UNSIGNED);
	}
	else if(is_short(lexeme)){
		sprintf(token,"%d",SHORT);
	}
	else if(is_int(lexeme)){
		sprintf(token,"%d",INT);
	}
	else if(is_float(lexeme)){
		sprintf(token,"%d",FLOAT);
	}
	else if(is_double(lexeme)){
		sprintf(token,"%d",DOUBLE);
	}
	else if(is_l_square(lexeme)){
		sprintf(token,"%d",L_SQUARE);
	}
	else if(is_r_square(lexeme)){
		sprintf(token,"%d",R_SQUARE);
	}
	else if(is_l_paraen(lexeme)){
		sprintf(token,"%d",L_PARAEN);
	}
	else if(is_r_paraen(lexeme)){
		sprintf(token,"%d",R_PARAEN);
	}
	else if(is_l_cbrace(lexeme)){
		sprintf(token,"%d",L_CBRACE);
	}
	else if(is_r_cbrace(lexeme)){
		sprintf(token,"%d",R_CBRACE);
	}
	else if(is_comma(lexeme)){
		sprintf(token,"%d",COMMA);
	}
	else if(is_semicol(lexeme)){
		sprintf(token,"%d",SEMICOL);
	}
	else if(is_eq_eq(lexeme)){
		sprintf(token,"%d",EQ_EQ);
	}
	else if(is_lesser(lexeme)){
		sprintf(token,"%d",LESSER);
	}
	else if(is_less_eq(lexeme)){
		sprintf(token,"%d",LESS_EQ);
	}
	else if(is_div(lexeme)){
		sprintf(token,"%d",DIV);
	}
	else if(is_greater(lexeme)){
		sprintf(token,"%d",GREATER);
	}
	else if(is_great_eq(lexeme)){
		sprintf(token,"%d",GREAT_EQ);
	}
	else if(is_plus_eq(lexeme)){
		sprintf(token,"%d",PLUS_EQ);
	}
	else if(is_minus_eq(lexeme)){
		sprintf(token,"%d",MINUS_EQ);
	}
	else if(is_div_eq(lexeme)){
		sprintf(token,"%d",DIV_EQ);
	}
	else if(is_mult_eq(lexeme)){
		sprintf(token,"%d",MULT_EQ);
	}
	else if(is_minus_minus(lexeme)){
		sprintf(token,"%d",MINUS_MINUS);
	}
	else if(is_plus_plus(lexeme)){
		sprintf(token,"%d",PLUS_PLUS);
	}
	else if(is_percent(lexeme)){
		sprintf(token,"%d",PERCENT);
	}
	else if(is_div(lexeme)){
		sprintf(token,"%d",DIV);
	}
	else if(is_mult(lexeme)){
		sprintf(token,"%d",MULT);
	}
	else if(is_minus(lexeme)){
		sprintf(token,"%d",MINUS);
	}
	else if(is_plus(lexeme)){
		sprintf(token,"%d",PLUS);
	}
	else if(is_int_const(lexeme)){
		printf("int");
		sprintf(token,"%d\t%s",INT_CONST,lexeme);
	}
	else if(is_flo_const(lexeme)){
		printf("float");
		sprintf(token,"%d\t%s",FLO_CONST,lexeme);
	}
	else if(is_comment_start(lexeme)){
		sprintf(token,"$start");
	}
	else if(is_comment_end(lexeme)){
		sprintf(token,"$end");
	}
	else if(is_identifier(lexeme)){
		printf("Identifier");
		if(mode==1) ht_set( symboltable, lexeme, "1");
		sprintf(token,"%d\t%s",IDNTIFIER,lexeme);
	}
	else sprintf(token,"%d",NOTOK);
	return token;
}
Esempio n. 3
0
void MethodTransform::build_cfg() {
  // Find the block boundaries
  std::unordered_map<MethodItemEntry*, std::vector<Block*>> branch_to_targets;
  std::vector<std::pair<DexTryItem*, Block*>> try_ends;
  std::unordered_map<DexTryItem*, std::vector<Block*>> try_catches;
  size_t id = 0;
  bool in_try = false;
  m_blocks.emplace_back(new Block(id++));
  m_blocks.back()->m_begin = m_fmethod->begin();
  // The first block can be a branch target.
  auto begin = m_fmethod->begin();
  if (begin->type == MFLOW_TARGET) {
    branch_to_targets[begin->target->src].push_back(m_blocks.back());
  }
  for (auto it = m_fmethod->begin(); it != m_fmethod->end(); ++it) {
    if (it->type == MFLOW_TRY) {
      if (it->tentry->type == TRY_START) {
        in_try = true;
      } else if (it->tentry->type == TRY_END) {
        in_try = false;
      }
    }
    if (!end_of_block(m_fmethod, it, in_try)) {
      continue;
    }
    // End the current block.
    auto next = std::next(it);
    if (next == m_fmethod->end()) {
      m_blocks.back()->m_end = next;
      continue;
    }
    // Start a new block at the next MethodItem.
    auto next_block = new Block(id++);
    if (next->type == MFLOW_OPCODE) {
      insert_fallthrough(m_fmethod, &*next);
      next = std::next(it);
    }
    m_blocks.back()->m_end = next;
    next_block->m_begin = next;
    m_blocks.emplace_back(next_block);
    // Record branch targets to add edges in the next pass.
    if (next->type == MFLOW_TARGET) {
      branch_to_targets[next->target->src].push_back(next_block);
      continue;
    }
    // Record try/catch blocks to add edges in the next pass.
    if (next->type == MFLOW_TRY) {
      if (next->tentry->type == TRY_END) {
        try_ends.emplace_back(next->tentry->tentry, next_block);
      } else if (next->tentry->type == TRY_CATCH) {
        try_catches[next->tentry->tentry].push_back(next_block);
      }
    }
  }
  // Link the blocks together with edges
  for (auto it = m_blocks.begin(); it != m_blocks.end(); ++it) {
    // Set outgoing edge if last MIE falls through
    auto lastmei = (*it)->rbegin();
    bool fallthrough = true;
    if (lastmei->type == MFLOW_OPCODE) {
      auto lastop = lastmei->insn->opcode();
      if (is_goto(lastop) || is_conditional_branch(lastop) ||
          is_multi_branch(lastop)) {
        fallthrough = !is_goto(lastop);
        auto const& targets = branch_to_targets[&*lastmei];
        for (auto target : targets) {
          (*it)->m_succs.push_back(target);
          target->m_preds.push_back(*it);
        }
      } else if (is_return(lastop) || lastop == OPCODE_THROW) {
        fallthrough = false;
      }
    }
    if (fallthrough && std::next(it) != m_blocks.end()) {
      Block* next = *std::next(it);
      (*it)->m_succs.push_back(next);
      next->m_preds.push_back(*it);
    }
  }
  /*
   * Now add the catch edges.  Every block inside a try-start/try-end region
   * gets an edge to every catch block.  This simplifies dataflow analysis
   * since you can always get the exception state by looking at successors,
   * without any additional analysis.
   *
   * NB: This algorithm assumes that a try-start/try-end region will consist of
   * sequentially-numbered blocks, which is guaranteed because catch regions
   * are contiguous in the bytecode, and we generate blocks in bytecode order.
   */
  for (auto tep : try_ends) {
    auto tryitem = tep.first;
    auto tryendblock = tep.second;
    size_t bid = tryendblock->id();
    always_assert(bid > 0);
    --bid;
    while (true) {
      auto block = m_blocks[bid];
      if (ends_with_may_throw(block)) {
        auto& catches = try_catches[tryitem];
        for (auto catchblock : catches) {
          block->m_succs.push_back(catchblock);
          catchblock->m_preds.push_back(block);
        }
      }
      auto begin = block->begin();
      if (begin->type == MFLOW_TRY) {
        auto tentry = begin->tentry;
        if (tentry->type == TRY_START && tentry->tentry == tryitem) {
          break;
        }
      }
      always_assert_log(bid > 0, "No beginning of try region found");
      --bid;
    }
  }
  TRACE(CFG, 5, "%s\n", show(m_method).c_str());
  TRACE(CFG, 5, "%s", show(m_blocks).c_str());
}