Пример #1
0
// rl_input puts upto MAX characters into BUF with the number put in
// BUF placed in *RESULT.
static void lexer_input (char *buf, unsigned long int *result, int max, void* yyscanner) {
    if (yyget_in(yyscanner) != rl_instream) { //not stdin so read as usual
        while ( (*result = read( fileno(yyget_in(yyscanner)), buf, max )) < 0 ) {
            if (errno != EINTR) {
                std::cerr << "read() in flex scanner failed" << std::endl;
                exit (1);
            }
        }
        return;
    }

    if (rl_len == 0) { //Do we need a new string?
        if (rl_start) {
            free(rl_start);
        }
        unsigned short scopes = yyget_extra(yyscanner)->indents.size();
        std::string prompt = "sugar";
        if(yyget_extra(yyscanner)->pendingEndInstr){
            prompt += "*";
        }
        if(scopes > 1){
            prompt += "("+std::to_string(scopes)+")";
        }
        prompt += "> ";
#if SHELL_USE_COLOR
        prompt = "\x1b[33m"+prompt+"\x1b[0m";
#endif
        rl_start = readline (prompt.c_str());
        if (rl_start == NULL) { //end of file
            *result = 0;
            rl_len = 0;
            return;
        }
        rl_line = rl_start;
        rl_len = strlen (rl_line)+1;
        if (rl_len != 1) {
            add_history (rl_line);
        }
        rl_line[rl_len-1] = '\n';
        fflush (stdout);
    }

    if (rl_len <= max) {
        strncpy (buf, rl_line, rl_len);
        *result = rl_len;
        rl_len = 0;
    }
    else {
        strncpy (buf, rl_line, max);
        *result = max;
        rl_line += max;
        rl_len -= max;
    }
}
Пример #2
0
/*Thread task function for reentrant scanner*/
void *lex_thread_task(void *arg)
{  
  lex_thread_arg *ar = (lex_thread_arg*) arg;
  
  FILE * f = fopen(ar->file_name, "r");
  if (f == NULL) {
    DEBUG_STDOUT_PRINT("ERROR> Lexing thread %d could not open input file. Aborting.\n", ar->id);
    exit(1);
  }

  lex_token *flex_token;
  int8_t end_of_chunk = 0;
  yyscan_t scanner;   //reentrant flex instance data
  int32_t flex_return_code;
  token_node *token_builder = NULL;
  token_node_stack stack;
  sem_value_stack stack_char;
  sem_value_stack stack_int;

  uint32_t alloc_size = 0, realloc_size = 0;

  uint32_t chunk_length = ar->cut_point_dx - ar->cut_point_sx;

  par_compute_alloc_realloc_size((ar->cut_point_dx - ar->cut_point_sx), &alloc_size, &realloc_size);
  DEBUG_STDOUT_PRINT("LEXER %d > alloc_size %d, realloc_size %d\n", ar->id, alloc_size, realloc_size)

  /*Initialization flex_token*/
  flex_token = (lex_token*) malloc(sizeof(lex_token));
  if (flex_token == NULL) {
    DEBUG_STDOUT_PRINT("ERROR> could not complete malloc flex_token. Aborting.\n");
    exit(1);
  }
  flex_token->chunk_length = chunk_length;
  flex_token->num_chars = 0;
  flex_token->chunk_ended = 0;
  //Initialize stack for semantic values.
  //Since the possible semantic values are only char or int, we can allocate two different stacks, one for each type, avoiding to waste memory.
  init_sem_value_stack(&stack_char, alloc_size, 0);
  init_sem_value_stack(&stack_int, alloc_size, 1);
  flex_token->stack_char = &stack_char;
  flex_token->stack_int = &stack_int;
  flex_token->realloc_size = realloc_size;

  fseek(f, ar->cut_point_sx, SEEK_SET);

  if(yylex_init_extra(flex_token, &scanner))
  {
    DEBUG_STDOUT_PRINT("ERROR> yylex_init_extra failed.\n")
    exit(1);
  }

  yyset_in(f, scanner);
  
  ar->list_begin = NULL;
  init_token_node_stack(&(stack), alloc_size);

  flex_return_code = yylex(scanner); 

  /*The procedure to find cut points cannot cut a single token in two parts.*/
  while(!end_of_chunk && flex_return_code != __END_OF_CHUNK && flex_return_code != __END_OF_FILE)
  {
    if(flex_return_code == __LEX_CORRECT) {
      //append a token
      par_append_token_node(flex_token->token, flex_token->semantic_value, &token_builder, &(ar->list_begin), &stack, realloc_size);
      ar->lex_token_list_length++;
    }
    else {
      //flex_return_code is __ERROR)
      DEBUG_STDOUT_PRINT("Lexing thread %d scanned erroneous input. Abort.\n", ar->id)
      ar->result = 1; /*Signal error by returning result!=0.*/
      fclose(yyget_in(scanner));
      yylex_destroy(scanner);
      fclose(f);
      pthread_exit(NULL);
    }

    if (flex_token->chunk_ended)
      end_of_chunk = 1;
    else {
      //Continue to scan the chunk
      flex_return_code = yylex(scanner); 
    }
  }

  ar->list_end = token_builder;

  fclose(yyget_in(scanner));
  yylex_destroy(scanner);

  fclose(f);

  pthread_exit(NULL);

}