add flex lexer
This commit is contained in:
5
.gitignore
vendored
5
.gitignore
vendored
@@ -50,3 +50,8 @@ modules.order
|
||||
Module.symvers
|
||||
Mkfile.old
|
||||
dkms.conf
|
||||
|
||||
bin
|
||||
|
||||
*.yy.c
|
||||
*.yy.h
|
||||
20
Makefile
20
Makefile
@@ -1,3 +1,19 @@
|
||||
build:
|
||||
LEXER_SRC = src/lexer/lex.l
|
||||
LEXER_C = src/lexer/lex.yy.c
|
||||
LEXER_H = src/lexer/lex.yy.h
|
||||
|
||||
CFILES = $(shell find src -name '*.c')
|
||||
BINARY = bin/cargon
|
||||
|
||||
all: $(BINARY)
|
||||
|
||||
$(LEXER_C) $(LEXER_H): $(LEXER_SRC)
|
||||
flex --header-file=$(LEXER_H) -o $(LEXER_C) $(LEXER_SRC)
|
||||
|
||||
$(BINARY): $(CFILES) $(LEXER_C) $(LEXER_H)
|
||||
mkdir -p bin
|
||||
gcc -O3 -o bin/cargon $(shell find src -name '*.c') -lm -Wall -Wextra -Werror
|
||||
gcc -O3 -o $(BINARY) $(CFILES) -lm -Wall -Wextra -Wno-unused-function
|
||||
|
||||
clean:
|
||||
rm -rf bin
|
||||
rm -f $(LEXER_C) $(LEXER_H)
|
||||
BIN
bin/cargon
BIN
bin/cargon
Binary file not shown.
47
src/lexer/lex.l
Normal file
47
src/lexer/lex.l
Normal file
@@ -0,0 +1,47 @@
|
||||
%{
|
||||
#include "token.h"
|
||||
int current_line = 1;
|
||||
int current_column = 1;
|
||||
|
||||
int yywrap() {
|
||||
return 1;
|
||||
}
|
||||
%}
|
||||
|
||||
%%
|
||||
|
||||
\"(\\[a-z\"'`]|[^\\"])*\" {
|
||||
add_token(TOKEN_STRING, yytext, current_line, current_column);
|
||||
current_column += yyleng;
|
||||
}
|
||||
|
||||
[0-9]+ {
|
||||
add_token(TOKEN_NUMBER, yytext, current_line, current_column);
|
||||
current_column += yyleng;
|
||||
}
|
||||
|
||||
[a-zA-Z_][a-zA-Z0-9_]* {
|
||||
add_token(TOKEN_IDENTIFIER, yytext, current_line, current_column);
|
||||
current_column += yyleng;
|
||||
}
|
||||
|
||||
"." {
|
||||
add_token(TOKEN_DOT, yytext, current_line, current_column);
|
||||
current_column += yyleng;
|
||||
}
|
||||
|
||||
\n {
|
||||
add_token(TOKEN_NEW_LINE, yytext, current_line, current_column);
|
||||
current_line++;
|
||||
current_column = 1;
|
||||
}
|
||||
|
||||
[ \t]+ {
|
||||
current_column += yyleng; // Advance column for whitespace
|
||||
}
|
||||
|
||||
. {
|
||||
fprintf(stderr, "Error: Unexpected character '%c' at line %d\n", *yytext, yylineno);
|
||||
exit(1);
|
||||
}
|
||||
%%
|
||||
20
src/lexer/lexer.c
Normal file
20
src/lexer/lexer.c
Normal file
@@ -0,0 +1,20 @@
|
||||
#include "lex.yy.h"
|
||||
#include "token.h"
|
||||
|
||||
int lexer() {
|
||||
const char *input = "term.log\n";
|
||||
|
||||
|
||||
|
||||
void* buffer = yy_scan_string(input);
|
||||
yy_switch_to_buffer(buffer);
|
||||
yylex(); // This fills the token array
|
||||
yy_delete_buffer(buffer);
|
||||
|
||||
for (int i = 0; i < token_count; i++) {
|
||||
printf("Token(type=%d, value='%s')\n", tokens[i].type, tokens[i].value);
|
||||
}
|
||||
|
||||
free_tokens();
|
||||
return 0;
|
||||
}
|
||||
1
src/lexer/lexer.h
Normal file
1
src/lexer/lexer.h
Normal file
@@ -0,0 +1 @@
|
||||
int lexer();
|
||||
35
src/lexer/token.c
Normal file
35
src/lexer/token.c
Normal file
@@ -0,0 +1,35 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "token.h"
|
||||
|
||||
#define INITIAL_CAPACITY 64
|
||||
|
||||
Token* tokens = NULL;
|
||||
int token_count = 0;
|
||||
static int token_capacity = 0;
|
||||
|
||||
void add_token(TokenType type, const char* value, int line, int column) {
|
||||
if (tokens == NULL) {
|
||||
token_capacity = INITIAL_CAPACITY;
|
||||
tokens = malloc(sizeof(Token) * token_capacity);
|
||||
} else if (token_count >= token_capacity) {
|
||||
token_capacity *= 2;
|
||||
tokens = realloc(tokens, sizeof(Token) * token_capacity);
|
||||
}
|
||||
|
||||
tokens[token_count].type = type;
|
||||
tokens[token_count].value = strdup(value);
|
||||
tokens[token_count].line = line;
|
||||
tokens[token_count].column = column;
|
||||
token_count++;
|
||||
}
|
||||
|
||||
void free_tokens() {
|
||||
for (int i = 0; i < token_count; ++i) {
|
||||
free(tokens[i].value);
|
||||
}
|
||||
free(tokens);
|
||||
tokens = NULL;
|
||||
token_count = 0;
|
||||
token_capacity = 0;
|
||||
}
|
||||
29
src/lexer/token.h
Normal file
29
src/lexer/token.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef TOKEN_H
|
||||
#define TOKEN_H
|
||||
|
||||
typedef enum {
|
||||
TOKEN_STRING,
|
||||
TOKEN_NUMBER,
|
||||
TOKEN_IDENTIFIER,
|
||||
TOKEN_KEYWORD,
|
||||
TOKEN_DOT,
|
||||
TOKEN_NEW_LINE,
|
||||
} TokenType;
|
||||
|
||||
typedef struct {
|
||||
TokenType type;
|
||||
char* value;
|
||||
int line;
|
||||
int column;
|
||||
} Token;
|
||||
|
||||
extern int token_count;
|
||||
|
||||
extern Token* tokens;
|
||||
|
||||
|
||||
void add_token(TokenType type, const char* value, int line, int column);
|
||||
|
||||
void free_tokens();
|
||||
|
||||
#endif
|
||||
13
src/main.c
13
src/main.c
@@ -4,6 +4,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "lexer/lexer.h"
|
||||
|
||||
void initialize() {
|
||||
initNumber();
|
||||
@@ -14,16 +15,6 @@ void cleanup() {
|
||||
}
|
||||
|
||||
int main() {
|
||||
initialize();
|
||||
char *code = "1.2e20";
|
||||
struct number mynum = translateNumber(code);
|
||||
if (mynum.denominator == 0) {
|
||||
printf("Invalid number\n");
|
||||
return 1;
|
||||
}
|
||||
double f = 1.0 * mynum.numerator / mynum.denominator;
|
||||
printf("Numerator: %ld\n", mynum.numerator);
|
||||
printf("Denominator: %lu\n", mynum.denominator);
|
||||
printf("Float: %lf\n", f);
|
||||
lexer();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -49,19 +49,19 @@ void doubleToFraction(double num, int64_t *numerator, uint64_t *denominator) {
|
||||
int currentSign = (num < 0) ? -1 : 1;
|
||||
num = fabs(num);
|
||||
|
||||
double tolerance = 1.0e-10;
|
||||
double h1 = 1, h2 = 0, k1 = 0, k2 = 1;
|
||||
double b = num;
|
||||
long double tolerance = 1.0e-10;
|
||||
long double h1 = 1, h2 = 0, k1 = 0, k2 = 1;
|
||||
long double b = num;
|
||||
do {
|
||||
double a = floor(b);
|
||||
double aux = h1;
|
||||
long double a = floor(b);
|
||||
long double aux = h1;
|
||||
h1 = a * h1 + h2;
|
||||
h2 = aux;
|
||||
aux = k1;
|
||||
k1 = a * k1 + k2;
|
||||
k2 = aux;
|
||||
b = 1 / (b - a);
|
||||
} while (fabs(num - h1 / k1) > num * tolerance);
|
||||
} while (fabsl(num - h1 / k1) > num * tolerance);
|
||||
|
||||
*numerator = (int64_t)(h1 * currentSign);
|
||||
*denominator = (uint64_t)k1;
|
||||
|
||||
Reference in New Issue
Block a user