Convert to c++
This commit is contained in:
parent
62d3f2c726
commit
ecc773b774
17
src/Makefile
17
src/Makefile
@ -1,18 +1,19 @@
|
|||||||
.PHONY: all clean
|
.PHONY: all clean
|
||||||
all: deelang
|
all: deelang
|
||||||
|
CC = g++
|
||||||
|
|
||||||
lexer.o lexer.h: parser.h lexer.l
|
lexer.o lexer.h: parser.h lexer.l
|
||||||
flex -o lexer.c --header-file=lexer.h lexer.l
|
flex -o lexer.cpp --header-file=lexer.h lexer.l
|
||||||
$(CC) -c lexer.c
|
$(CC) -c lexer.cpp
|
||||||
rm lexer.c
|
rm lexer.cpp
|
||||||
|
|
||||||
parser.h parser.o: parser.y
|
parser.h parser.o: parser.y
|
||||||
bison -o parser.c --header=parser.h parser.y
|
bison -o parser.cpp --header=parser.h parser.y
|
||||||
$(CC) -c parser.c
|
$(CC) -c parser.cpp
|
||||||
rm parser.c
|
rm parser.cpp
|
||||||
|
|
||||||
deelang: deelang.c lexer.o parser.o syntax.o
|
deelang: deelang.cpp lexer.o parser.o syntax.o
|
||||||
$(CC) -o $@ $^
|
$(CC) -o $@ $^
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf parser.o lexer.o parser.h lexer.h deelang
|
rm -rf *.o parser.h lexer.h deelang
|
||||||
|
@ -2,7 +2,11 @@
|
|||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
|
|
||||||
void main() {
|
using namespace std;
|
||||||
|
|
||||||
|
int main() {
|
||||||
yydebug = 1;
|
yydebug = 1;
|
||||||
yyparse();
|
yyparse();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
43
src/lexer.l
43
src/lexer.l
@ -1,12 +1,13 @@
|
|||||||
%{
|
%{
|
||||||
|
#include <stack>
|
||||||
#include "syntax.h"
|
#include "syntax.h"
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
int stack[100]; // Max indentation depth
|
using namespace std;
|
||||||
int sp = -1;
|
|
||||||
int peek();
|
stack<int> s;
|
||||||
void push(int a);
|
|
||||||
void pop();
|
#define YY_USER_INIT s.push(0); BEGIN(freshline);
|
||||||
#define YY_USER_INIT push(0); BEGIN(freshline);
|
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%option noyywrap
|
%option noyywrap
|
||||||
@ -18,20 +19,20 @@ letter [A-Za-z]
|
|||||||
|
|
||||||
%%
|
%%
|
||||||
<freshline>""/[^\t ] {
|
<freshline>""/[^\t ] {
|
||||||
if (peek() == 0) {
|
if (s.top() == 0) {
|
||||||
BEGIN(0);
|
BEGIN(0);
|
||||||
} else {
|
} else {
|
||||||
pop(); yyless(0); return DEDENT;
|
s.pop(); yyless(0); return DEDENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
<freshline>[ \t]+ {
|
<freshline>[ \t]+ {
|
||||||
if (peek() == yyleng) {
|
if (s.top() == yyleng) {
|
||||||
BEGIN(0); // Same indentation, continue
|
BEGIN(0); // Same indentation, continue
|
||||||
} else if (peek() > yyleng) {
|
} else if (s.top() > yyleng) {
|
||||||
pop(); yyless(0); return DEDENT;
|
s.pop(); yyless(0); return DEDENT;
|
||||||
// Same rule again until the stack is even
|
// Same rule again until the stack is even
|
||||||
} else {
|
} else {
|
||||||
push(yyleng); BEGIN(0); return INDENT;
|
s.push(yyleng); BEGIN(0); return INDENT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[^\n]* // Eat comments
|
#[^\n]* // Eat comments
|
||||||
@ -49,20 +50,4 @@ elif return ELIF;
|
|||||||
"/"\n // Eat newlines ending in /
|
"/"\n // Eat newlines ending in /
|
||||||
[\n;] BEGIN(freshline); return STOP;
|
[\n;] BEGIN(freshline); return STOP;
|
||||||
. fprintf(stderr, "Scanning error!\nOffender: %s\n", yytext); exit(1);
|
. 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--;
|
|
||||||
}
|
|
37
src/parser.y
37
src/parser.y
@ -1,25 +1,23 @@
|
|||||||
%{
|
%{
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "syntax.h"
|
#include "syntax.h"
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
int yylex();
|
int yylex();
|
||||||
int yyerror(const char* p) { fprintf(stderr, p); }
|
void yyerror(const char* p) { fprintf(stderr, p); }
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%define parse.trace
|
%define parse.trace
|
||||||
|
|
||||||
%union {
|
%union {
|
||||||
expr_t expr;
|
float num;
|
||||||
binop_t binop;
|
|
||||||
atom_t id;
|
|
||||||
num_t num;
|
|
||||||
char *sym;
|
char *sym;
|
||||||
string_t string;
|
Node *node;
|
||||||
object_t object;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
%token <id> ID
|
%token <sym> ID
|
||||||
%token <num> NUM
|
%token <num> NUM
|
||||||
%token <string> STRING
|
%token <sym> STRING
|
||||||
|
|
||||||
%token STOP
|
%token STOP
|
||||||
%token INDENT DEDENT
|
%token INDENT DEDENT
|
||||||
@ -31,8 +29,7 @@ int yyerror(const char* p) { fprintf(stderr, p); }
|
|||||||
%left '/' '*'
|
%left '/' '*'
|
||||||
%left MAPS
|
%left MAPS
|
||||||
|
|
||||||
%nterm <expr> expr
|
%nterm <node> expr
|
||||||
%nterm <object> objdef
|
|
||||||
|
|
||||||
%%
|
%%
|
||||||
program: statements | statements statement;
|
program: statements | statements statement;
|
||||||
@ -44,16 +41,16 @@ assignment: ID GETS expr;
|
|||||||
assignments: assignments assignment STOP | // null production;
|
assignments: assignments assignment STOP | // null production;
|
||||||
expr: funcdef
|
expr: funcdef
|
||||||
| funcall
|
| funcall
|
||||||
| objdef { $$.type = DEE_OBJ; $$.object = $1;}
|
| objdef
|
||||||
| expr CAT expr { $$ = make_binop(CAT, $1, $3); }
|
| expr CAT expr { $$ = new OpNode(CAT, $1, $3); }
|
||||||
| expr '+' expr { $$ = make_binop('+', $1, $3); }
|
| expr '+' expr { $$ = new OpNode('+', $1, $3); }
|
||||||
| expr '-' expr { $$ = make_binop('-', $1, $3); }
|
| expr '-' expr { $$ = new OpNode('-', $1, $3); }
|
||||||
| expr '*' expr { $$ = make_binop('*', $1, $3); }
|
| expr '*' expr { $$ = new OpNode('*', $1, $3); }
|
||||||
| expr '/' expr { $$ = make_binop('/', $1, $3); }
|
| expr '/' expr { $$ = new OpNode('/', $1, $3); }
|
||||||
| '(' expr ')' {$$ = $2;}
|
| '(' expr ')' {$$ = $2;}
|
||||||
| ID {$$.id = $1; $$.type = DEE_ID;}
|
| ID {$$ = new IdNode($1);}
|
||||||
| NUM {$$.num = $1; $$.type = DEE_NUM;}
|
| NUM {$$ = new NumNode($1);}
|
||||||
| STRING {$$.string = $1; $$.type = DEE_STR;};
|
| STRING {$$ = new StringNode($1);};
|
||||||
|
|
||||||
funcdef: param MAPS expr | param MAPS block;
|
funcdef: param MAPS expr | param MAPS block;
|
||||||
param: ID | '_' | // null production;
|
param: ID | '_' | // null production;
|
||||||
|
8
src/stack.hh
Normal file
8
src/stack.hh
Normal file
@ -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.
|
15
src/syntax.c
15
src/syntax.c
@ -1,15 +0,0 @@
|
|||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
|
|
||||||
#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;
|
|
||||||
}
|
|
22
src/syntax.cpp
Normal file
22
src/syntax.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#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;
|
||||||
|
}
|
57
src/syntax.h
57
src/syntax.h
@ -1,40 +1,37 @@
|
|||||||
#ifndef SYNTAX_H
|
#ifndef SYNTAX_H
|
||||||
#define SYNTAX_H
|
#define SYNTAX_H
|
||||||
|
|
||||||
typedef float num_t;
|
class Node {};
|
||||||
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;
|
|
||||||
|
|
||||||
#define DEE_BINOP 1
|
class IdNode : public Node {
|
||||||
#define DEE_ID 2
|
private:
|
||||||
#define DEE_NUM 3
|
char* id;
|
||||||
#define DEE_STR 4
|
public:
|
||||||
#define DEE_OBJ 5
|
IdNode(char*);
|
||||||
|
};
|
||||||
|
|
||||||
struct binop_t {
|
class NumNode : public Node {
|
||||||
expr_t *first;
|
private:
|
||||||
expr_t *second;
|
float num;
|
||||||
|
public:
|
||||||
|
NumNode(float);
|
||||||
|
};
|
||||||
|
|
||||||
|
class StringNode : public Node {
|
||||||
|
private:
|
||||||
|
char* string;
|
||||||
|
public:
|
||||||
|
StringNode(char*);
|
||||||
|
};
|
||||||
|
|
||||||
|
class OpNode : public Node {
|
||||||
|
private:
|
||||||
int op;
|
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 */
|
#endif /* SYNTAX_H */
|
||||||
|
Loading…
Reference in New Issue
Block a user