Skip to content

Commit

Permalink
Merge pull request #2 from Dayof/dev
Browse files Browse the repository at this point in the history
Second parser version before deadline
  • Loading branch information
Dayof authored Oct 30, 2020
2 parents 241531a + 8052388 commit e170382
Show file tree
Hide file tree
Showing 22 changed files with 210 additions and 2,092 deletions.
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
# CPPython
# CPPython - Lexer/Parser

## Requirements

- Flex 2.6.4
- Bison 3.5.1
- GCC 9.3.0
- Make 4.2.1

## Usage

```bash
$ cd src
$ chmod +x build.sh
$ ./build.sh
$ ./cppython tests/valid_1.ppy # for valid test
$ ./cppython tests/incorrect_1.ppy # for invalid test
$ make
$ ./cppython tests/parser/valid_1.ppy # for valid test
$ ./cppython tests/parser/invalid_1.ppy # for invalid test
```

## Author
Expand Down
16 changes: 8 additions & 8 deletions src/Makefile
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
FILES = parser.c lexer.c ast.c sym_tab.c main.c
FILES = parser/parser.c lexer/lexer.c core/ast.c core/sym_tab.c core/main.c
CFLAGS = -g -Wall -pedantic -x c
CC = gcc

cppython: $(FILES) ast.h sym_tab.h
$(CC) $(CFLAGS) $(FILES) -o cppython -lfl
cppython: $(FILES) core/ast.h core/sym_tab.h
$(CC) $(CFLAGS) $(FILES) -I core -I lexer -I parser -o cppython -lfl

lexer.c: cppython.lex
flex cppython.lex
lexer/lexer.c: lexer/cppython.lex
flex lexer/cppython.lex

parser.c: cppython.y
bison -d -v cppython.y
parser/parser.c: parser/cppython.y
bison -d -v parser/cppython.y

clean:
rm -f *.o *~ lexer.c lexer.h parser.c parser.h parser.output cppython
rm -f *.o *~ lexer/lexer.c lexer/lexer.h parser/parser.c parser/parser.h parser/parser.output cppython
23 changes: 2 additions & 21 deletions src/README.md
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
# CPPython - Lexer
# CPPython - Lexer/Parser

## Requirements

- Flex 2.6.4
- Bison 3.5.1
- GCC 9.3.0

## Usage

```bash
$ make
$ ./cppython tests/parser/valid_1.ppy # for valid test
$ ./cppython tests/parser/invalid_1.ppy # for invalid test
```

## Output examples
## Examples

