示例#1
0
/*
 * Read a string literal:
 * - lex->current_char == '"' and lex->buffer is empty
 */
static yices_token_t read_string(lexer_t *lex) {
  yices_token_t tk;
  int c, x;
  reader_t *rd;
  string_buffer_t *buffer;

  rd = &lex->reader;
  buffer = lex->buffer;
  assert(reader_current_char(rd) == '"');

  c = reader_next_char(rd);

  for (;;) {
    if (c == '"') { // end of string
      // consume the closing quote
      reader_next_char(rd);
      tk = TK_STRING;
      break;
    }
    if (c == '\n' || c == EOF) { // missing quotes
      tk = TK_OPEN_STRING;
      break;
    }
    if (c == '\\') {
      // escape sequence
      c = reader_next_char(rd);
      switch (c) {
      case 'n': c = '\n'; break;
      case 't': c = '\t'; break;
      default:
        if ('0' <= c && c <= '7') {
          // read at most 2 more octal digits
          x = c - '0';
          c = reader_next_char(rd);
          if ('0' <= c && c <= '7') {
            x = 8 * x + (c - '0');
            c = reader_next_char(rd);
            if ('0' <= c && c <= '7') {
              x = 8 * x + (c - '0');
              c = reader_next_char(rd);
            }
          }
          // x = character built from the octal digits
          // c = character after octal digit
          string_buffer_append_char(buffer, x);
          continue;
        } // else skip '\': copy c in the buffer
        break;
      }
    }
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  }

  string_buffer_close(buffer);
  return tk;
}
示例#2
0
/*
 * Numbers that start with '0'
 * - the buffer must be empty
 * - current char must be '0'
 */
static smt2_token_t smt2_read_number0(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  buffer = lex->buffer;
  c = reader_current_char(rd);

  assert(string_buffer_length(buffer) == 0 && c == '0');

  // add '0'
  string_buffer_append_char(buffer, c);

  c = reader_next_char(rd);
  tk = SMT2_TK_NUMERAL;

  if (c == '.') {
    // parse a decimal '0.<digits>'
    do {
      string_buffer_append_char(buffer, c);
      c = reader_next_char(rd);
    } while (isdigit(c));

    tk = SMT2_TK_DECIMAL;
    if (string_buffer_length(buffer) <= 2) {
      tk = SMT2_TK_INVALID_DECIMAL; // '0.' but not digit after that
    }

  } else if (isdigit(c)) {
    /*
     * invalid numeral such as '00..' or '05...'
     * put all the digits that follow '0' in the buffer
     * to give a nicer error message
     */
    do {
      string_buffer_append_char(buffer, c);
      c = reader_next_char(rd);
    } while (isdigit(c));

    tk = SMT2_TK_INVALID_NUMERAL;
  }

  string_buffer_close(buffer);

  return tk;
}
示例#3
0
/*
 * Read a symbol or keyword
 * lex->buffer contains one char (not a separator or digit)
 * char = next character after that.
 */
static yices_token_t read_symbol(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  token_t tk;
  const keyword_t *kw;

  rd = &lex->reader;
  c = reader_current_char(rd);
  buffer = lex->buffer;

  while (! is_yices_sep(c)) {
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  }

  string_buffer_close(buffer);

  tk = TK_SYMBOL;
  kw = in_yices_kw(buffer->data, buffer->index);
  if (kw != NULL) {
    tk = kw->tk;
  }

  return tk;
}
示例#4
0
/*
 * String literal for SMT-LIB 2.5
 *
 * Gratuitous change to the escape sequence:
 * - replace "" inside the string by "
 * - note that this means that we can't have an empty string ""
 *   (so the example on page 22 of 'The SMT-LIB Standard Version 2.5'
 *   is wrong).
 */
