178 lines
6.0 KiB
C
178 lines
6.0 KiB
C
// test_lexer.c
|
|
#include "../../../../libcore/acutest.h"
|
|
#include "../lexer.h"
|
|
#include <string.h>
|
|
|
|
int test_read(void *dst_buf, int dst_size, int elem_size, int count, void *stream) {
|
|
if (stream == NULL) {
|
|
return 0;
|
|
}
|
|
int size = dst_size > elem_size * count ? elem_size * count : dst_size;
|
|
memcpy(dst_buf, stream, size);
|
|
return size;
|
|
}
|
|
|
|
// 测试辅助函数
|
|
static inline void test_lexer_string(const char* input, tok_type_t expected_type) {
|
|
lexer_t lexer;
|
|
tok_t token;
|
|
|
|
init_lexer(&lexer, "test.c", (void*)input, test_read);
|
|
get_valid_token(&lexer, &token);
|
|
|
|
TEST_CHECK(token.type == expected_type);
|
|
TEST_MSG("Expected: %s", get_tok_name(expected_type));
|
|
TEST_MSG("Got: %s", get_tok_name(token.type));
|
|
}
|
|
|
|
// 基础运算符测试
|
|
void test_operators() {
|
|
TEST_CASE("Arithmetic operators"); {
|
|
test_lexer_string("+", TOKEN_ADD);
|
|
test_lexer_string("++", TOKEN_ADD_ADD);
|
|
test_lexer_string("+=", TOKEN_ASSIGN_ADD);
|
|
test_lexer_string("-", TOKEN_SUB);
|
|
test_lexer_string("--", TOKEN_SUB_SUB);
|
|
test_lexer_string("-=", TOKEN_ASSIGN_SUB);
|
|
test_lexer_string("*", TOKEN_MUL);
|
|
test_lexer_string("*=", TOKEN_ASSIGN_MUL);
|
|
test_lexer_string("/", TOKEN_DIV);
|
|
test_lexer_string("/=", TOKEN_ASSIGN_DIV);
|
|
test_lexer_string("%", TOKEN_MOD);
|
|
test_lexer_string("%=", TOKEN_ASSIGN_MOD);
|
|
}
|
|
|
|
TEST_CASE("Bitwise operators"); {
|
|
test_lexer_string("&", TOKEN_AND);
|
|
test_lexer_string("&&", TOKEN_AND_AND);
|
|
test_lexer_string("&=", TOKEN_ASSIGN_AND);
|
|
test_lexer_string("|", TOKEN_OR);
|
|
test_lexer_string("||", TOKEN_OR_OR);
|
|
test_lexer_string("|=", TOKEN_ASSIGN_OR);
|
|
test_lexer_string("^", TOKEN_XOR);
|
|
test_lexer_string("^=", TOKEN_ASSIGN_XOR);
|
|
test_lexer_string("~", TOKEN_BIT_NOT);
|
|
test_lexer_string("<<", TOKEN_L_SH);
|
|
test_lexer_string("<<=", TOKEN_ASSIGN_L_SH);
|
|
test_lexer_string(">>", TOKEN_R_SH);
|
|
test_lexer_string(">>=", TOKEN_ASSIGN_R_SH);
|
|
}
|
|
|
|
TEST_CASE("Comparison operators"); {
|
|
test_lexer_string("==", TOKEN_EQ);
|
|
test_lexer_string("!=", TOKEN_NEQ);
|
|
test_lexer_string("<", TOKEN_LT);
|
|
test_lexer_string("<=", TOKEN_LE);
|
|
test_lexer_string(">", TOKEN_GT);
|
|
test_lexer_string(">=", TOKEN_GE);
|
|
}
|
|
|
|
TEST_CASE("Special symbols"); {
|
|
test_lexer_string("(", TOKEN_L_PAREN);
|
|
test_lexer_string(")", TOKEN_R_PAREN);
|
|
test_lexer_string("[", TOKEN_L_BRACKET);
|
|
test_lexer_string("]", TOKEN_R_BRACKET);
|
|
test_lexer_string("{", TOKEN_L_BRACE);
|
|
test_lexer_string("}", TOKEN_R_BRACE);
|
|
test_lexer_string(";", TOKEN_SEMICOLON);
|
|
test_lexer_string(",", TOKEN_COMMA);
|
|
test_lexer_string(":", TOKEN_COLON);
|
|
test_lexer_string(".", TOKEN_DOT);
|
|
test_lexer_string("...", TOKEN_ELLIPSIS);
|
|
test_lexer_string("->", TOKEN_DEREF);
|
|
test_lexer_string("?", TOKEN_COND);
|
|
}
|
|
}
|
|
|
|
// 关键字测试
|
|
void test_keywords() {
|
|
TEST_CASE("C89 keywords");
|
|
test_lexer_string("while", TOKEN_WHILE);
|
|
test_lexer_string("sizeof", TOKEN_SIZEOF);
|
|
|
|
// TEST_CASE("C99 keywords");
|
|
// test_lexer_string("restrict", TOKEN_RESTRICT);
|
|
// test_lexer_string("_Bool", TOKEN_INT); // 需确认你的类型定义
|
|
}
|
|
|
|
// 字面量测试
|
|
void test_literals() {
|
|
TEST_CASE("Integer literals"); {
|
|
// 十进制
|
|
test_lexer_string("0", TOKEN_INT_LITERAL);
|
|
test_lexer_string("123", TOKEN_INT_LITERAL);
|
|
// test_lexer_string("2147483647", TOKEN_INT_LITERAL);
|
|
|
|
// // 十六进制
|
|
// test_lexer_string("0x0", TOKEN_INT_LITERAL);
|
|
// test_lexer_string("0x1A3F", TOKEN_INT_LITERAL);
|
|
// test_lexer_string("0XABCDEF", TOKEN_INT_LITERAL);
|
|
|
|
// // 八进制
|
|
// test_lexer_string("0123", TOKEN_INT_LITERAL);
|
|
// test_lexer_string("0777", TOKEN_INT_LITERAL);
|
|
|
|
// // 边界值测试
|
|
// test_lexer_string("2147483647", TOKEN_INT_LITERAL); // INT_MAX
|
|
// test_lexer_string("4294967295", TOKEN_INT_LITERAL); // UINT_MAX
|
|
}
|
|
|
|
// TEST_CASE("Character literals"); {
|
|
// test_lexer_string("'a'", TOKEN_CHAR_LITERAL);
|
|
// test_lexer_string("'\\n'", TOKEN_CHAR_LITERAL);
|
|
// test_lexer_string("'\\t'", TOKEN_CHAR_LITERAL);
|
|
// test_lexer_string("'\\\\'", TOKEN_CHAR_LITERAL);
|
|
// test_lexer_string("'\\0'", TOKEN_CHAR_LITERAL);
|
|
// }
|
|
|
|
TEST_CASE("String literals"); {
|
|
test_lexer_string("\"hello\"", TOKEN_STRING_LITERAL);
|
|
test_lexer_string("\"multi-line\\nstring\"", TOKEN_STRING_LITERAL);
|
|
test_lexer_string("\"escape\\\"quote\"", TOKEN_STRING_LITERAL);
|
|
}
|
|
|
|
// TEST_CASE("Integer literals");
|
|
// test_lexer_string("123", TOKEN_INT_LITERAL);
|
|
// test_lexer_string("0x1F", TOKEN_INT_LITERAL);
|
|
|
|
// TEST_CASE("Floating literals");
|
|
// test_lexer_string("3.14e-5", TOKEN_FLOAT_LITERAL);
|
|
|
|
// TEST_CASE("Character literals");
|
|
// test_lexer_string("'\\n'", TOKEN_CHAR_LITERAL);
|
|
}
|
|
|
|
// 边界测试
|
|
void test_edge_cases() {
|
|
// TEST_CASE("Long identifiers");
|
|
// char long_id[LEXER_MAX_TOKEN_SIZE+2] = {0};
|
|
// memset(long_id, 'a', LEXER_MAX_TOKEN_SIZE+1);
|
|
// test_lexer_string(long_id, TOKEN_IDENT);
|
|
|
|
// TEST_CASE("Buffer boundary");
|
|
// char boundary[LEXER_BUFFER_SIZE*2] = {0};
|
|
// memset(boundary, '+', LEXER_BUFFER_SIZE*2-1);
|
|
// test_lexer_string(boundary, TOKEN_ADD);
|
|
}
|
|
|
|
// 错误处理测试
|
|
void test_error_handling() {
|
|
TEST_CASE("Invalid characters");
|
|
lexer_t lexer;
|
|
tok_t token;
|
|
|
|
init_lexer(&lexer, "test.c", NULL, test_read);
|
|
get_valid_token(&lexer, &token);
|
|
|
|
TEST_CHECK(token.type == TOKEN_EOF); // 应触发错误处理
|
|
}
|
|
|
|
// 测试列表
|
|
TEST_LIST = {
|
|
{"operators", test_operators},
|
|
{"keywords", test_keywords},
|
|
{"literals", test_literals},
|
|
{"edge_cases", test_edge_cases},
|
|
{"error_handling", test_error_handling},
|
|
{NULL, NULL}
|
|
}; |