init: it compiles, but idk what is happening
This commit is contained in:
commit
dfd72482ac
8
.gitignore
vendored
Normal file
8
.gitignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
|
||||||
|
a.out
|
||||||
|
|
||||||
|
# File generated by flex and bison
|
||||||
|
parser.c
|
||||||
|
scanner.c
|
||||||
|
token.h
|
||||||
|
|
9
Makefile
Normal file
9
Makefile
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
|
||||||
|
all: flex bison
|
||||||
|
gcc expr.c parser.c scanner.c main.c
|
||||||
|
|
||||||
|
bison:
|
||||||
|
bison --defines=token.h --output=parser.c parser.bison
|
||||||
|
|
||||||
|
flex: bison
|
||||||
|
flex -o scanner.c scanner.flex
|
100
expr.c
Normal file
100
expr.c
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
|
||||||
|
#include "expr.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
struct decl* decl_create(
|
||||||
|
char* name,
|
||||||
|
struct type* type,
|
||||||
|
struct expr* value,
|
||||||
|
struct stmt* code,
|
||||||
|
struct decl* next)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct decl* d = malloc(sizeof(*d));
|
||||||
|
d->name = name;
|
||||||
|
d->value = value;
|
||||||
|
d->code = code;
|
||||||
|
d->next = next;
|
||||||
|
return d;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stmt* stmt_create(
|
||||||
|
stmt_t kind,
|
||||||
|
struct decl* decl, struct expr* init_expr,
|
||||||
|
struct expr* expr, struct expr* next_expr,
|
||||||
|
struct stmt* body, struct stmt* else_body,
|
||||||
|
struct stmt* next)
|
||||||
|
{
|
||||||
|
|
||||||
|
struct stmt* s = malloc(sizeof(*s));
|
||||||
|
s->decl = decl;
|
||||||
|
s->expr = expr;
|
||||||
|
s->next = next;
|
||||||
|
s->body = body;
|
||||||
|
s->else_body = else_body;
|
||||||
|
s->init_expr = init_expr;
|
||||||
|
s->next_expr = next_expr;
|
||||||
|
s->kind = kind;
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct expr* expr_create(expr_t kind, struct expr* left, struct expr* right)
|
||||||
|
{
|
||||||
|
struct expr* e = malloc(sizeof(*e));
|
||||||
|
e->kind = kind;
|
||||||
|
e->left = left;
|
||||||
|
e->right = right;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct expr* expr_create_name(const char* name)
|
||||||
|
{
|
||||||
|
struct expr* e = malloc(sizeof(*e));
|
||||||
|
e->kind = EXPR_NAME;
|
||||||
|
e->name = name;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct expr* expr_create_integer_literal(int i)
|
||||||
|
{
|
||||||
|
struct expr* e = malloc(sizeof(*e));
|
||||||
|
e->kind = EXPR_INTEGER_LITERAL;
|
||||||
|
e->integer_value = i;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct expr* expr_create_boolean_literal(int b)
|
||||||
|
{
|
||||||
|
struct expr* e = malloc(sizeof(*e));
|
||||||
|
e->kind = EXPR_BOOLEAN_LITERAL;
|
||||||
|
// FIXME: Check if it is 0 or 1?
|
||||||
|
e->integer_value = b;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct expr* expr_create_char_literal(char c)
|
||||||
|
{
|
||||||
|
struct expr* e = malloc(sizeof(*e));
|
||||||
|
e->kind = EXPR_CHAR_LITERAL;
|
||||||
|
e->integer_value = c; // this limits us to ASCII?
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct expr* expr_create_string_literal(const char* s)
|
||||||
|
{
|
||||||
|
struct expr* e = malloc(sizeof(*e));
|
||||||
|
e->kind = EXPR_STRING_LITERAL;
|
||||||
|
e->string_literal = s;
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct type* create_type(type_t kind, struct type* subtybe, struct param_list* param_list)
|
||||||
|
{
|
||||||
|
struct type* t = malloc(sizeof(*t));
|
||||||
|
t->kind = kind;
|
||||||
|
t->subtype = subtybe;
|
||||||
|
t->params = param_list;
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
89
expr.h
Normal file
89
expr.h
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
|
||||||
|
|
||||||
|
#ifndef PARSER_H
|
||||||
|
#define PARSER_H
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
STMT_DECL,
|
||||||
|
STMT_EXPR,
|
||||||
|
STMT_IF_ELSE,
|
||||||
|
STMT_FOR,
|
||||||
|
STMT_PRINT,
|
||||||
|
STMT_RETURN,
|
||||||
|
STMT_BLOCK
|
||||||
|
} stmt_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
EXPR_ADD,
|
||||||
|
EXPR_SUB,
|
||||||
|
EXPR_MUL,
|
||||||
|
EXPR_DIV,
|
||||||
|
EXPR_GT,
|
||||||
|
EXPR_LT,
|
||||||
|
EXPR_EQ,
|
||||||
|
EXPR_NOT,
|
||||||
|
EXPR_NAME,
|
||||||
|
EXPR_INTEGER_LITERAL,
|
||||||
|
EXPR_STRING_LITERAL,
|
||||||
|
EXPR_BOOLEAN_LITERAL,
|
||||||
|
EXPR_CHAR_LITERAL,
|
||||||
|
EXPR_CALL,
|
||||||
|
EXPR_ARG,
|
||||||
|
EXPR_SUBSCRIPT
|
||||||
|
} expr_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
TYPE_VOID,
|
||||||
|
TYPE_BOOLEAN,
|
||||||
|
TYPE_CHARACTER,
|
||||||
|
TYPE_INTEGER,
|
||||||
|
TYPE_STRING,
|
||||||
|
TYPE_ARRAY,
|
||||||
|
TYPE_FUNCTION
|
||||||
|
} type_t;
|
||||||
|
|
||||||
|
struct type {
|
||||||
|
type_t kind;
|
||||||
|
struct type* subtype;
|
||||||
|
struct param_list* params;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct param_list {
|
||||||
|
char* name;
|
||||||
|
struct type* type;
|
||||||
|
struct param_list* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct expr {
|
||||||
|
expr_t kind;
|
||||||
|
struct expr* left;
|
||||||
|
struct expr* right;
|
||||||
|
|
||||||
|
const char* name;
|
||||||
|
int integer_value;
|
||||||
|
const char* string_literal;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct stmt {
|
||||||
|
stmt_t kind;
|
||||||
|
struct decl* decl;
|
||||||
|
struct expr* init_expr;
|
||||||
|
struct expr* expr;
|
||||||
|
struct expr* next_expr;
|
||||||
|
struct stmt* body;
|
||||||
|
struct stmt* else_body;
|
||||||
|
struct stmt* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct decl {
|
||||||
|
char* name;
|
||||||
|
struct type* type;
|
||||||
|
struct expr* value;
|
||||||
|
struct stmt* code;
|
||||||
|
struct decl* next;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct expr* expr_create(expr_t kind, struct expr* left, struct expr* right);
|
||||||
|
|
||||||
|
|
||||||
|
#endif // PARSER_H
|
35
main.c
Normal file
35
main.c
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
/* Flex */
|
||||||
|
// extern FILE *yyin;
|
||||||
|
// extern int yylex();
|
||||||
|
// extern char* yytext;
|
||||||
|
|
||||||
|
/* Bison */
|
||||||
|
extern int yyparse();
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
if (yyparse()) {
|
||||||
|
printf("Parse successful!\n");
|
||||||
|
} else {
|
||||||
|
printf("Parse failed!\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// yyin = fopen("program.c", "r");
|
||||||
|
// if (!yyin) {
|
||||||
|
// printf("Could not open source file!\n");
|
||||||
|
// return 1;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// while (1) {
|
||||||
|
// enum yytokentype t = yylex();
|
||||||
|
// if (t == YYEOF) break;
|
||||||
|
// printf("token: %d text: %s\n", t, yytext);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
|
105
parser.bison
Normal file
105
parser.bison
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
%{
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "expr.h"
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
struct decl* parser_result = 0;
|
||||||
|
|
||||||
|
extern int yylex();
|
||||||
|
extern char* yytext;
|
||||||
|
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
%token TOKEN_INT
|
||||||
|
%token TOKEN_PLUS
|
||||||
|
%token TOKEN_MINUS
|
||||||
|
%token TOKEN_MUL
|
||||||
|
%token TOKEN_DIV
|
||||||
|
%token TOKEN_LPAREN
|
||||||
|
%token TOKEN_RPAREN
|
||||||
|
%token TOKEN_RBRACE
|
||||||
|
%token TOKEN_LBRACE
|
||||||
|
%token TOKEN_IF
|
||||||
|
%token TOKEN_SEMI
|
||||||
|
%token TOKEN_ERROR
|
||||||
|
%token TOKEN_COLON
|
||||||
|
%token TOKEN_ASSIGN
|
||||||
|
%token TOKEN_VOID
|
||||||
|
%token TOKEN_WHILE
|
||||||
|
%token TOKEN_IDENT
|
||||||
|
%token TOKEN_NUMBER
|
||||||
|
|
||||||
|
%union {
|
||||||
|
|
||||||
|
struct decl* decl;
|
||||||
|
struct stmt* stmt;
|
||||||
|
struct expr* expr;
|
||||||
|
struct type* type;
|
||||||
|
|
||||||
|
char* name;
|
||||||
|
}
|
||||||
|
|
||||||
|
%type <decl> program decl_list decl
|
||||||
|
%type <stmt> stmt_list stmt
|
||||||
|
%type <expr> expr factor term
|
||||||
|
%type <type> type
|
||||||
|
%type <name> name
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
program : decl_list { parser_result = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
decl : name TOKEN_COLON type TOKEN_SEMI
|
||||||
|
{ $$ = decl_create($1,$3,0,0,0); }
|
||||||
|
| name TOKEN_COLON type TOKEN_ASSIGN expr TOKEN_SEMI
|
||||||
|
{ $$ = decl_create($1,$3,$5,0,0); }
|
||||||
|
;
|
||||||
|
|
||||||
|
decl_list : decl decl_list { $$ = $1; $1->next = $2; }
|
||||||
|
| { $$ = 0; }
|
||||||
|
;
|
||||||
|
|
||||||
|
stmt : TOKEN_IF TOKEN_LPAREN expr TOKEN_RPAREN stmt
|
||||||
|
{ $$ = stmt_create(STMT_IF_ELSE,0,0,$3,0,$5,0,0); }
|
||||||
|
| TOKEN_LBRACE stmt_list TOKEN_RBRACE
|
||||||
|
{ $$ = stmt_create(STMT_BLOCK,0,0,0,0,$2,0,0); }
|
||||||
|
;
|
||||||
|
|
||||||
|
stmt_list : stmt stmt_list { $$ = $1; $1->next $2; }
|
||||||
|
| { $$ = 0; }
|
||||||
|
;
|
||||||
|
|
||||||
|
expr : expr TOKEN_PLUS term { $$ = expr_create(EXPR_ADD,$1,$3); }
|
||||||
|
| expr TOKEN_MINUS term { $$ = expr_create(EXPR_SUB,$1,$3); }
|
||||||
|
| term { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
term : term TOKEN_MUL factor { $$ = expr_create(EXPR_MUL,$1,$3); }
|
||||||
|
| term TOKEN_DIV factor { $$ = expr_create(EXPR_DIV,$1,$3); }
|
||||||
|
| factor { $$ = $1; }
|
||||||
|
;
|
||||||
|
|
||||||
|
factor : TOKEN_MINUS factor
|
||||||
|
{ $$ = expr_create(EXPR_SUB, expr_create_integer_literal(0), $2); }
|
||||||
|
| TOKEN_LPAREN expr TOKEN_RPAREN { $$ = $2; }
|
||||||
|
| TOKEN_INT { $$ = expr_create_integer_literal(atoi(yytext)); }
|
||||||
|
;
|
||||||
|
|
||||||
|
type : TOKEN_INT { $$ = create_type(TYPE_INTEGER,0,0); }
|
||||||
|
| TOKEN_VOID { $$ = create_type(TYPE_VOID,0,0); }
|
||||||
|
;
|
||||||
|
|
||||||
|
name : TOKEN_IDENT { $$ = yytext; }
|
||||||
|
;
|
||||||
|
|
||||||
|
%%
|
||||||
|
|
||||||
|
int yyerror(char* s)
|
||||||
|
{
|
||||||
|
printf("parse error: %s\n", s);
|
||||||
|
return 1;
|
||||||
|
}
|
30
scanner.flex
Normal file
30
scanner.flex
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
%{
|
||||||
|
|
||||||
|
#include "token.h"
|
||||||
|
|
||||||
|
%}
|
||||||
|
|
||||||
|
DIGIT [0-9]
|
||||||
|
LETTER [a-zA-Z]
|
||||||
|
|
||||||
|
%%
|
||||||
|
(" "|\t|\n) /* skip whitespce */
|
||||||
|
\+ { return TOKEN_PLUS; }
|
||||||
|
\- { return TOKEN_MINUS; }
|
||||||
|
\* { return TOKEN_MUL; }
|
||||||
|
\/ { return TOKEN_DIV; }
|
||||||
|
if { return TOKEN_IF; }
|
||||||
|
\( { return TOKEN_LPAREN; }
|
||||||
|
\) { return TOKEN_RPAREN; }
|
||||||
|
\{ { return TOKEN_LBRACE; }
|
||||||
|
\} { return TOKEN_RBRACE; }
|
||||||
|
void { return TOKEN_VOID; }
|
||||||
|
int { return TOKEN_INT; }
|
||||||
|
while { return TOKEN_WHILE; }
|
||||||
|
{LETTER}+ { return TOKEN_IDENT; }
|
||||||
|
{DIGIT}+ { return TOKEN_NUMBER; }
|
||||||
|
. { return TOKEN_ERROR; }
|
||||||
|
|
||||||
|
%%
|
||||||
|
int yywrap() { return 1; }
|
||||||
|
|
Loading…
Reference in New Issue
Block a user