static smt2_token_t smt2_read_string_var(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  buffer = lex->buffer;
  assert(reader_current_char(rd) == '"');

  for (;;) {
    c = reader_next_char(rd);
    if (c == '"') {
      c = reader_next_char(rd);
      if (c != '"') {
	tk = SMT2_TK_STRING;
	break;
      }
    }
    if (c < 32 && !isspace(c)) {
      // error
      tk = SMT2_TK_INVALID_STRING;
      break;
    }
   string_buffer_append_char(buffer, c);
  }

  string_buffer_close(buffer);

  return tk;
}
示例#5
0
/*
 * Read a quoted symbol: any sequence of characters delimited by '|'
 * - exceptions: no '\' allowed in the symbol
 * - all characters between '|' must be printable
 * - the delimiting '|' are not part of the symbol
 *
 * - the buffer must be empty
 * - current char must be '|'
 *
 * Return SMT2_TK_INVALID_SYMBOL if a non-printable character
 * or '\' is found before the closing '|'. Return SMT2_TK_QSYMBOL
 * otherwise.
 */
static smt2_token_t smt2_read_quoted_symbol(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  buffer = lex->buffer;
  assert(string_buffer_length(buffer) == 0 &&
         reader_current_char(rd) == '|');

  for (;;) {
    c = reader_next_char(rd);
    if (c == '|' || c == '\\' || !ok_char(c)) { 
      //    (!isprint(c) && !isspace(c))) { // HACK TO PARSE BENCHMARKS
      // either the terminator '|' or a character not allowed in quoted symbols
      break;
    }
    string_buffer_append_char(buffer, c);
  }
  string_buffer_close(buffer);

  tk = SMT2_TK_INVALID_SYMBOL;
  if (c == '|') {
    // consume the closing '|'
    reader_next_char(rd);
    tk = SMT2_TK_QSYMBOL;
  }

  return tk;
}
示例#6
0
/*
 * Read a simple symbol
 * - the buffer must be empty
 * - current_char must be simple
 * - read the sequence of simple chars and add it to the buffer
 *
 * If the symbol is a reserved word, return the corresponding
 * token id. Otherwise, return SMT2_TK_SYMBOL.
 */
static smt2_token_t smt2_read_symbol(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  const keyword_t *kw;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  buffer = lex->buffer;
  c = reader_current_char(rd);

  assert(string_buffer_length(buffer) == 0 && issimple(c));

  do {
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  } while (issimple(c));
  string_buffer_close(buffer);

  tk = SMT2_TK_SYMBOL;
  kw = in_smt2_tk(buffer->data, buffer->index);
  if (kw != NULL) {
    tk = kw->tk;
  }

  return tk;
}
示例#7
0
/*
 * Read a keyword:
 * - the buffer must be empty
 * - current_char must be ':'
 * - add ':' + the sequence of simple_chars that follows to the buffer
 *
 * If ':' is not followed by a simple char, return SMT2_TK_INVALID_KEYWORD
 * Otherwise return SMT2_TK_KEYWORD.
 */
static smt2_token_t smt2_read_keyword(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  buffer = lex->buffer;
  c = reader_current_char(rd);

  assert(string_buffer_length(buffer) == 0 && c == ':');

  do {
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  } while (issimple(c));
  string_buffer_close(buffer);

  tk = SMT2_TK_KEYWORD;
  if (string_buffer_length(buffer) <= 1) {
    tk = SMT2_TK_INVALID_KEYWORD;
  }

  return tk;
}
示例#8
0
/*
 * Read an hexadecimal literal
 * - the buffer must contain '#'
 * - current_char must be 'x'
 * - add 'x' and the sequence of hexadecimal digits that
 *   follows to the buffer
 * - stop on the first character that's not hexadecimal
 *
 * The resulting token is stored in buffer
 * - return code:
 *   SMT2_TK_HEXADECIMAL if the sequence is non-empty
 *   SMT2_TK_INVALID_HEXADECIMAL if the sequence is empty
 */
