diff --git a/src/Makefile b/src/Makefile index d7b8cec..889833a 100644 --- a/src/Makefile +++ b/src/Makefile @@ -1,18 +1,19 @@ .PHONY: all clean all: deelang +CC = g++ lexer.o lexer.h: parser.h lexer.l - flex -o lexer.c --header-file=lexer.h lexer.l - $(CC) -c lexer.c - rm lexer.c + flex -o lexer.cpp --header-file=lexer.h lexer.l + $(CC) -c lexer.cpp + rm lexer.cpp parser.h parser.o: parser.y - bison -o parser.c --header=parser.h parser.y - $(CC) -c parser.c - rm parser.c + bison -o parser.cpp --header=parser.h parser.y + $(CC) -c parser.cpp + rm parser.cpp -deelang: deelang.c lexer.o parser.o syntax.o +deelang: deelang.cpp lexer.o parser.o syntax.o $(CC) -o $@ $^ clean: - rm -rf parser.o lexer.o parser.h lexer.h deelang + rm -rf *.o parser.h lexer.h deelang diff --git a/src/deelang.c b/src/deelang.cpp similarity index 64% rename from src/deelang.c rename to src/deelang.cpp index cc16030..f9e3219 100644 --- a/src/deelang.c +++ b/src/deelang.cpp @@ -2,7 +2,11 @@ #include "lexer.h" #include "parser.h" -void main() { +using namespace std; + +int main() { yydebug = 1; yyparse(); + + return 0; } diff --git a/src/lexer.l b/src/lexer.l index 8c73416..f7fb4db 100644 --- a/src/lexer.l +++ b/src/lexer.l @@ -1,12 +1,13 @@ %{ +#include #include "syntax.h" #include "parser.h" -int stack[100]; // Max indentation depth -int sp = -1; -int peek(); -void push(int a); -void pop(); -#define YY_USER_INIT push(0); BEGIN(freshline); +using namespace std; + +stack s; + +#define YY_USER_INIT s.push(0); BEGIN(freshline); + %} %option noyywrap @@ -18,20 +19,20 @@ letter [A-Za-z] %% ""/[^\t ] { -if (peek() == 0) { +if (s.top() == 0) { BEGIN(0); } else { - pop(); yyless(0); return DEDENT; + s.pop(); yyless(0); return DEDENT; } } [ \t]+ { -if (peek() == yyleng) { +if (s.top() == yyleng) { BEGIN(0); // Same indentation, continue -} else if (peek() > yyleng) { - pop(); yyless(0); return DEDENT; +} else if (s.top() > yyleng) { + s.pop(); yyless(0); return DEDENT; // Same rule again until the stack is even } else { - push(yyleng); BEGIN(0); return INDENT; + s.push(yyleng); BEGIN(0); return INDENT; } } #[^\n]* // Eat comments @@ -49,20 +50,4 @@ elif return ELIF; "/"\n // Eat newlines ending in / [\n;] BEGIN(freshline); return STOP; . fprintf(stderr, "Scanning error!\nOffender: %s\n", yytext); exit(1); -%% - -int peek() { - printf("Peek @ %d\n", stack[sp]); - return stack[sp]; -} - -void push(int a) { - printf("Push @ %d\n", a); - sp++; - stack[sp] = a; -} - -void pop() { - printf("Pop! Sp @ %d\n", sp); - sp--; -} +%% \ No newline at end of file diff --git a/src/parser.y b/src/parser.y index 720a4d0..58b58f0 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,25 +1,23 @@ %{ #include #include "syntax.h" +using namespace std; + int yylex(); -int yyerror(const char* p) { fprintf(stderr, p); } +void yyerror(const char* p) { fprintf(stderr, p); } %} %define parse.trace %union { - expr_t expr; - binop_t binop; - atom_t id; - num_t num; + float num; char *sym; - string_t string; - object_t object; + Node *node; } -%token ID +%token ID %token NUM -%token STRING +%token STRING %token STOP %token INDENT DEDENT @@ -31,8 +29,7 @@ int yyerror(const char* p) { fprintf(stderr, p); } %left '/' '*' %left MAPS -%nterm expr -%nterm objdef +%nterm expr %% program: statements | statements statement; @@ -44,16 +41,16 @@ assignment: ID GETS expr; assignments: assignments assignment STOP | // null production; expr: funcdef | funcall - | objdef { $$.type = DEE_OBJ; $$.object = $1;} - | expr CAT expr { $$ = make_binop(CAT, $1, $3); } - | expr '+' expr { $$ = make_binop('+', $1, $3); } - | expr '-' expr { $$ = make_binop('-', $1, $3); } - | expr '*' expr { $$ = make_binop('*', $1, $3); } - | expr '/' expr { $$ = make_binop('/', $1, $3); } + | objdef + | expr CAT expr { $$ = new OpNode(CAT, $1, $3); } + | expr '+' expr { $$ = new OpNode('+', $1, $3); } + | expr '-' expr { $$ = new OpNode('-', $1, $3); } + | expr '*' expr { $$ = new OpNode('*', $1, $3); } + | expr '/' expr { $$ = new OpNode('/', $1, $3); } | '(' expr ')' {$$ = $2;} - | ID {$$.id = $1; $$.type = DEE_ID;} - | NUM {$$.num = $1; $$.type = DEE_NUM;} - | STRING {$$.string = $1; $$.type = DEE_STR;}; + | ID {$$ = new IdNode($1);} + | NUM {$$ = new NumNode($1);} + | STRING {$$ = new StringNode($1);}; funcdef: param MAPS expr | param MAPS block; param: ID | '_' | // null production; diff --git a/src/stack.hh b/src/stack.hh new file mode 100644 index 0000000..746965d --- /dev/null +++ b/src/stack.hh @@ -0,0 +1,8 @@ +// A Bison parser, made by GNU Bison 3.8.2. + +// Starting with Bison 3.2, this file is useless: the structure it +// used to define is now defined with the parser itself. +// +// To get rid of this file: +// 1. add '%require "3.2"' (or newer) to your grammar file +// 2. remove references to this file from your build system. diff --git a/src/syntax.c b/src/syntax.c deleted file mode 100644 index 0674438..0000000 --- a/src/syntax.c +++ /dev/null @@ -1,15 +0,0 @@ -#include -#include - -#include "syntax.h" - -expr_t make_binop(int op, expr_t first, expr_t second) { - expr_t myexpr; - myexpr.type = DEE_BINOP; - myexpr.binop.op = op; - myexpr.binop.first = (expr_t*) malloc(sizeof(expr_t)); - myexpr.binop.second = (expr_t*) malloc(sizeof(expr_t)); - memcpy(myexpr.binop.first, &first, sizeof(expr_t)); - memcpy(myexpr.binop.second, &second, sizeof(expr_t)); - return myexpr; -} diff --git a/src/syntax.cpp b/src/syntax.cpp new file mode 100644 index 0000000..f79afcb --- /dev/null +++ b/src/syntax.cpp @@ -0,0 +1,22 @@ +#include +#include + +#include "syntax.h" + +IdNode::IdNode(char * id) { + this->id = id; +} + +NumNode::NumNode(float num) { + this->num = num; +} + +StringNode::StringNode(char *str) { + this->string = string; +} + +OpNode::OpNode(int op, Node *first, Node *second) { + this->op = op; + this->first = first; + this->second = second; +} diff --git a/src/syntax.h b/src/syntax.h index 31ba4fc..55a57af 100644 --- a/src/syntax.h +++ b/src/syntax.h @@ -1,40 +1,37 @@ #ifndef SYNTAX_H #define SYNTAX_H -typedef float num_t; -typedef char* atom_t; -typedef char* string_t; -typedef struct expr_t expr_t; -typedef struct binop_t binop_t; -typedef struct object_t object_t; -typedef struct function_t function_t; -typedef struct block_t block_t; +class Node {}; -#define DEE_BINOP 1 -#define DEE_ID 2 -#define DEE_NUM 3 -#define DEE_STR 4 -#define DEE_OBJ 5 +class IdNode : public Node { +private: + char* id; +public: + IdNode(char*); +}; -struct binop_t { - expr_t *first; - expr_t *second; +class NumNode : public Node { +private: + float num; +public: + NumNode(float); +}; + +class StringNode : public Node { +private: + char* string; +public: + StringNode(char*); +}; + +class OpNode : public Node { +private: int op; + Node *first; + Node *second; +public: + OpNode(int, Node*, Node*); }; -struct object_t {}; - -struct expr_t { - int type; - union { - atom_t id; - num_t num; - string_t string; - binop_t binop; - object_t object; - }; -}; - -expr_t make_binop(int, expr_t, expr_t); #endif /* SYNTAX_H */