From 2a232f8f42c0a7d5a7b648358a192c21865a55f6 Mon Sep 17 00:00:00 2001 From: Kai Stevenson Date: Sat, 10 Jun 2023 23:45:25 -0700 Subject: lexing works --- .gitignore | 6 +++ Makefile | 16 ++++++ lexer.c | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ lexer.h | 39 +++++++++++++++ operetta.c | 37 ++++++++++++++ operetta.h | 4 ++ parse.c | 8 +++ parse.h | 13 +++++ proposition.c | 0 proposition.h | 13 +++++ testfile | 2 + 11 files changed, 291 insertions(+) create mode 100644 .gitignore create mode 100644 Makefile create mode 100644 lexer.c create mode 100644 lexer.h create mode 100644 operetta.c create mode 100644 operetta.h create mode 100644 parse.c create mode 100644 parse.h create mode 100644 proposition.c create mode 100644 proposition.h create mode 100644 testfile diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c7137bd --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +*.swp +operetta +*.exe* +*.core +vgcore.* +*.dSYM/ diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0948a4e --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +CFLAGS=-I. -Wall -Wextra -Wpedantic -O3 -lm -Wcast-align +CFLAGS+= -Wshadow -Wstrict-prototypes -Wundef -Wpointer-arith +CFLAGS+= -Wunreachable-code -Wswitch-enum -Wformat=2 -g +PREFIX ?= /usr +BINDIR ?= ${PREFIX}/bin + +generate: + $(CC) -o operetta operetta.c proposition.c parse.c lexer.c $(CFLAGS) + +install: operetta + install operetta ${DESTDIR}${BINDIR} +clean: + rm precedent + +uninstall: + rm -f ${DESTDIR}${BINDIR}/operetta diff --git a/lexer.c b/lexer.c new file mode 100644 index 0000000..bff9a40 --- /dev/null +++ b/lexer.c @@ -0,0 +1,153 @@ +#include +#include +#include +#include "lexer.h" + +token_t init_token(tokenType_t type, void* value) { + token_t t; + t.type = type; + t.value = value; + return t; +} +linkList_t* init_linklist(void* value, linkList_t* next) { + linkList_t* ll = calloc(sizeof(linkList_t), 1); + ll->value = value; + ll->next = next; + return ll; +} +int advance_whitespace(char** linePointer) { + int64_t a = (int64_t)linePointer; + while (**linePointer == ' ' || **linePointer == ' ') { + (*linePointer)++; + } + return (int)((int64_t)linePointer - a); +} +linkList_t* lex_line(char* line) { + char** p = malloc(sizeof(char*)); + *p = line; + linkList_t* root = init_linklist(NULL, NULL); + linkList_t* ll = root; + while (1) { + token_t t = lex_first_token(p); + if (t.type == EOL) { + printf("eol\n"); + break; + } + if (t.type == ERR) { + exit(1); + } + if (ll->value != NULL) { + ll->next = init_linklist(NULL, NULL); + ll = ll->next; + } + token_t* tp = malloc(sizeof(token_t)); + printf("good\n"); + *tp = t; + ll->value = tp; + } + free(p); + return root; +} +token_t lex_first_token(char** content) { + int m = 5; + char* s = malloc(sizeof(char) * m); + int c = 0; + advance_whitespace(content); + while (**content != '\n') { + s[c] = **content; + s[c+1] = '\0'; + (*content)++; + printf("lexing: %c\n", s[c]); + /* check if we need to parse a string or an int */ + if (s[c] >= 65 && s[c] <= 90) { + free(s); + (*content)--; + return lex_first_string(content); + } + else if (s[c] >= 48 && s[c] <= 57) { + free(s); + (*content)--; + return lex_first_int(content); + } + /* otherwise, check to see if a symbol has been matched */ + if (strcmp(s, "(") == 0) { + free(s); + return init_token(OPEN_PAREN, NULL); + } + else if (strcmp(s, ")") == 0) { + free(s); + return init_token(CLOSE_PAREN, NULL); + } + else if (strcmp(s, "#") == 0) { + free(s); + return init_token(START_COMMENT, NULL); + } + else if (strcmp(s, "|") == 0) { + free(s); + return init_token(JUSTIFICATION, NULL); + } + else if (strcmp(s, "pr") == 0) { + free(s); + return init_token(PREMISE, NULL); + } + else if (strcmp(s, "as") == 0) { + free(s); + return init_token(ASSUMPTION, NULL); + } + else if (strcmp(s, "^") == 0) { + free(s); + return init_token(CONJUNCTION, NULL); + } + else if (strcmp(s, "v") == 0) { + free(s); + return init_token(DISJUNCTION, NULL); + } + else if (strcmp(s, "->") == 0) { + free(s); + return init_token(IMPLICATION, NULL); + } + else if (strcmp(s, "<-") == 0) { + free(s); + return init_token(BI_IMPLICATION, NULL); + } + else if (c <= m) { + printf("c: %d\n", c); + c++; + continue; + } + else { + free(s); + return init_token(ERR, NULL); + } + } + return init_token(EOL, NULL); +} +token_t lex_first_string(char** content) { + int m = 50; + char* s = malloc(sizeof(char) * m); + int c = 0; + advance_whitespace(content); + while (**content >= 65 && **content <= 90) { + s[c] = **content; + (*content)++; + c++; + } + s[c] = '\0'; + return init_token(STRING, s); +} +token_t lex_first_int(char** content) { + int m = 10; + char* s = malloc(sizeof(char) * m); + int c = 0; + advance_whitespace(content); + while (**content >= 48 && **content <= 57) { + s[c] = **content; + (*content)++; + c++; + } + s[c] = '\0'; + int* ip = malloc(sizeof(int)); + *ip = atoi(s); + free(s); + return init_token(INT, (void*)ip); +} diff --git a/lexer.h b/lexer.h new file mode 100644 index 0000000..f8dc046 --- /dev/null +++ b/lexer.h @@ -0,0 +1,39 @@ +#ifndef LEXER +#define LEXER +typedef enum TokenType { + ERR, + EOL, + STRING, + INT, + OPEN_PAREN, + CLOSE_PAREN, + START_COMMENT, + JUSTIFICATION, + PREMISE, + ASSUMPTION, + CONJUNCTION, + DISJUNCTION, + IMPLICATION, + BI_IMPLICATION, + EXPLOSION, + ELIMINATION, + INTRODUCTION, +} tokenType_t; + +typedef struct Token { + tokenType_t type; + void* value; +} token_t; +token_t init_token(tokenType_t type, void* value); +typedef struct LinkedList { + void* value; + struct LinkedList* next; +} linkList_t; + +linkList_t* init_linklist(void* value, linkList_t* next); +int advance_whitespace(char** linePointer); +linkList_t* lex_line(char* line); +token_t lex_first_token(char** content); +token_t lex_first_string(char** content); +token_t lex_first_int(char** content); +#endif diff --git a/operetta.c b/operetta.c new file mode 100644 index 0000000..5d71c0b --- /dev/null +++ b/operetta.c @@ -0,0 +1,37 @@ +#include +#include +#include "operetta.h" +#include "lexer.h" +#include "parse.h" +#include "proposition.h" + +int main(int argc, char** argv) { + /* read file */ + char* path = argv[1]; + char* content = read_file(path); + linkList_t* ll = lex_line(content); + linkList_t* l1 = ll; + while (1) { + token_t* t = (token_t*)l1->value; + printf("%d \n", t->type); + if (l1->next == NULL) { + break; + } + l1 = l1->next; + } + free(content); +} +char* read_file(char* path) { + FILE* file = fopen(path, "r"); + if (file == NULL) { + printf("file %s does not exist\n", path); + } + fseek(file, 0, SEEK_END); + unsigned long int length = ftell(file); + fseek(file, 0, SEEK_SET); + char* out = malloc((length + 1) * sizeof(char)); + fread(out, length, 1, file); + fclose(file); + out[length] = '\0'; + return out; +} diff --git a/operetta.h b/operetta.h new file mode 100644 index 0000000..6ae1578 --- /dev/null +++ b/operetta.h @@ -0,0 +1,4 @@ +#ifndef OPERETTA +#define OPERETTA +char* read_file(char* path); +#endif diff --git a/parse.c b/parse.c new file mode 100644 index 0000000..67ca02e --- /dev/null +++ b/parse.c @@ -0,0 +1,8 @@ +#include +#include "parse.h" +lineSet_t init_lineset(line_t* lines, int count) { + lineSet_t lineSet; + lineSet.lines = lines; + lineSet.count = count; + return lineSet; +} diff --git a/parse.h b/parse.h new file mode 100644 index 0000000..0bfe06f --- /dev/null +++ b/parse.h @@ -0,0 +1,13 @@ +#ifndef PARSE +#define PARSE +#include "proposition.h" +typedef struct Line { + prop_t proposition; + just_t justification; +} line_t; +typedef struct LineSet { + line_t* lines; + int count; +} lineSet_t; +lineSet_t init_lineset(line_t* lines, int count); +#endif diff --git a/proposition.c b/proposition.c new file mode 100644 index 0000000..e69de29 diff --git a/proposition.h b/proposition.h new file mode 100644 index 0000000..5ffb009 --- /dev/null +++ b/proposition.h @@ -0,0 +1,13 @@ +#ifndef PROPOSITION +#define PROPOSITION +#include "lexer.h" +typedef struct Proposition { + struct Proposition* propA; + struct Proposition* propB; + tokenType_t relation; + char isSimple; +} prop_t; +typedef struct Justification { + tokenType_t rule; +} just_t; +#endif diff --git a/testfile b/testfile new file mode 100644 index 0000000..1bfb915 --- /dev/null +++ b/testfile @@ -0,0 +1,2 @@ +QvP | pr +T^L | pr -- cgit v1.3.1