static smt2_token_t smt2_read_hexa(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  buffer = lex->buffer;
  c = reader_current_char(rd);

  assert(string_buffer_length(buffer) == 1 &&
         buffer->data[0] == '#' && c == 'x');

  do {
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  } while (isxdigit(c));
  string_buffer_close(buffer);

  tk = SMT2_TK_HEXADECIMAL;
  if (string_buffer_length(buffer) <= 2) {
    tk = SMT2_TK_INVALID_HEXADECIMAL;
  }

  return tk;
}
示例#9
0
/*
 * Read a binary literal
 * - the buffer must contain '#'
 * - current char must be 'b'
 * - add 'b' and the sequence of '0' and '1' that follows
 *   to the buffer
 * - stop on the first character that's not '0' or '1'
 *
 * The resulting token is stored in buffer
 * - return code:
 *   SMT2_TK_BINARY if the sequence is non-empty
 *   SMT2_TK_INVALID_BINARY if the sequence is empty
 */
static smt2_token_t smt2_read_binary(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  buffer = lex->buffer;
  c = reader_current_char(rd);

  assert(string_buffer_length(buffer) == 1 &&
         buffer->data[0] == '#' && c == 'b');

  do {
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  } while (c == '0' || c == '1');
  string_buffer_close(buffer);

  tk = SMT2_TK_BINARY;
  if (string_buffer_length(buffer) <= 2) {
    tk = SMT2_TK_INVALID_BINARY;
  }

  return tk;
}
示例#10
0
static void show_test(char *desc, string_buffer_t *s) {
  printf("%s\n", desc);
  string_buffer_append_char(s, '!');
  string_buffer_print(stdout, s);
  printf("\n");
  fflush(stdout);
}
示例#11
0
/*
 * Numbers that don't start with '0'
 * - the buffer must be empty
 * - current char must be a digit '1' to '9'
 * - read the sequence of digits that follows and add it to the buffer
 * - if the character after this sequence is '.' then read as a DECIMAL
 *   otherwise the token is a NUMERAL.
 *
 * Return code:
 * - SMT2_INVALID_DECIMAL if the '.' is not followed by a digit
 */
static smt2_token_t smt2_read_number(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;
  uint32_t i;

  rd = &lex->reader;
  buffer = lex->buffer;
  c = reader_current_char(rd);

  assert(string_buffer_length(buffer) == 0 && isdigit(c) && c != '0');

  // first sequence of digits
  do {
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  } while (isdigit(c));

  tk = SMT2_TK_NUMERAL;
  if (c == '.') {
    i = string_buffer_length(buffer);

    // attempt to parse a DECIMAL
    do {
      string_buffer_append_char(buffer, c);
      c = reader_next_char(rd);
    } while (isdigit(c));

    tk = SMT2_TK_DECIMAL;
    if (string_buffer_length(buffer) <= i+1) {
      tk = SMT2_TK_INVALID_DECIMAL;
    }
  }

  string_buffer_close(buffer);

  return tk;
}
示例#12
0
/*
 * Read a string literal
 * - current char is "
 * - read all characters until the closing " or any non-printable
 *   character
 * - replace escape sequences \" by " and \\ by \
 *
 * Result: the lexer's buffer contains the string literal
 * without the delimiting quotes.
 * - return code:
 *   SMT2_TK_STRING if the string is valid
 *   SMT2_TK_INVALID_STRING if the string is terminated by
 *   a non-printable character
 *
 * NOTE: this is not strictly compliant with the SMT-LIB 2.0
 * standard as we may include non-ascii printable characters
 * in the string.
 *
 * NOTE2: the SMT-LIB2 standard says 'a string is any sequence of
 * printable ASCII characters delimited by double quotes ...' But it
 * does not define 'printable ASCII character'. Several benchmarks in
 * SMT-LIB include line breaks inside a string (which are not
 * printable characters), so I've changed the loop below to allow both
 * printable characters and spaces.
 */
