Refactored the scanner and updated the Token struct to store the length of its lexeme to avoid malloc()ing new strings for every token.

This commit is contained in:
2022-02-10 17:17:33 +00:00
parent 2d84019e58
commit 7bdbb9f53a
3 changed files with 55 additions and 14 deletions
+18 -1
View File
@@ -1,3 +1,4 @@
#include "scanner.h"
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <sysexits.h> #include <sysexits.h>
@@ -19,10 +20,26 @@ int main(int argc, char** argv) {
} }
} }
void Print(TokenList* list) {
char lexeme[100];
for(int i = 0; i < list->size; i++) {
printf("[Line %d] ", list->tokens[i]->line);
for(int j = 0; j < list->tokens[i]->length; j++) {
printf("%c", list->tokens[i]->lexeme[j]);
}
printf("\n");
}
}
void RunFile(const char* path) { void RunFile(const char* path) {
printf("Running '%s'\n", path); printf("Running '%s'\n", path);
char* contents = GetFileContents(path); char* contents = GetFileContents(path);
//Tokenize(contents); TokenList* tokens = ScanTokens(contents);
Print(tokens);
DestroyTokenList(tokens);
free(contents);
} }
char* GetFileContents(const char* path) { char* GetFileContents(const char* path) {
+35 -12
View File
@@ -10,9 +10,9 @@ int current; //points to the character currently being considered.
int length; int length;
int line = 1; int line = 1;
char Advance(void); const char* Advance(void);
int IsAtend(void); int IsAtend(void);
void ScanToken(void); void ScanToken(TokenList*);
TokenList* CreateList(void); TokenList* CreateList(void);
TokenList* ScanTokens(const char* source) { TokenList* ScanTokens(const char* source) {
@@ -23,12 +23,15 @@ TokenList* ScanTokens(const char* source) {
if (length == 0) return NULL; if (length == 0) return NULL;
TokenList* tokens = CreateList();
while(!IsAtend()) { while(!IsAtend()) {
start = current; start = current;
ScanToken(); ScanToken(tokens);
} }
//Add EOF token and return list once that's set up. //Add EOF token and return list once that's set up.
return tokens;
} }
TokenList* CreateList() { TokenList* CreateList() {
@@ -57,7 +60,7 @@ void DestroyTokenList(TokenList* list) {
if (!list) return; if (!list) return;
for(int i = 0; i < list->size; i++) { for(int i = 0; i < list->size; i++) {
free(list->tokens[i]->lexeme); //free(list->tokens[i]->lexeme); This shouldn't be needed since the lexeme is a pointer into the source code.
free(list->tokens[i]); free(list->tokens[i]);
} }
@@ -65,7 +68,7 @@ void DestroyTokenList(TokenList* list) {
free(list); free(list);
} }
int AddTokenToList(TokenType type, char* lexeme, TokenList* tokens) { int AddTokenToList(TokenType type, const char* lexeme, int length, TokenList* tokens) {
if (!tokens) return 0; if (!tokens) return 0;
Token* token = calloc(1, sizeof(Token)); Token* token = calloc(1, sizeof(Token));
@@ -76,6 +79,7 @@ int AddTokenToList(TokenType type, char* lexeme, TokenList* tokens) {
token->lexeme = lexeme; token->lexeme = lexeme;
token->type = type; token->type = type;
token->length = length; //Set the length of the lexeme (which is just a pointer into the complete soure listing).
if ((tokens->size + 1) > tokens->capacity) { if ((tokens->size + 1) > tokens->capacity) {
void* new_ptr = realloc(tokens->tokens, sizeof(Token*) * tokens->capacity * 2);//calloc(tokens->capacity * 2, sizeof(Token*)); void* new_ptr = realloc(tokens->tokens, sizeof(Token*) * tokens->capacity * 2);//calloc(tokens->capacity * 2, sizeof(Token*));
@@ -95,28 +99,47 @@ int AddTokenToList(TokenType type, char* lexeme, TokenList* tokens) {
return 1; return 1;
} }
void ScanToken() { void ScanToken(TokenList* tokens) {
char c = Advance(); const char* c = Advance();
switch (c) { switch (*c) {
case '(': case '(':
AddTokenToList(LParen, c, 1, tokens);
break;
case ')': case ')':
AddTokenToList(RParen, c, 1, tokens);
break;
case '{': case '{':
AddTokenToList(LBrace, c, 1, tokens);
break;
case '}': case '}':
AddTokenToList(RBrace, c, 1, tokens);
break;
case ',': case ',':
AddTokenToList(Comma, c, 1, tokens);
break;
case '.': case '.':
AddTokenToList(Dot, c, 1, tokens);
break;
case '-': case '-':
AddTokenToList(Minus, c, 1, tokens);
break;
case '+': case '+':
AddTokenToList(Plus, c, 1, tokens);
break;
case ';': case ';':
AddTokenToList(Semicolon, c, 1, tokens);
break;
case '*': case '*':
break; AddTokenToList(Star, c, 1, tokens);
break;
} }
} }
int IsAtEnd() { int IsAtend() {
return current >= length; return current >= length;
} }
char Advance() { const char* Advance() {
return source_code[current++]; return &source_code[current++];
} }
+2 -1
View File
@@ -31,8 +31,9 @@ typedef enum {
typedef struct { typedef struct {
TokenType type; TokenType type;
char* lexeme; const char* lexeme;
int line; int line;
int length;
} Token; } Token;
typedef struct { typedef struct {