Grammars are broken.
This commit is contained in:
parent
b43fd46260
commit
92d9da14c2
@ -35,4 +35,3 @@ Variables can be defined, with several attributes:
|
|||||||
> d:lazy = (1 + 1) // Interpreter will wait as long as possible before
|
> d:lazy = (1 + 1) // Interpreter will wait as long as possible before
|
||||||
// evaluating.
|
// evaluating.
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -1,17 +1,27 @@
|
|||||||
|
%code requires {
|
||||||
|
#include "../../src/include/ast.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
%{
|
||||||
|
#include "../../src/include/ast.h"
|
||||||
|
%}
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
int intval;
|
int intval;
|
||||||
char* strval;
|
char* strval;
|
||||||
|
AST* ast;
|
||||||
}
|
}
|
||||||
|
|
||||||
%token <intval> NUM
|
%token <intval> NUM
|
||||||
%token <strval> CALL
|
%token <strval> CALL
|
||||||
%token PLUS
|
%token PLUS
|
||||||
|
%type <ast> exp
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
exp:
|
exp:
|
||||||
NUM {}
|
NUM {}
|
||||||
| exp PLUS exp {}
|
| exp PLUS exp { $$ = ast_type_call_init("+", 2, [ast_type_num_init($1), ast_type_num_init(int val)]}
|
||||||
;
|
;
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
@ -14,6 +14,9 @@ typedef struct {
|
|||||||
void* data;
|
void* data;
|
||||||
} AST;
|
} AST;
|
||||||
|
|
||||||
|
AST* ast_init(ASTType type, void* data);
|
||||||
|
void ast_destroy(AST* ast);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int val;
|
int val;
|
||||||
} ASTTypeNum;
|
} ASTTypeNum;
|
||||||
@ -30,7 +33,4 @@ typedef struct {
|
|||||||
ASTTypeCall* ast_type_call_init(char* to, size_t argc, AST** argv);
|
ASTTypeCall* ast_type_call_init(char* to, size_t argc, AST** argv);
|
||||||
void ast_type_call_destroy(ASTTypeCall* call);
|
void ast_type_call_destroy(ASTTypeCall* call);
|
||||||
|
|
||||||
AST* ast_init(ASTType type, void* data);
|
|
||||||
void ast_destroy(AST* ast);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -71,4 +71,6 @@ void lexerstate_print_raw();
|
|||||||
// Create the input string.
|
// Create the input string.
|
||||||
void lexer_set_global(const char* str);
|
void lexer_set_global(const char* str);
|
||||||
|
|
||||||
|
int yylex();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
38
src/lexer.c
38
src/lexer.c
@ -8,6 +8,10 @@
|
|||||||
#include "include/token.h"
|
#include "include/token.h"
|
||||||
#include "include/util.h"
|
#include "include/util.h"
|
||||||
|
|
||||||
|
#include "../build/grammars/grammar.tab.h"
|
||||||
|
|
||||||
|
extern YYSTYPE yylval;
|
||||||
|
|
||||||
Lexer* thelexer = NULL;
|
Lexer* thelexer = NULL;
|
||||||
|
|
||||||
void lexer_init(char* src) {
|
void lexer_init(char* src) {
|
||||||
@ -138,36 +142,32 @@ void lexerstate_print_raw() {
|
|||||||
} else printf("%s", lexerstate_names[s]);
|
} else printf("%s", lexerstate_names[s]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#include "../build/grammars/grammar.tab.h"
|
int yylex() {
|
||||||
|
|
||||||
extern YYSTYPE yylval;
|
|
||||||
|
|
||||||
int yylex(void) {
|
|
||||||
if (*thelexer->cchar == '\0') return YYEOF;
|
if (*thelexer->cchar == '\0') return YYEOF;
|
||||||
|
|
||||||
switch (*thelexer->cchar) {
|
// Skip all whitespace.
|
||||||
case ' ':
|
while (*thelexer->cchar == ' ' || *thelexer->cchar == '\t')
|
||||||
case '\t': thelexer->cchar++;
|
thelexer->cchar++;
|
||||||
}
|
|
||||||
|
|
||||||
// Assign & consume current character.
|
// Assign & consume current character.
|
||||||
int c = *thelexer->cchar++;
|
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) {
|
switch (c) {
|
||||||
case '+': return PLUS;
|
case '+': return PLUS;
|
||||||
default: return CALL;
|
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);
|
fprintf(stderr, "Unexpected character: %c\n", c);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
15
src/main.c
15
src/main.c
@ -1,8 +1,16 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "include/ast.h"
|
||||||
#include "include/dstr.h"
|
#include "include/dstr.h"
|
||||||
#include "include/util.h"
|
|
||||||
#include "include/lexer.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) {
|
int main(int argc, char** argv) {
|
||||||
while (1) {
|
while (1) {
|
||||||
@ -20,6 +28,11 @@ int main(int argc, char** argv) {
|
|||||||
lexer_init(cline->buf);
|
lexer_init(cline->buf);
|
||||||
lexer_lex();
|
lexer_lex();
|
||||||
lexer_print();
|
lexer_print();
|
||||||
|
if (yyparse() == 0) {
|
||||||
|
printf("Parsed successfully!\n");
|
||||||
|
} else {
|
||||||
|
printf("Parse error.\n");
|
||||||
|
}
|
||||||
lexer_destroy();
|
lexer_destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user