-
Notifications
You must be signed in to change notification settings - Fork 1
/
test_lexer.c
125 lines (114 loc) · 5.36 KB
/
test_lexer.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
#include "nocc.h"
typedef struct {
int kind;
const char *text;
int line;
const char *string;
} TokenTestSuite;
static void test_tokens(const char *src, const TokenTestSuite *suites) {
const Token **toks = (const Token **)lex("test_lexer", src)->data;
int i = 0;
do {
if (toks[i]->kind != suites[i].kind) {
fprintf(stderr, "%s\n: toks[%d]->kind is expected %d, but got %d\n",
src, i, suites[i].kind, toks[i]->kind);
exit(1);
}
if (strcmp(toks[i]->text, suites[i].text) != 0) {
fprintf(stderr, "%s\n: toks[%d]->text is expected %s, but got %s\n",
src, i, suites[i].text, toks[i]->text);
exit(1);
}
if (toks[i]->line != suites[i].line) {
fprintf(stderr, "%s\n: toks[%d]->line is expected %d, but got %d\n",
src, i, suites[i].line, toks[i]->line);
exit(1);
}
if (suites[i].string == NULL) {
if (toks[i]->string != NULL) {
fprintf(stderr,
"%s\n: toks[%d]->string is expected null, but got %s\n",
src, i, toks[i]->string);
exit(1);
}
} else {
if (toks[i]->string == NULL) {
fprintf(stderr,
"%s\n: toks[%d]->string is expected %s, but got null\n",
src, i, suites[i].string);
exit(1);
} else if (strcmp(toks[i]->string, suites[i].string) != 0) {
fprintf(stderr,
"%s\n: toks[%d]->string is expected %s, but got %s\n",
src, i, suites[i].string, toks[i]->string);
exit(1);
}
}
} while (toks[i++]->kind != '\0');
}
void test_lexer(void) {
test_tokens("42 + 5 - \n a*abc", (TokenTestSuite[]){
{token_number, "42", 1, NULL},
{' ', " ", 1, NULL},
{'+', "+", 1, NULL},
{' ', " ", 1, NULL},
{token_number, "5", 1, NULL},
{' ', " ", 1, NULL},
{'-', "-", 1, NULL},
{' ', " ", 1, NULL},
{'\n', "\n", 1, NULL},
{' ', " ", 2, NULL},
{token_identifier, "a", 2, NULL},
{'*', "*", 2, NULL},
{token_identifier, "abc", 2, NULL},
{'\0', "", 2, NULL},
});
test_tokens("if (x<=y==true) {\n}", (TokenTestSuite[]){
{token_identifier, "if", 1, NULL},
{' ', " ", 1, NULL},
{'(', "(", 1, NULL},
{token_identifier, "x", 1, NULL},
{token_lesser_equal, "<=", 1, NULL},
{token_identifier, "y", 1, NULL},
{token_equal, "==", 1, NULL},
{token_identifier, "true", 1, NULL},
{')', ")", 1, NULL},
{' ', " ", 1, NULL},
{'{', "{", 1, NULL},
{'\n', "\n", 1, NULL},
{'}', "}", 2, NULL},
{'\0', "", 2, NULL},
});
test_tokens("\"\" \"hello\"\n\"wor\\nld\" \"he\\\"lp\"",
(TokenTestSuite[]){
{token_string, "\"\"", 1, ""},
{' ', " ", 1, NULL},
{token_string, "\"hello\"", 1, "hello"},
{'\n', "\n", 1, NULL},
{token_string, "\"wor\\nld\"", 2, "wor\nld"},
{' ', " ", 2, NULL},
{token_string, "\"he\\\"lp\"", 2, "he\"lp"},
{'\0', "", 2, NULL},
});
test_tokens("/* comment */ /* comment\n */ code */",
(TokenTestSuite[]){
{' ', " ", 1, NULL}, /* comment */
{' ', " ", 1, NULL}, /* */
{' ', " ", 1, NULL}, /* comment\n */
{' ', " ", 2, NULL}, /* */
{token_identifier, "code", 2, NULL},
{' ', " ", 2, NULL},
{'*', "*", 2, NULL},
{'/', "/", 2, NULL},
{'\0', "", 2, NULL},
});
test_tokens("'a''b''\\\\''\\'''\\n'",
(TokenTestSuite[]){
{token_character, "'a'", 1, "a"},
{token_character, "'b'", 1, "b"},
{token_character, "'\\\\'", 1, "\\"},
{token_character, "'\\''", 1, "\'"},
{token_character, "'\\n'", 1, "\n"},
{'\0', "", 1, NULL},
});
}