1
0
Fork 0

improve lexer

This commit is contained in:
Alex Kotov 2023-05-04 01:41:04 +04:00
parent e4004807fc
commit 97e2470e6b
Signed by: kotovalexarian
GPG key ID: 553C0EBBEB5D5F08
3 changed files with 73 additions and 20 deletions

49
enums.c
View file

@ -1,16 +1,53 @@
#include "enums.h" #include "enums.h"
#include <stdbool.h>
#include <stddef.h> #include <stddef.h>
const char *State_to_str(enum State state) const char *State_to_str(const enum State state)
{ {
switch (state) { switch (state) {
case STATE_INIT: return "STATE_INIT"; case STATE_INIT: return "STATE_INIT";
case STATE_WHITESPACE: return "STATE_WHITESPACE"; case STATE_WHITESPACE: return "STATE_WHITESPACE";
case STATE_OPEN: return "STATE_OPEN"; case STATE_OPEN: return "STATE_OPEN";
case STATE_CLOSE: return "STATE_CLOSE"; case STATE_CLOSE: return "STATE_CLOSE";
case STATE_ID: return "STATE_ID"; case STATE_ID: return "STATE_ID";
case STATE_NUM: return "STATE_NUM"; case STATE_NUM: return "STATE_NUM";
} }
return NULL; return NULL;
} }
const char *TokenType_to_str(const enum TokenType token_type)
{
switch (token_type) {
case TOKEN_OPEN: return "TOKEN_OPEN";
case TOKEN_CLOSE: return "TOKEN_CLOSE";
case TOKEN_ID: return "TOKEN_ID";
case TOKEN_NUM: return "TOKEN_NUM";
}
return NULL;
}
const char *Type_to_str(const enum Type type)
{
switch (type) {
case TYPE_PAIR: return "TYPE_PAIR";
case TYPE_ATOM: return "TYPE_ATOM";
case TYPE_STRING: return "TYPE_STRING";
case TYPE_NUMBER: return "TYPE_NUMBER";
}
return NULL;
}
bool
State_to_token_type(const enum State state, enum TokenType *const token_type)
{
switch (state) {
case STATE_OPEN: *token_type = STATE_OPEN; break;
case STATE_CLOSE: *token_type = STATE_CLOSE; break;
case STATE_ID: *token_type = STATE_ID; break;
case STATE_NUM: *token_type = STATE_NUM; break;
default: return false;
}
return true;
}

13
enums.h
View file

@ -1,6 +1,8 @@
#ifndef __ENUMS_H__ #ifndef __ENUMS_H__
#define __ENUMS_H__ #define __ENUMS_H__
#include <stdbool.h>
enum State { enum State {
STATE_INIT, STATE_INIT,
STATE_WHITESPACE, STATE_WHITESPACE,
@ -10,6 +12,13 @@ enum State {
STATE_NUM, STATE_NUM,
}; };
enum TokenType {
TOKEN_OPEN,
TOKEN_CLOSE,
TOKEN_ID,
TOKEN_NUM,
};
enum Type { enum Type {
TYPE_PAIR, TYPE_PAIR,
TYPE_ATOM, TYPE_ATOM,
@ -18,5 +27,9 @@ enum Type {
}; };
const char *State_to_str(enum State state); const char *State_to_str(enum State state);
const char *TokenType_to_str(enum TokenType token_type);
const char *Type_to_str(enum Type type);
bool State_to_token_type(enum State state, enum TokenType *token_type);
#endif #endif

31
main.c
View file

@ -10,7 +10,7 @@
struct Token { struct Token {
struct Token *next; struct Token *next;
enum State type; enum TokenType type;
char *val; char *val;
}; };
@ -40,7 +40,7 @@ static void error(const char *msg);
static void buffer_add(char chr); static void buffer_add(char chr);
static void buffer_clean(); static void buffer_clean();
static void token_add(enum State type, char *val); static void token_add(enum State state, char *val);
static void lex(char chr); static void lex(char chr);
/********** /**********
@ -49,7 +49,7 @@ static void lex(char chr);
static void shift_token(); static void shift_token();
static struct Object *prepare_object(enum Type type); static struct Object *prepare_object(enum Type type);
static void expect(enum State state); static void expect(enum TokenType token_type);
static struct Object *parse(); static struct Object *parse();
static struct Object *expr(); static struct Object *expr();
@ -78,7 +78,7 @@ int main()
printf("Tokens:\n"); printf("Tokens:\n");
for (const struct Token *token = tokens; token; token = token->next) { for (const struct Token *token = tokens; token; token = token->next) {
printf("%s:%s;\n", State_to_str(token->type), token->val); printf("%s:%s;\n", TokenType_to_str(token->type), token->val);
} }
struct Object *const program = parse(); struct Object *const program = parse();
@ -109,14 +109,17 @@ void buffer_clean()
buffer_index = 0; buffer_index = 0;
} }
void token_add(enum State type, char *val) void token_add(enum State state, char *val)
{ {
if (type == STATE_WHITESPACE) return; if (state == STATE_WHITESPACE) return;
enum TokenType token_type;
if (!State_to_token_type(state, &token_type)) error("invalid state");
struct Token *token = malloc(sizeof(struct Token)); struct Token *token = malloc(sizeof(struct Token));
assert(token); assert(token);
token->next = NULL; token->next = NULL;
token->type = type; token->type = token_type;
token->val = malloc(strlen(val) + 1); token->val = malloc(strlen(val) + 1);
assert(token->val); assert(token->val);
strcpy(token->val, val); strcpy(token->val, val);
@ -310,10 +313,10 @@ struct Object *prepare_object(const enum Type type)
return object; return object;
} }
void expect(const enum State state) void expect(const enum TokenType token_type)
{ {
if (!tokens) error("no tokens in expect"); if (!tokens) error("no tokens in expect");
if (tokens->type != state) error("no expected"); if (tokens->type != token_type) error("no expected");
shift_token(); shift_token();
} }
@ -327,15 +330,15 @@ struct Object *expr()
if (!tokens) error("no tokens"); if (!tokens) error("no tokens");
switch (tokens->type) { switch (tokens->type) {
case STATE_OPEN: return parens(); case TOKEN_OPEN: return parens();
case STATE_ID: case TOKEN_ID:
{ {
struct Object *const object = prepare_object(TYPE_ATOM); struct Object *const object = prepare_object(TYPE_ATOM);
object->s = tokens->val; object->s = tokens->val;
shift_token(); shift_token();
return object; return object;
} }
case STATE_NUM: case TOKEN_NUM:
{ {
struct Object *const object = prepare_object(TYPE_NUMBER); struct Object *const object = prepare_object(TYPE_NUMBER);
object->i = atoll(tokens->val); object->i = atoll(tokens->val);
@ -360,11 +363,11 @@ struct Object *parens_part()
{ {
struct Object *const object = prepare_object(TYPE_PAIR); struct Object *const object = prepare_object(TYPE_PAIR);
if (tokens && tokens->type != STATE_CLOSE) { if (tokens && tokens->type != TOKEN_CLOSE) {
object->a = expr(); object->a = expr();
} }
if (tokens && tokens->type != STATE_CLOSE) { if (tokens && tokens->type != TOKEN_CLOSE) {
object->b = parens_part(); object->b = parens_part();
} else { } else {
object->b = NULL; object->b = NULL;