static smt2_token_t smt2_read_string(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  buffer = lex->buffer;
  assert(reader_current_char(rd) == '"');

  for (;;) {
    c = reader_next_char(rd);
    if (c == '"') {
      // consume the closing quote
      reader_next_char(rd);
      tk = SMT2_TK_STRING;
      break;
    }

    if (!isprint(c) && !isspace(c)) {
      // error
      tk = SMT2_TK_INVALID_STRING;
      break;
    }

    if (c == '\\') {
      c = reader_next_char(rd);
      if (c != '"' && c != '\\') {
        // keep the backslash
        string_buffer_append_char(buffer, '\\');
      }
    }
    string_buffer_append_char(buffer, c);
  }

  string_buffer_close(buffer);

  return tk;
}
示例#13
0
char *js_get_message(jsval v) {
	jsval messages, msg, rval;
	uint32_t messages_len;
	char *c_str;
	int i;
	struct string_buffer sb = STRING_BUFFER_INITIALIZER;

	if (!JS_GetProperty(js_context, JSVAL_TO_OBJECT(v), "messages", &messages)) {
		return NULL;
	}

	switch(JS_TypeOfValue(js_context, messages)) {
		case JSTYPE_STRING:
			c_str = JS_EncodeString(js_context, JSVAL_TO_STRING(messages));
			return c_str;

		case JSTYPE_OBJECT:
			if (!JS_GetArrayLength(js_context, JSVAL_TO_OBJECT(messages), &messages_len)) {
				return NULL;
			}

			for (i = 0; i < (int) messages_len; i++) {
				if (!JS_GetElement(js_context, JSVAL_TO_OBJECT(messages), i, &msg)) {
					goto out_err;
				}

				c_str = JS_EncodeString(js_context, JSVAL_TO_STRING(msg));

				if (string_buffer_append_string(&sb, c_str))
					goto out_err;

				if (i < (int) messages_len - 1) {
					if (string_buffer_append_char(&sb, '\n'))
						goto out_err;
				}

				free(c_str);
			}

			return sb.s;
		default:
			break;
	}

out_err:
	free(c_str);
	string_buffer_cleanup(&sb);
	return NULL;
}
示例#14
0
size_t read_line(int socket, STRING_BUFFER_PTR *string_buffer_ptr) {

    // If input is invalid then just error out.
    //
    if (NULL == string_buffer_ptr){
        return 0;
    }

    // We are getting a new "line" so wack the old one if it exists.
    //
    if (*string_buffer_ptr){
        string_buffer_reset(*string_buffer_ptr);
    }
    else{
        *string_buffer_ptr = string_buffer_new();
    }

    // Now we read in the data:
    //
    char c = '\0';

    while (c != '\n') {
        ssize_t n = recv(socket, &c, 1, 0);

        if (n > 0) {
            if (c == '\r') {
                n = recv(socket, &c, 1, MSG_PEEK);

                if ((n > 0) && (c == '\n')) {
                    recv(socket, &c, 1, 0);
                }
                else {
                    c = '\n';
                }
            }

            string_buffer_append_char(*string_buffer_ptr, c);
        }
        else {
            c = '\n';
        }
    }

    return string_buffer_c_string_length(*string_buffer_ptr);
}
示例#15
0
int tokenizer_eat_number(struct tokenizer* tokenizer)
 //@ requires Tokenizer(tokenizer);
 //@ ensures Tokenizer(tokenizer);
{
	for (;;)
	  //@ invariant Tokenizer(tokenizer);
	{
		int result;
		bool isDigit;
		
		result = tokenizer_peek(tokenizer);
		isDigit = is_digit(result);
		if ( !isDigit ) break;
		
	        result = tokenizer_next_char(tokenizer);
		string_buffer_append_char(tokenizer->buffer, (char)result);
	}

	return '0';
}
示例#16
0
/*
 * Read a hexadecimal constant:
 * lex->current_char = 'x' and lex->buffer contains "0"
 */
