Changed things.
This commit is contained in:
parent
2008bab1f7
commit
77f40cf3c5
@ -3,9 +3,13 @@
|
|||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
|
|
||||||
|
#define TOKENS_MAX 32
|
||||||
|
#define ZERO_CHAR 30
|
||||||
|
|
||||||
// What the lexer is currently looking at.
|
// What the lexer is currently looking at.
|
||||||
typedef enum {
|
typedef enum {
|
||||||
LEXER_STATE_CONFUSED, // Can't decide what it's looking at (also initial
|
LEXER_STATE_CONFUSED, // Can't decide what it's looking at (also initial
|
||||||
@ -30,6 +34,9 @@ Lexer* lexer_init(char* src);
|
|||||||
// Destroy a lexer.
|
// Destroy a lexer.
|
||||||
void lexer_destroy(Lexer* lexer);
|
void lexer_destroy(Lexer* lexer);
|
||||||
|
|
||||||
|
// Convert text to tokens.
|
||||||
|
void lexer_lex(Lexer* lexer);
|
||||||
|
|
||||||
// Lex in confused mode.
|
// Lex in confused mode.
|
||||||
void lexer_do_confused(Lexer* lexer);
|
void lexer_do_confused(Lexer* lexer);
|
||||||
|
|
||||||
@ -39,10 +46,15 @@ void lexer_do_number(Lexer* lexer);
|
|||||||
// Lex in call mode.
|
// Lex in call mode.
|
||||||
void lexer_do_call(Lexer* lexer);
|
void lexer_do_call(Lexer* lexer);
|
||||||
|
|
||||||
// Convert text to tokens.
|
// Increment the lexer's current character pointer.
|
||||||
void lexer_lex(Lexer* lexer);
|
void lexer_inc(Lexer* lexer);
|
||||||
|
|
||||||
// Add a token to the lexer.
|
// Add a token to the lexer.
|
||||||
void lexer_add_token(Lexer* lexer, Token* token);
|
void lexer_add_token(Lexer* lexer, Token* token);
|
||||||
|
|
||||||
|
// Print the contents of a lexer.
|
||||||
|
void lexer_print(Lexer* lexer);
|
||||||
|
|
||||||
|
static char* lexer_state_str(Lexer* lexer);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
#ifndef TOKEN_H
|
#ifndef TOKEN_H
|
||||||
#define TOKEN_H
|
#define TOKEN_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
TOKEN_TYPE_CALL,
|
TOKEN_TYPE_CALL,
|
||||||
TOKEN_TYPE_NUMBER,
|
TOKEN_TYPE_NUMBER,
|
||||||
@ -10,9 +13,13 @@ typedef enum {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
TokenType type; // The type of the Token.
|
TokenType type; // The type of the Token.
|
||||||
char* val; // The text of the Token.
|
char* val; // The text of the Token.
|
||||||
|
size_t len; // Length of the text of the Token.
|
||||||
} Token;
|
} Token;
|
||||||
|
|
||||||
Token* token_init(TokenType type, char* val);
|
Token* token_init(TokenType type, char* val);
|
||||||
void token_destroy(Token* token);
|
void token_destroy(Token* token);
|
||||||
|
|
||||||
|
void token_print(Token* token);
|
||||||
|
static char* token_type_str(Token* token);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
88
src/lexer.c
88
src/lexer.c
@ -1,6 +1,9 @@
|
|||||||
#include "include/lexer.h"
|
#include "include/lexer.h"
|
||||||
#include "include/token.h"
|
#include "include/token.h"
|
||||||
|
#include <assert.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
Lexer* lexer_init(char* src) {
|
Lexer* lexer_init(char* src) {
|
||||||
Lexer* lexer = malloc(sizeof(Lexer));
|
Lexer* lexer = malloc(sizeof(Lexer));
|
||||||
@ -9,7 +12,7 @@ Lexer* lexer_init(char* src) {
|
|||||||
lexer->srcl = strlen(src);
|
lexer->srcl = strlen(src);
|
||||||
lexer->cchar = lexer->src;
|
lexer->cchar = lexer->src;
|
||||||
|
|
||||||
lexer->tokens = NULL;
|
lexer->tokens = calloc(TOKENS_MAX, sizeof(Token));
|
||||||
lexer->ntokens = 0;
|
lexer->ntokens = 0;
|
||||||
lexer->state = LEXER_STATE_CONFUSED;
|
lexer->state = LEXER_STATE_CONFUSED;
|
||||||
|
|
||||||
@ -22,16 +25,6 @@ void lexer_destroy(Lexer* lexer) {
|
|||||||
for (int i = 0; i < lexer->ntokens; token_destroy(lexer->tokens[i++]));
|
for (int i = 0; i < lexer->ntokens; token_destroy(lexer->tokens[i++]));
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexer_do_confused(Lexer* lexer) {
|
|
||||||
int c = atoi(lexer->cchar);
|
|
||||||
|
|
||||||
if (c) lexer_add_token(lexer, token_init(TOKEN_TYPE_NUMBER, lexer->cchar));
|
|
||||||
else lexer_add_token(lexer, token_init(TOKEN_TYPE_CALL, lexer->cchar));
|
|
||||||
}
|
|
||||||
|
|
||||||
void lexer_do_number(Lexer* lexer) {}
|
|
||||||
void lexer_do_call(Lexer* lexer) {}
|
|
||||||
|
|
||||||
void lexer_lex(Lexer* lexer) {
|
void lexer_lex(Lexer* lexer) {
|
||||||
while (*lexer->cchar) {
|
while (*lexer->cchar) {
|
||||||
switch (lexer->state) {
|
switch (lexer->state) {
|
||||||
@ -43,7 +36,74 @@ void lexer_lex(Lexer* lexer) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lexer_add_token(Lexer* lexer, Token* token) {
|
void lexer_do_confused(Lexer* lexer) {
|
||||||
(void)reallocarray(lexer->tokens, lexer->ntokens++, sizeof(Token));
|
if (isdigit(*lexer->cchar)) lexer_do_number(lexer);
|
||||||
lexer->tokens[lexer->ntokens-1] = token;
|
else lexer_do_call(lexer);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lexer_do_number(Lexer* lexer) {
|
||||||
|
// Size of the number string.
|
||||||
|
size_t numsz;
|
||||||
|
|
||||||
|
// Where the number string starts.
|
||||||
|
char* start = lexer->cchar;
|
||||||
|
|
||||||
|
for (numsz = 0; *lexer->cchar && isdigit(*lexer->cchar); numsz++)
|
||||||
|
lexer_inc(lexer);
|
||||||
|
|
||||||
|
char* num = malloc(numsz + 1);
|
||||||
|
memcpy(num, start, numsz);
|
||||||
|
num[numsz] = '\0';
|
||||||
|
|
||||||
|
lexer_add_token(lexer, token_init(TOKEN_TYPE_NUMBER, num));
|
||||||
|
}
|
||||||
|
|
||||||
|
void lexer_do_call(Lexer* lexer) {
|
||||||
|
// Size of the call string.
|
||||||
|
size_t callsz;
|
||||||
|
|
||||||
|
// Where the call string starts.
|
||||||
|
char* start = lexer->cchar;
|
||||||
|
|
||||||
|
for(callsz = 0; *lexer->cchar && isalpha(*lexer->cchar); callsz++)
|
||||||
|
lexer_inc(lexer);
|
||||||
|
|
||||||
|
char* call = malloc(callsz + 1);
|
||||||
|
memcpy(call, start, callsz);
|
||||||
|
call[callsz] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
void lexer_inc(Lexer* lexer) {
|
||||||
|
lexer->cchar += sizeof(char);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lexer_add_token(Lexer* lexer, Token* token) {
|
||||||
|
assert(lexer->ntokens < TOKENS_MAX);
|
||||||
|
|
||||||
|
if (lexer->ntokens < TOKENS_MAX - 1) {
|
||||||
|
lexer->tokens[lexer->ntokens - 1] = token;
|
||||||
|
lexer->ntokens++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void lexer_print(Lexer* lexer) {
|
||||||
|
printf("Lexer @%p:\n", lexer);
|
||||||
|
printf("\tsrc: \"%s\"\n", lexer->src);
|
||||||
|
printf("\tsrcl: \"%ld\"\n", lexer->srcl);
|
||||||
|
printf("\tcchar: \"%s\"\n", lexer->cchar);
|
||||||
|
printf("\tntokens: %ld\n", lexer->ntokens);
|
||||||
|
printf("\ttokens: [START]\n");
|
||||||
|
for (int i = 0; i < lexer->ntokens; i++) token_print(lexer->tokens[i]);
|
||||||
|
printf("[END]\n");
|
||||||
|
printf("\tstate: %s\n", lexer_state_str(lexer));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* lexer_state_str(Lexer* lexer) {
|
||||||
|
switch (lexer->state) {
|
||||||
|
case LEXER_STATE_NUM: return "NUM";
|
||||||
|
case LEXER_STATE_CALL: return "CALL";
|
||||||
|
case LEXER_STATE_CONFUSED: return "CONFUSED";
|
||||||
|
default: return "???";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
11
src/main.c
11
src/main.c
@ -1,9 +1,14 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "include/util.h"
|
#include "include/util.h"
|
||||||
|
#include "include/lexer.h"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
printf("2 is even: %s\n", is_even(2) ? "true" : "false");
|
char* text = malloc(5);
|
||||||
printf("5 is even: %s\n", is_even(5) ? "true" : "false");
|
text = "a1b2";
|
||||||
return 0;
|
|
||||||
|
Lexer* lexer = lexer_init(text);
|
||||||
|
lexer_print(lexer);
|
||||||
|
lexer_lex(lexer);
|
||||||
|
lexer_print(lexer);
|
||||||
}
|
}
|
||||||
|
17
src/token.c
17
src/token.c
@ -1,5 +1,3 @@
|
|||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#include "include/token.h"
|
#include "include/token.h"
|
||||||
|
|
||||||
Token* token_init(TokenType type, char* val) {
|
Token* token_init(TokenType type, char* val) {
|
||||||
@ -15,3 +13,18 @@ void token_destroy(Token* t) {
|
|||||||
free(t->val);
|
free(t->val);
|
||||||
free(t);
|
free(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void token_print(Token* token) {
|
||||||
|
printf("Token @%p:\n", token);
|
||||||
|
printf("\ttype: %s\n", token_type_str(token));
|
||||||
|
printf("\tval: %s\n", token->val);
|
||||||
|
printf("\tlen: %ld\n", token->len);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* token_type_str(Token* token) {
|
||||||
|
switch (token->type) {
|
||||||
|
case TOKEN_TYPE_CALL: return "CALL";
|
||||||
|
case TOKEN_TYPE_NUMBER: return "NUMBER";
|
||||||
|
default: return "???";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -19,6 +19,6 @@ int test_token() {
|
|||||||
return UNITY_END();
|
return UNITY_END();
|
||||||
}
|
}
|
||||||
|
|
||||||
__attribute__((constructor)) void register_tests_token() {
|
__attribute__((constructor)) void register_token() {
|
||||||
register_test(test_token);
|
register_test(test_token);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user