Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Second parser version before deadline #2

Merged
merged 3 commits into from
Oct 30, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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