static yices_token_t read_hex_constant(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;

  rd = &lex->reader;
  c = reader_current_char(rd);
  buffer = lex->buffer;

  do {
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  } while (isxdigit(c));
  string_buffer_close(buffer);

  if (string_buffer_length(buffer) <= 2) {
    return TK_EMPTY_HEXCONST; // empty constant
  } else {
    return TK_HEX_CONSTANT;
  }
}
示例#17
0
int tokenizer_eat_symbol(struct tokenizer* tokenizer)
 //@ requires Tokenizer(tokenizer);
 //@ ensures Tokenizer(tokenizer);
{
	for (;;)
		//@ invariant Tokenizer(tokenizer);
	{
		int result;
		bool isSymbolChar;
		
		result = tokenizer_peek(tokenizer);
		isSymbolChar = is_symbol_char(result);
		
		if (!isSymbolChar) break;
		
		result = tokenizer_next_char(tokenizer);
		string_buffer_append_char(tokenizer->buffer, (char)result);
	}

	return 'S';
}
示例#18
0
int mod_clamav_result(struct smtp_server_context *ctx, bfd_t *fr, int status)
{
	if (WEXITSTATUS(status) > 1) {
		JS_Log(JS_LOG_ERR, "clamdscan failed with error\n");
		return 0;
	}

	if (!WEXITSTATUS(status)) {
		JS_Log(JS_LOG_INFO, "message passed\n");
		return 0;
	}

	ctx->code = 550;

	do {
		struct string_buffer sb;
		char c;
		int i;

		string_buffer_init(&sb);
		/* first line of output is "stream: " followed
		 * by the virus name followed by " FOUND"; first
		 * skip "stream: " */
		for (i = 0; i < 8; i++)
			if (bfd_getc(fr) < 0)
				break;
		/* copy virus name */
		while ((c = bfd_getc(fr)) >= 0 && c != ' ')
			string_buffer_append_char(&sb, c);
		if (sb.s == NULL)
			break;
		if (asprintf(&ctx->message, "This message appears to be infected with the %s virus", sb.s) == -1)
			ctx->message = NULL;
	} while (0);
	if (ctx->message == NULL)
		ctx->message = strdup("This message appears to contain viruses");
	return 0;
}
示例#19
0
dino_http_method parse_method_url(dino_http_data_t *http) {
    // Should not happen:
    //
    if (NULL == http) {
        return http_invalid;
    }

    // Read in the data:
    //
    STRING_BUFFER_PTR string_buffer_ptr = NULL;

    if (0 == read_line(http->socket, &string_buffer_ptr)) {
        string_buffer_delete(string_buffer_ptr, true);
        return http_invalid;
    }

    // Obtain the method
    //
    char method[32];
    memory_clear(method, sizeof(method));
    int offset = 0;

    const char *line = string_buffer_c_string(string_buffer_ptr);

    for (int i = 0; !isspace(line[i]) && (i < sizeof(method)); i++) {
        method[i] = line[i];
        offset++;
    }

    http->request.method = map_string_to_http_method(method);

    if (http_invalid == http->request.method) {
        string_buffer_delete(string_buffer_ptr, true);
        return http_invalid;
    }

    // Fetch the URL
    //
    const char *query = line + offset;
    STRING_BUFFER_PTR buffer_url = string_buffer_new();

    // Skip over the ' 's and the tabs
    //
    while (*query != '\0' && (*query == ' ' || *query == '\t')) {
        ++query;
    }

    while (*query != '\0' && *query != '?' && *query != ' ' && *query != '\t') {
        string_buffer_append_char(buffer_url, *query);
        query++;
    }

    http->request.url = buffer_url;

    if (*query == '?') {
        // Move off of '?'
        //
        query++;

        offset = 0;

        STRING_BUFFER_PTR buffer_params = string_buffer_new();

        while (!isspace(*query) && *query != 0) {
            string_buffer_append_char(buffer_params, *query);
            offset++;
            query++;
        }

        // Parse the URL parameters
        //
        char *break_token = NULL;

        for (char *param = strtok_r(string_buffer_c_string(buffer_params), "&", &break_token);
             param;
             param = strtok_r(NULL, "&", &break_token))
        {
            char *break_token_2 = NULL;
            char *key = strtok_r(param, "=", &break_token_2);
            char *value = strtok_r(NULL, "=", &break_token_2);

            dino_strmap_add(http->request.params_map, key, value);
        }

        string_buffer_delete(buffer_params, true);
    }

    string_buffer_delete(string_buffer_ptr, true);
    return http->request.method;
}
示例#20
0
/*
 * Read the next token and return its code tk
 * - set lex->token to tk
 * - set lex->tk_pos
 * - if the token is not '(' or ')', then its value is in lex->buffer
 *   as a string
 */
