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

merge changes #1

Merged
merged 2 commits into from
Feb 4, 2021
Merged
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
1 change: 1 addition & 0 deletions doc/grammar.ebnf
Original file line number Diff line number Diff line change
@@ -23,6 +23,7 @@ expression = '(' [expression_list] ')'

expression_list = expression { ',' expression };
identifier = "[a-zA-Z_]([a-zA-Z0-9_]+)?";
identifier_list = identifier { ',' identifier };
integer = "[0-9]+";
function_call = identifier '(' expression_list ')';
unary_expression = unary_operator expression;
4 changes: 2 additions & 2 deletions include/ast.h
Original file line number Diff line number Diff line change
@@ -44,7 +44,7 @@ typedef struct jade_expression_list {
jade_ast_kind kind;
ast_node* parent;
jade_node* first;
jade_node* last;
jade_node* last;
} jade_expression_list;

typedef struct jade_program {
@@ -57,7 +57,7 @@ typedef struct jade_program {
typedef struct jade_identifier {
jade_ast_kind kind;
ast_node* parent;
const char* name;
char* name;
} jade_identifier;

typedef struct jade_integer {
3 changes: 2 additions & 1 deletion include/parser.h
Original file line number Diff line number Diff line change
@@ -6,8 +6,9 @@
typedef struct jade_parser {
jade_scanner* scanner;
jade_program* ast;
jade_token token;
} jade_parser;

void jade_parser_init(jade_parser* parser, jade_scanner* scanner);
void jade_parser_destroy(jade_parser* parser);
jade_program* jade_parser_parse(jade_scanner* scanner);
void jade_parser_parse(jade_parser* parser);
25 changes: 24 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include <stdio.h>
#include <stdlib.h>
#include "scanner.h"
#include "parser.h"

/*
int test_scanner(int argc, char** argv) {
if (argc < 2) {
fprintf(stderr, "USAGE: jadec file\n");
@@ -29,8 +31,29 @@ int test_scanner(int argc, char** argv) {
jade_scanner_destroy(&scanner);
return EXIT_SUCCESS;
}
*/

int test_parser(int argc, char** argv) {
if (argc < 2) {
fprintf(stderr, "USAGE: jadec file\n");
exit(EXIT_FAILURE);
}

jade_scanner scanner;
jade_scanner_init(&scanner, argv[1]);
//jade_scanner_destroy(&scanner);

jade_parser parser;
jade_parser_init(&parser, &scanner);
jade_parser_parse(&parser);

//printf("%s\n", parser.scanner->source);

return EXIT_SUCCESS;
}


int main(int argc, char** argv) {
return test_scanner(argc, argv);
//return test_scanner(argc, argv);
return test_parser(argc, argv);
}
194 changes: 191 additions & 3 deletions src/parser.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,23 @@
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include "parser.h"
#include "visitors/deleter_visitor.h"

static jade_token next_token(jade_parser* parser);
static void check_token(jade_parser* parser, jade_token_kind expected);
static void expect_token(jade_parser* parser, jade_token_kind expected);
static void syntax_error(jade_parser* parser, jade_token_kind expected, jade_token_kind got);

static jade_program* parse_program(jade_parser* parser, ast_node* parent);
static jade_global_definition_list* parse_global_definition_list(jade_parser* parser, ast_node* parent);
static void parse_global_definition(jade_parser* parser, jade_global_definition_list* global_definition_list, jade_identifier* target);
static jade_identifier* parse_identifier(jade_parser* parser, ast_node* parent);
static jade_function_definition* parse_function_definition(jade_parser* parser, ast_node* parent, jade_identifier* target);
static jade_variable_definition* parse_variable_definition(jade_parser* parser, ast_node* parent, jade_identifier* target);
static jade_expression_list* parse_expression_list(jade_parser* parser, ast_node* parent);
static ast_node* parse_expression(jade_parser* parser, ast_node* parent);

void jade_parser_init(jade_parser* parser, jade_scanner* scanner) {
parser->scanner = scanner;
parser->ast = NULL;
@@ -11,7 +27,179 @@ void jade_parser_destroy(jade_parser* parser) {
accept_deleter_visitor(parser->ast);
}

jade_program* jade_parser_parse(jade_scanner* scanner) {
// TODO: implement
return NULL;
void jade_parser_parse(jade_parser* parser) {
parser->ast = parse_program(parser, (ast_node*)parser->ast);
printf("\nPARSED PROGRAM");
}




static jade_program* parse_program(jade_parser* parser, ast_node* parent) {
jade_program* program = malloc(sizeof(jade_program));
program->kind = JADE_AST_KIND_PROGRAM;
program->parent = parent;

// (
expect_token(parser, JADE_TOKEN_KIND_LPAREN);

if (next_token(parser).kind != JADE_TOKEN_KIND_RPAREN) {
program->definitions = parse_global_definition_list(parser, (ast_node*)program);
}

// )
expect_token(parser, JADE_TOKEN_KIND_RPAREN);

// ,(
expect_token(parser, JADE_TOKEN_KIND_DELIMITER);
expect_token(parser, JADE_TOKEN_KIND_LPAREN);

if (next_token(parser).kind != JADE_TOKEN_KIND_RPAREN) {
//program->expressions;
}

// )
check_token(parser, JADE_TOKEN_KIND_RPAREN);

// EOF
expect_token(parser, JADE_TOKEN_KIND_EOF);

return program;
}

static jade_global_definition_list* parse_global_definition_list(jade_parser* parser, ast_node* parent) {
jade_global_definition_list* global_definition_list = malloc(sizeof(jade_global_definition_list));
global_definition_list->kind = JADE_AST_KIND_GLOBAL_DEFINITION_LIST;
global_definition_list->parent = parent;

// f
check_token(parser, JADE_TOKEN_KIND_IDENTIFIER);
jade_identifier* target = parse_identifier(parser, NULL);
parse_global_definition(parser, global_definition_list, target);


while (next_token(parser).kind == JADE_TOKEN_KIND_DELIMITER) {
parse_global_definition(parser, global_definition_list, target);
}

check_token(parser, JADE_TOKEN_KIND_RPAREN);


return global_definition_list;
}

static void parse_global_definition(jade_parser* parser, jade_global_definition_list* global_definition_list, jade_identifier* target) {
jade_token_kind kind = next_token(parser).kind;
if (kind == JADE_TOKEN_KIND_LPAREN) {
if (global_definition_list->first) {
global_definition_list->last = (jade_node*)parse_function_definition(parser, (ast_node*)global_definition_list, target);
global_definition_list->first->next = global_definition_list->last;
} else {
global_definition_list->first = (jade_node*)parse_function_definition(parser, (ast_node*)global_definition_list, target);
global_definition_list->last = global_definition_list->first;
}
} else if (kind == JADE_TOKEN_KIND_DEFINE) {
//global_definition_list->first = (jade_node*)parse_variable_definition(parser, (ast_node*)global_definition_list, target);
} else {
syntax_error(parser, JADE_TOKEN_KIND_LPAREN, parser->token.kind);
syntax_error(parser, JADE_TOKEN_KIND_DEFINE, parser->token.kind);
}
}

static jade_function_definition* parse_function_definition(jade_parser* parser, ast_node* parent, jade_identifier* target) {
jade_function_definition* function_definition = malloc(sizeof(jade_function_definition));
function_definition->kind = JADE_AST_KIND_FUNCTION_DEFINITION;
function_definition->parent = parent;
function_definition->target = target;
target->parent = (ast_node*)function_definition;

function_definition->parameters = parse_expression_list(parser, (ast_node*)function_definition);

return function_definition;
}

static jade_expression_list* parse_expression_list(jade_parser* parser, ast_node* parent) {
jade_expression_list* expression_list = malloc(sizeof(jade_expression_list));
expression_list->kind = JADE_AST_KIND_EXPRESSION_LIST;
expression_list->parent = parent;

while (parser->token.kind != JADE_TOKEN_KIND_RPAREN) {
if (expression_list->first) {
expression_list->last = (jade_node*)parse_expression(parser, (ast_node*)expression_list);
expression_list->first->next = expression_list->last;
} else {
expression_list->first = (jade_node*)parse_expression(parser, (ast_node*)expression_list);
expression_list->last = expression_list->first;
}
while (parser->token.kind == JADE_TOKEN_KIND_DELIMITER) {
if (expression_list->first) {
expression_list->last = (jade_node*)parse_expression(parser, (ast_node*)expression_list);
expression_list->first->next = expression_list->last;
} else {
expression_list->first = (jade_node*)parse_expression(parser, (ast_node*)expression_list);
expression_list->last = expression_list->first;
}
}
}

return expression_list;
}

static ast_node* parse_expression(jade_parser* parser, ast_node* parent) {

while (parser->token.kind != JADE_TOKEN_KIND_DELIMITER || parser->token.kind != JADE_TOKEN_KIND_RPAREN) {
next_token(parser);
if (parser->token.kind == JADE_TOKEN_KIND_IDENTIFIER) {

}
}
}


static jade_identifier* parse_identifier(jade_parser* parser, ast_node* parent) {
jade_identifier* identifier = malloc(sizeof(jade_identifier));
identifier->kind = JADE_AST_KIND_IDENTIFIER;
identifier->parent = parent;
identifier->name = malloc(parser->token.size + 1);
jade_lexeme(parser->scanner, &parser->token, identifier->name);

return identifier;
}








static jade_token next_token(jade_parser* parser) {
char lexeme[64];
jade_lexeme(parser->scanner, &parser->token, lexeme);
printf("%s", lexeme);

parser->token = jade_scan(parser->scanner);
return parser->token;
}

static void check_token(jade_parser* parser, jade_token_kind expected) {
if (parser->token.kind != expected)
syntax_error(parser, expected, parser->token.kind);
}

static void expect_token(jade_parser* parser, jade_token_kind expected) {
next_token(parser);
check_token(parser, expected);
}

static void syntax_error(jade_parser* parser, jade_token_kind expected, jade_token_kind got) {
fprintf(
stderr,
"%s:%ld:%ld: expected: %s got: %s\n",
parser->scanner->path,
parser->scanner->line,
parser->scanner->column,
jade_token_kind_name(expected),
jade_token_kind_name(got)
);
}
2 changes: 1 addition & 1 deletion test/scanner.jd
Original file line number Diff line number Diff line change
@@ -10,4 +10,4 @@
pi := 2, f(g(pi))
),
f(g(k + pi))
)
)
6 changes: 6 additions & 0 deletions test/test.jd
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
fffffffffffffffffffffffff
ffffffffffffffffffffffffff
ffffffffffffffffffffffffff
fffffffffffffffffffffffff
asd
as ! $ %$@$@ $@$ ^ 21312321
7 changes: 7 additions & 0 deletions test/test_program.jd
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
(
f(x,y)
),

(

)