From 92d9da14c2c4b801f3115a481b102c1c528d5e28 Mon Sep 17 00:00:00 2001 From: Jacob Signorovitch Date: Sat, 9 Nov 2024 10:27:03 -0500 Subject: [PATCH] Grammars are broken. --- README.md | 1 - src/grammar.y | 12 +++++++++++- src/include/ast.h | 6 +++--- src/include/lexer.h | 2 ++ src/lexer.c | 38 +++++++++++++++++++------------------- src/main.c | 17 +++++++++++++++-- 6 files changed, 50 insertions(+), 26 deletions(-) diff --git a/README.md b/README.md index 827a5d4..17517e4 100644 --- a/README.md +++ b/README.md @@ -35,4 +35,3 @@ Variables can be defined, with several attributes: > d:lazy = (1 + 1) // Interpreter will wait as long as possible before // evaluating. ``` - diff --git a/src/grammar.y b/src/grammar.y index 4025133..35c9db9 100644 --- a/src/grammar.y +++ b/src/grammar.y @@ -1,17 +1,27 @@ +%code requires { + #include "../../src/include/ast.h" +} + +%{ +#include "../../src/include/ast.h" +%} + %union { int intval; char* strval; + AST* ast; } %token NUM %token CALL %token PLUS +%type exp %% exp: NUM {} - | exp PLUS exp {} + | exp PLUS exp { $$ = ast_type_call_init("+", 2, [ast_type_num_init($1), ast_type_num_init(int val)]} ; %% diff --git a/src/include/ast.h b/src/include/ast.h index 02789c8..f1051c9 100644 --- a/src/include/ast.h +++ b/src/include/ast.h @@ -14,6 +14,9 @@ typedef struct { void* data; } AST; +AST* ast_init(ASTType type, void* data); +void ast_destroy(AST* ast); + typedef struct { int val; } ASTTypeNum; @@ -30,7 +33,4 @@ typedef struct { ASTTypeCall* ast_type_call_init(char* to, size_t argc, AST** argv); void ast_type_call_destroy(ASTTypeCall* call); -AST* ast_init(ASTType type, void* data); -void ast_destroy(AST* ast); - #endif diff --git a/src/include/lexer.h b/src/include/lexer.h index 7d5e97b..37c05f8 100644 --- a/src/include/lexer.h +++ b/src/include/lexer.h @@ -71,4 +71,6 @@ void lexerstate_print_raw(); // Create the input string. void lexer_set_global(const char* str); +int yylex(); + #endif diff --git a/src/lexer.c b/src/lexer.c index 0a20f69..14d1eab 100644 --- a/src/lexer.c +++ b/src/lexer.c @@ -8,6 +8,10 @@ #include "include/token.h" #include "include/util.h" +#include "../build/grammars/grammar.tab.h" + +extern YYSTYPE yylval; + Lexer* thelexer = NULL; void lexer_init(char* src) { @@ -138,36 +142,32 @@ void lexerstate_print_raw() { } else printf("%s", lexerstate_names[s]); } -#include "../build/grammars/grammar.tab.h" - -extern YYSTYPE yylval; - -int yylex(void) { +int yylex() { if (*thelexer->cchar == '\0') return YYEOF; - switch (*thelexer->cchar) { - case ' ': - case '\t': thelexer->cchar++; - } + // Skip all whitespace. + while (*thelexer->cchar == ' ' || *thelexer->cchar == '\t') + thelexer->cchar++; // Assign & consume current character. int c = *thelexer->cchar++; + // Check for NUM. + if (isdigit(c)) { + int value = c - '0'; + while (isdigit(*thelexer->cchar)) { + value = value * 10 + (*thelexer->cchar - '0'); // Accumulate value. + thelexer->cchar++; + } + yylval.intval = value; // Set the token value. + return NUM; + } + switch (c) { case '+': return PLUS; default: return CALL; } - if (isdigit(c)) { - int value = c - '0'; // Start with the first digit - while (isdigit(*thelexer->cchar)) { - value = value * 10 + (*thelexer->cchar - '0'); // Accumulate value - thelexer++; - } - yylval.intval = value; // Set the token value - return NUM; // Return the INTEGER token type - } - fprintf(stderr, "Unexpected character: %c\n", c); return 0; diff --git a/src/main.c b/src/main.c index 8c1a9d2..449436d 100644 --- a/src/main.c +++ b/src/main.c @@ -1,11 +1,19 @@ #include +#include "include/ast.h" #include "include/dstr.h" -#include "include/util.h" #include "include/lexer.h" +#include "include/util.h" + +#include "../build/grammars/grammar.tab.h" + +// Global Abstract Syntax Tree. +AST* root = NULL; + +extern int yyparse(); int main(int argc, char** argv) { - while(1) { + while (1) { Dstr* cline = dstr_init(); // The current line. printf("> "); fflush(stdout); @@ -20,6 +28,11 @@ int main(int argc, char** argv) { lexer_init(cline->buf); lexer_lex(); lexer_print(); + if (yyparse() == 0) { + printf("Parsed successfully!\n"); + } else { + printf("Parse error.\n"); + } lexer_destroy(); }