smt2_token_t next_smt2_token(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c;
  smt2_token_t tk;

  rd = &lex->reader;
  c = reader_current_char(rd);
  buffer = lex->buffer;
  string_buffer_reset(buffer);

  // skip spaces and comments
  for (;;) {
    while (isspace(c)) c = reader_next_char(rd);
    if (c != ';') break;
    // comments: read everything until the end of the line or EOF
    do {
      c = reader_next_char(rd);
    } while (c != '\n' && c != EOF);
  }

  // record start of token
  lex->tk_pos = rd->pos;
  lex->tk_line = rd->line;
  lex->tk_column = rd->column;

  switch (c) {
  case '(':
    tk = SMT2_TK_LP;
    goto next_then_return;

  case ')':
    tk = SMT2_TK_RP;
    goto next_then_return;

  case EOF:
    tk = SMT2_TK_EOS;
    goto done;

  case '"':
    if (two_dot_five_variant) {
      tk = smt2_read_string_var(lex);
    } else {
      tk = smt2_read_string(lex);
    }
    goto done;

  case '#':
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
    if (c == 'b') {
      tk = smt2_read_binary(lex);
    } else if (c == 'x') {
      tk = smt2_read_hexa(lex);
    } else {
      tk = SMT2_TK_ERROR;
      string_buffer_close(buffer);
    }
    goto done;

  case '0':
    tk = smt2_read_number0(lex);
    goto done;

  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
    tk = smt2_read_number(lex);
    goto done;

  case ':':
    tk = smt2_read_keyword(lex);
    goto done;

  case '|':
    tk = smt2_read_quoted_symbol(lex);
    goto done;

  default:
    if (issimple(c)) {
      tk = smt2_read_symbol(lex);
      goto done;
    } else {
      tk = SMT2_TK_ERROR;
      /*
       * copy the bad character in buffer for
       * better error reporting
       */
      string_buffer_append_char(buffer, c);
      string_buffer_close(buffer);
      goto next_then_return;
    }
  }

 next_then_return:
  reader_next_char(rd);

 done:
  lex->token = tk;

  return tk;
}
示例#21
0
/*
 * Read a number
 * lex->buffer contains <optional_sign> and a single digit
 * current_char = what's after the digit in buffer.
 */