- Valid input 1:
- Commands: ./cppython tests/parser/valid_1.ppy
Expand Down Expand Up @@ -58,8 +44,3 @@ $ ./cppython tests/parser/invalid_1.ppy # for invalid test
LexerError: line 1, column 2, token '^' is not recognized
```

## Author

Name: Dayanne Fernandes da Cunha
University ID: 130107191
32 changes: 0 additions & 32 deletions src/ast.c

This file was deleted.

75 changes: 75 additions & 0 deletions src/core/ast.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
#include <stdio.h>
#include <stdlib.h>
#include "ast.h"

ast_node* create_bin_expr(char *operator, ast_node* left, ast_node* right) {
if (PARSER_VERBOSE) printf("\nCreating binary expression node: .%d. .%s. .%d.\n",
left->op.integer_expr, operator, right->op.integer_expr);
ast_node* expr = (ast_node*) malloc(sizeof(ast_node));
expr->tag = BINARY_TYPE;
expr->op.binary_expr.operator = operator;
expr->op.binary_expr.left = left;
expr->op.binary_expr.right = right;
return expr;
}

ast_node* create_int_expr(int value) {
if (PARSER_VERBOSE) printf("\n\nCreating integer expression node: %d\n", value);
ast_node* expr = (ast_node*) malloc(sizeof(ast_node));
expr->tag = INTEGER_TYPE;
expr->op.integer_expr = value;
return expr;
}

void create_ast(ast_node* expression) {
if (PARSER_VERBOSE) printf("\nCreating AST.\n");
root = expression;
return;
}

void create_empy_ast() {
if (PARSER_VERBOSE) printf("\nCreating empty AST.\n");
root = NULL;
return;
}

ast_node* print_exp(ast_node* node) {
if (PARSER_VERBOSE) {
if (node == NULL) {
printf("Empty expression.\n");
} else {
printf("TAG: %d\n", node->tag);
}
}
return node;
}

void print_ast(ast_node* node) {
if (node == NULL) {
printf("Empty AST.\n");
return;
}

if (PARSER_VERBOSE) printf("TAG: %d\n", node->tag);

for (int i=0; i < AST_LVL; ++i) printf(" ");

// terminal leaf
if (node->tag == INTEGER_TYPE) {
printf("INT: %d\n", node->op.integer_expr);
return;
// terminal leaf
} else if (node->tag == VAR_TYPE) {
printf("VAR: %s\n", node->op.variable_expr);
return;
// non terminal node
} else if (node->tag == BINARY_TYPE) {
printf("OP: %s\n", node->op.binary_expr.operator);
AST_LVL += 1;
print_ast(node->op.binary_expr.right);
print_ast(node->op.binary_expr.left);
} else {
printf("Print AST unknown error.\n");
return;
}
}
21 changes: 14 additions & 7 deletions src/ast.h → src/core/ast.h
Original file line number Diff line number Diff line change
@@ -1,28 +1,35 @@
#ifndef __AST_H__
#define __AST_H__

int LEX_VERBOSE, PARSER_VERBOSE, MAIN_VERBOSE, AST_LVL;
int line, column;

enum TAG {
INTEGER_TYPE=0,
VAR_TYPE,
BINARY_TYPE
};

typedef struct exp {
int tag;
union {
int integer_expr;
char *string_expr;
char *variable_expr;
struct {
char *operator;
struct exp* left;
struct exp* right;
} binary_expr;
} op;
} op;
} ast_node;

typedef struct expr_list {
ast_node* head;
struct expr_list* next;
} ast;
ast_node* root;

void print_ast(ast_node* node);
ast_node* print_exp(ast_node* node);

void create_empy_ast();
void create_ast(ast_node* expression);
ast_node* show(ast_node* expression);
ast_node* create_int_expr(int value);
ast_node* create_bin_expr(char *operator, ast_node* left, ast_node* right);

Expand Down
10 changes: 7 additions & 3 deletions src/main.c → src/core/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,22 @@

int main (int argc, char *argv[]) {
printf("Welcome to CPPython interpreter:\n");
MAIN_VERBOSE = LEX_VERBOSE = PARSER_VERBOSE = AST_LVL = 0;
root = NULL;

// init lexer and parser
printf("Lexer/parser:\n");
line = column = 1;
yyin = fopen(argv[1], "r");
printf("\nline %d. ", line);
if (MAIN_VERBOSE) printf("\nline %d. ", line);
do {
yyparse();
} while (!feof(yyin));
fclose(yyin);
printf("\n");
printf("Lexer and parser finished.\n\n");
printf("\nLexer and parser finished.\n\n");

printf("Abstract Syntax Tree:\n");
print_ast(root);

return 0;
}
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 10 additions & 10 deletions src/cppython.lex → src/lexer/cppython.lex
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include "ast.h"
#include "parser.h"

enum TOKENS{
enum TOKENS {
ERROR_TOK=1,
NEWLINE_TOK,
WHITESPACE_TOK,
Expand All @@ -26,7 +26,7 @@
};
%}

%option outfile="lexer.c" header-file="lexer.h"
%option outfile="lexer/lexer.c" header-file="lexer/lexer.h"
%option nounput
%option noinput

Expand Down Expand Up @@ -96,33 +96,33 @@ NUMBER ({INTEGER}|{FLOAT})
void handle_token(int token) {
switch (token) {
case INTEGER_TOK:
printf("Token: <integer, '%s'>", yytext);
if (LEX_VERBOSE) printf("Token: <integer, '%s'>", yytext);
yylval.value = atoi(yytext);
break;
case SUB_TOK:
printf("Token: <sub, '%s'>", yytext);
if (LEX_VERBOSE) printf("Token: <sub, '%s'>", yytext);
yylval.op = yytext;
break;
case ADD_TOK:
printf("Token: <add, '%s'>", yytext);
if (LEX_VERBOSE) printf("Token: <add, '%s'>", yytext);
yylval.op = yytext;
break;
case MULT_TOK:
printf("Token: <mult, '%s'>", yytext);
if (LEX_VERBOSE) printf("Token: <mult, '%s'>", yytext);
yylval.op = yytext;
break;
case DIV_TOK:
printf("Token: <div, '%s'>", yytext);
if (LEX_VERBOSE) printf("Token: <div, '%s'>", yytext);
yylval.op = yytext;
break;
case NEWLINE_TOK:
line += 1;
column = 0; // reset column index
printf("\nline %d. ", line);
if (LEX_VERBOSE) printf("\nline %d. ", line);
break;
case ERROR_TOK:
printf("\nLexerError: line %d, column %d, token '%s' is not recognized\n",
line, column, yytext);
if (LEX_VERBOSE) printf("\nLexerError: line %d, column %d, token '%s' is not recognized\n",
line, column, yytext);
exit(1);
default:
break; // ignore
Expand Down
Loading

0 comments on commit e170382

Please sign in to comment.