This repository was archived by the owner on Sep 17, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlexer.c
More file actions
80 lines (69 loc) · 2.62 KB
/
Copy pathlexer.c
File metadata and controls
80 lines (69 loc) · 2.62 KB
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
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tokens.h"
#include "lexer.h"
Tokens *lexer_get_tokens(Lexer *lexer, const char *text, int text_size) {
lexer->text = text; // If fgets, newline could be added to the end, but we are able to advance and ignore that
lexer->text_size = text_size;
lexer->index = 0;
lexer_advance(lexer);
memset(lexer->error, 0, sizeof(lexer->error));
Tokens *tokens = NULL;
while (lexer->current) {
if (strchr(WHITESPACE, lexer->current) != NULL) {
lexer_advance(lexer);
} else if (lexer->current == '.' || strchr(DIGITS, lexer->current) != NULL) {
append_tokens(&tokens, *lexer_get_number(lexer));
} else if (lexer->current == '+') {
lexer_advance(lexer);
append_tokens(&tokens, (Token) { PLUS, 0 });
} else if (lexer->current == '-') {
lexer_advance(lexer);
append_tokens(&tokens, (Token) { MINUS, 0 });
} else if (lexer->current == '*') {
lexer_advance(lexer);
if (lexer->current == '*') {
lexer_advance(lexer);
append_tokens(&tokens, (Token) { POWER, 0 });
} else
append_tokens(&tokens, (Token) { MULTIPLY, 0 });
} else if (lexer->current == '/') {
lexer_advance(lexer);
append_tokens(&tokens, (Token) { DIVIDE, 0 });
} else if (lexer->current == '(') {
lexer_advance(lexer);
append_tokens(&tokens, (Token) { LPAREN, 0 });
} else if (lexer->current == ')') {
lexer_advance(lexer);
append_tokens(&tokens, (Token) { RPAREN, 0 });
} else {
if (tokens != NULL) {
free_tokens(tokens);
tokens = NULL;
}
snprintf(lexer->error, sizeof(lexer->error), "Illegal character '%c'", lexer->current);
return tokens;
}
}
return tokens;
}
Token *lexer_get_number(Lexer *lexer) {
int decimal_point_count = 0;
int index = 0;
char number_str[lexer->text_size];
memset(number_str, 0, sizeof(number_str));
number_str[index++] = lexer->current;
lexer_advance(lexer);
while (lexer->current && (lexer->current == '.' || strchr(DIGITS, lexer->current) != NULL)) {
if (lexer->current == '.')
if (++decimal_point_count > 1)
break;
number_str[index++] = lexer->current;
lexer_advance(lexer);
}
return & (Token) { NUMBER, strtod(number_str, NULL) };
}
void lexer_advance(Lexer *lexer) {
lexer->current = lexer->text[lexer->index++];
}