static yices_token_t read_number(lexer_t *lex) {
  reader_t *rd;
  string_buffer_t *buffer;
  int c, all_zeros;
  yices_token_t tk;

  rd = &lex->reader;
  c = reader_current_char(rd);
  buffer = lex->buffer;
  tk = TK_NUM_RATIONAL; // default

  while (isdigit(c)) {
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
  }

  if (c == '/') {
    // denominator
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
    if (! isdigit(c)) {
      tk = TK_INVALID_NUM;
      goto done;
    }
    all_zeros = true;
    do {
      if (c != '0') all_zeros = false;
      string_buffer_append_char(buffer, c);
      c = reader_next_char(rd);
    } while (isdigit(c));

    if (all_zeros) tk = TK_ZERO_DIVISOR;
    // else tk = TK_NUM_RATIONAL
    goto done;
  }

  if (c == '.') {
    tk = TK_NUM_FLOAT;
    // fractional part
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
    if (! isdigit(c)) {
      tk = TK_INVALID_NUM;
      goto done;
    }
    do {
      string_buffer_append_char(buffer, c);
      c = reader_next_char(rd);
    } while (isdigit(c));
  }

  if (c == 'e' || c == 'E') {
    tk = TK_NUM_FLOAT;
    // exponent
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
    if (c == '+' || c == '-') {
      string_buffer_append_char(buffer, c);
      c = reader_next_char(rd);
    }
    if (! isdigit(c)) {
      tk = TK_INVALID_NUM;
      goto done;
    }
    do {
      string_buffer_append_char(buffer, c);
      c = reader_next_char(rd);
    } while (isdigit(c));
  }

 done:
  string_buffer_close(buffer);
  return tk;
}
示例#22
0
/*
 * Read next token and return its type tk
 * - set lex->token to tk
 * - set lex->tk_pos, etc.
 * - if token is TK_STRING, TK_NUM_RATIONAL, TK_NUM_FLOAT, TK_BV_CONSTANT, TK_SYMBOL, TK_ERROR,
 *   the token value is stored in lex->buffer (as a string).
 */
