-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathlexer.c
115 lines (105 loc) · 2.84 KB
/
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
#include <stdio.h>
#include <ctype.h>
#include "knicc.h"
Lexer *l;
char peek_char() {
return l->src[l->index];
}
char peek_more_char() {
return l->src[l->index + 1];
}
TokenType is_two_chars_op(char current, char peeked) {
if (current == '=' && peeked == '=') return tEq;
if (current == '<' && peeked == '=') return tLessEq;
if (current == '>' && peeked == '=') return tMoreEq;
if (current == '+' && peeked == '+') return tInc;
if (current == '-' && peeked == '-') return tDec;
if (current == '+' && peeked == '=') return tPlusEq;
if (current == '!' && peeked == '=') return tNotEq;
if (current == '&' && peeked == '&') return tAnd;
if (current == '|' && peeked == '|') return tOr;
return NOT_FOUND;
}
Token *lex() {
char literal[30];
TokenType type;
int i = 0;
char c = peek_char();
char peeked;
if (isdigit(c)) {
while(isdigit(c)) {
literal[i] = c;
i++;
l->index += 1;
c = l->src[l->index];
}
literal[i] = '\0';
type = tInt;
return new_token(literal, i, type);
} else if (isalpha(c)) {
while(isdigit(c) || isalpha(c) || c == '_') {
literal[i] = c;
i++;
l->index += 1;
c = peek_char();
}
literal[i] = '\0';
type = keyword(literal);
return new_token(literal, i, type);
} else if (special_char(c) != NOT_FOUND) {
peeked = peek_more_char(l);
type = is_two_chars_op(c, peeked);
if (type != NOT_FOUND) {
literal[0] = c;
literal[1] = peeked;
literal[2] = '\0';
l->index += 2;
return new_token(literal, 3, type);
}
literal[0] = c;
literal[1] = '\0';
type = special_char(c);
l->index += 1;
return new_token(literal, 2, type);
} else if (isblank(c)) {
l->index += 1;
return lex(l);
} else if (c == '"') {
l->index += 1;
c = peek_char();
while (c != '"') {
literal[i] = c;
i += 1;
l->index += 1;
c = peek_char();
}
literal[i] = '\0';
l->index += 1;
return new_token(literal, i, tString);
} else return new_token("", 1, _EOF);
}
void store_token(Token *t) {
l->tokens[l->length] = t;
l->length += 1;
}
Lexer *init_lexer() {
Lexer *l = malloc(sizeof(Lexer));
l->index = 0;
l->token_index = 0;
l->length = 0;
return l;
}
Token *get_token() {
if (l->length <= l->token_index) {
perror("get_token: LENGTH OVER");
}
Token *t = l->tokens[l->token_index];
l->token_index += 1;
return t;
}
Token *peek_token() {
if (l->length <= l->token_index) {
perror("peek_token: LENGTH OVER");
}
return l->tokens[l->token_index];
}