-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmdp_lexer.c
96 lines (73 loc) · 1.96 KB
/
mdp_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
#include "mdp_lexer.h"
Lexer* init_lexer(const char* src)
{
cat(&src, "\n");
Lexer* lexer = (Lexer*)malloc(sizeof(Lexer));
lexer->src = src;
lexer->src_size = strlen(src);
lexer->curr_pos = -1;
advance_lexer(lexer);
return lexer;
}
void free_lexer(Lexer* lexer)
{
free(lexer);
lexer->src = NULL;
lexer = NULL;
}
void advance_lexer(Lexer* lexer)
{
lexer->curr_pos++;
if(lexer->curr_pos >= lexer->src_size)
lexer->curr_char = '\0';
else
lexer->curr_char = lexer->src[lexer->curr_pos];
}
char peek_lexer(Lexer* lexer)
{
if(lexer->curr_pos + 1 >= lexer->src_size)
return '\0';
return lexer->src[lexer->curr_pos + 1];
}
void skip_whitespace(Lexer* lexer)
{
while(lexer->curr_char == ' ' || lexer->curr_char == '\t')
advance_lexer(lexer);
}
Token create_token(char* value, TokenType type)
{
Token token;
token.type = type;
token.value = value;
return token;
}
Token create_text_token(Lexer* lexer)
{
Token token;
int start_pos = lexer->curr_pos;
while(isalnum(peek_lexer(lexer)) || ispunct(peek_lexer(lexer)))
advance_lexer(lexer);
char* value = substr((char*)lexer->src, start_pos, lexer->curr_pos + 1);
token.type = TOKEN_TEXT;
token.value = value;
return token;
}
Token get_next_token(Lexer* lexer)
{
skip_whitespace(lexer);
Token token;
if(lexer->curr_char == '\n')
token = create_token("\n", TOKEN_NEWLINE);
else if(lexer->curr_char == '#')
token = create_token("#", TOKEN_HASHTAG);
else if(lexer->curr_char == '*')
token = create_token("*", TOKEN_ASTERISK);
else if(lexer->curr_char == '_')
token = create_token("_", TOKEN_UNDERSCORE);
else if(isalnum(lexer->curr_char) || ispunct(lexer->curr_char))
token = create_text_token(lexer);
else if(lexer->curr_char == '\0')
token = create_token(NULL, TOKEN_EOF);
advance_lexer(lexer);
return token;
}