yices_token_t next_yices_token(lexer_t *lex) {
  yices_token_t tk;
  reader_t *rd;
  string_buffer_t *buffer;
  int c;

  rd = &lex->reader;
  c = reader_current_char(rd);
  buffer = lex->buffer;
  string_buffer_reset(buffer);

  // skip spaces and comments
  for (;;) {
    while (isspace(c)) c = reader_next_char(rd);
    if (c != ';') break;
    do { // read to end-of-line or eof
      c = reader_next_char(rd);
    } while (c != '\n' && c != EOF);
  }

  // record token position (start of token)
  lex->tk_pos = rd->pos;
  lex->tk_line = rd->line;
  lex->tk_column = rd->column;

  switch (c) {
  case '(':
    tk = TK_LP;
    goto next_then_return;
  case ')':
    tk = TK_RP;
    goto next_then_return;
  case EOF:
    tk = TK_EOS;
    goto done;
  case ':':
    c = reader_next_char(rd);
    if (c == ':') {
      tk = TK_COLON_COLON;
      goto next_then_return;
    } else {
      // store ':' in the buffer since that may be used for reporting errors
      string_buffer_append_char(buffer, ':');
      string_buffer_close(buffer);
      tk = TK_ERROR;
      goto done;
    }
  case '"':
    tk = read_string(lex);
    goto done;
  case '+':
  case '-':
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
    if (isdigit(c)) {
      string_buffer_append_char(buffer, c);
      reader_next_char(rd);
      tk = read_number(lex);
    } else {
      tk = read_symbol(lex);
    }
    goto done;

  case '0':
    string_buffer_append_char(buffer, c);
    c = reader_next_char(rd);
    if (c == 'b') {
      tk = read_bv_constant(lex);
    } else if (c == 'x') {
      tk = read_hex_constant(lex);
    } else {
      tk = read_number(lex);
    }
    goto done;

  case '1':
  case '2':
  case '3':
  case '4':
  case '5':
  case '6':
  case '7':
  case '8':
  case '9':
    string_buffer_append_char(buffer, c);
    reader_next_char(rd);
    tk = read_number(lex);
    goto done;

  default: // symbol or keyword
    string_buffer_append_char(buffer, c);
    reader_next_char(rd);
    tk = read_symbol(lex);
    goto done;
  }

  /*
   * read next character and exit
   */
 next_then_return:
  reader_next_char(rd);


 done:
  lex->token = tk;
  return tk;
}
示例#23
0
int main() {
  int32_t x, y;
  uint32_t a, b, n;
  char c;
  string_buffer_t *s;

  s = &buffer;
  init_string_buffer(s, 0);
  show_test("empty buffer", s);

  string_buffer_reset(s);
  for (c = 'a'; c <= 'z'; c++) {
    string_buffer_append_char(s, c);
  }
  show_test("alphabet", s);

  string_buffer_reset(s);
  for (c = 'a'; c <= 'z'; c++) {
    string_buffer_append_char(s, c);
  }
  string_buffer_append_string(s, "au898ue2bcc90219");
  show_test("alphabet+au898ue2bcc90219", s);

  x = INT32_MIN;
  for (;;){
    sprintf(aux, "signed number: %" PRId32, x);
    string_buffer_reset(s);
    string_buffer_append_int32(s, x);
    show_test(aux, s);
    y = x >> 1;
    if (y == x) break;
    x = y;
  }

  x = INT32_MAX;
  for (;;) {
    sprintf(aux, "signed number: %" PRId32, x);
    string_buffer_reset(s);
    string_buffer_append_int32(s, x);
    show_test(aux, s);
    y = x>>1;
    if (y == x) break;
    x = y;
  }

  a = UINT32_MAX;
  for (;;){
    sprintf(aux, "unsigned number: %" PRIu32, a);
    string_buffer_reset(s);
    string_buffer_append_uint32(s, a);
    show_test(aux, s);
    b = a >> 1;
    if (b == a) break;
    a = b;
  }

  mpz_init(z0);
  mpz_init(z1);
  mpq_init(q0);

  mpz_set_str(z0, "111102222033330123456789", 10);
  string_buffer_reset(s);
  string_buffer_append_mpz(s, z0);
  show_test("mpz: 111102222033330123456789", s);

  mpz_set_str(z0, "-111102222033330123456789", 10);
  string_buffer_reset(s);
  string_buffer_append_mpz(s, z0);
  show_test("mpz: -111102222033330123456789", s);

  string_buffer_reset(s);
  string_buffer_append_mpz(s, z1);
  show_test("mpz: 0", s);

  mpq_set_str(q0, "-98765432109876543210", 10);
  string_buffer_reset(s);
  string_buffer_append_mpq(s, q0);
  show_test("mpq: -98765432109876543210", s);

  mpq_set_str(q0, "-98765432109876543210/38192839777", 10);
  string_buffer_reset(s);
  string_buffer_append_mpq(s, q0);
  show_test("mpq: -98765432109876543210/38192839777", s);

  init_rationals();
  rational_t r0;
  q_init(&r0);
  string_buffer_reset(s);
  string_buffer_append_rational(s, &r0);
  show_test("rational: 0", s);

  q_set_int32(&r0, -12, 73);
  string_buffer_reset(s);
  string_buffer_append_rational(s, &r0);
  show_test("rational: -12/73", s);

  q_set_mpq(&r0, q0);
  string_buffer_reset(s);
  string_buffer_append_rational(s, &r0);
  show_test("rational: -98765432109876543210/38192839777", s);

  q_set_mpz(&r0, z0);
  string_buffer_reset(s);
  string_buffer_append_rational(s, &r0);
  show_test("rational: -111102222033330123456789", s);


  printf("\nBit Vectors\n");
  init_bvconstants();
  bv0 = bvconst_alloc(1);
  bvconst_clear(bv0, 1);
  for (n=1; n<= 32; n++) {
    string_buffer_reset(s);
    string_buffer_append_bvconst(s, bv0, n);
    sprintf(aux, "bv[%" PRIu32"]: 0b000...", n);
    show_test(aux, s);
  }

  for (n=1; n <= 32; n++) {
    bvconst_clear(bv0, 1);
    bvconst_set_bit(bv0, n-1);
    string_buffer_reset(s);
    string_buffer_append_bvconst(s, bv0, n);
    sprintf(aux, "bv[%" PRIu32"]: 0b100...", n);
    show_test(aux, s);
  }


  bvconst_free(bv0, 1);

  cleanup_bvconstants();

  cleanup_rationals();

  mpz_clear(z0);
  mpz_clear(z1);
  mpq_clear(q0);

  delete_string_buffer(s);

  return 0;
}