Parser working

This commit is contained in:
pjht 2018-09-09 17:31:02 -05:00
parent a75baf7296
commit b94fa9d49a
7 changed files with 127 additions and 22 deletions

View File

@ -11,6 +11,7 @@
F61910692142A8C5003B8798 /* tokenize.c in Sources */ = {isa = PBXBuildFile; fileRef = F61910682142A8C5003B8798 /* tokenize.c */; };
F65A954E21454B31005FCAF5 /* token.c in Sources */ = {isa = PBXBuildFile; fileRef = F65A954D21454B31005FCAF5 /* token.c */; };
F661C333214590930021FCCE /* parser.c in Sources */ = {isa = PBXBuildFile; fileRef = F661C332214590930021FCCE /* parser.c */; };
F661C3362145CE760021FCCE /* ast.c in Sources */ = {isa = PBXBuildFile; fileRef = F661C3352145CE760021FCCE /* ast.c */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -34,6 +35,8 @@
F65A954D21454B31005FCAF5 /* token.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = token.c; sourceTree = "<group>"; };
F661C331214590930021FCCE /* parser.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = parser.h; sourceTree = "<group>"; };
F661C332214590930021FCCE /* parser.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = parser.c; sourceTree = "<group>"; };
F661C3342145CE760021FCCE /* ast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ast.h; sourceTree = "<group>"; };
F661C3352145CE760021FCCE /* ast.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ast.c; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -73,6 +76,8 @@
F65A954C21454B21005FCAF5 /* token.h */,
F661C331214590930021FCCE /* parser.h */,
F661C332214590930021FCCE /* parser.c */,
F661C3342145CE760021FCCE /* ast.h */,
F661C3352145CE760021FCCE /* ast.c */,
);
path = cinc;
sourceTree = "<group>";
@ -134,6 +139,7 @@
buildActionMask = 2147483647;
files = (
F65A954E21454B31005FCAF5 /* token.c in Sources */,
F661C3362145CE760021FCCE /* ast.c in Sources */,
F61910692142A8C5003B8798 /* tokenize.c in Sources */,
F661C333214590930021FCCE /* parser.c in Sources */,
F61910612142A876003B8798 /* main.c in Sources */,

39
cinc/ast.c Normal file
View File

@ -0,0 +1,39 @@
//
// ast.c
// cinc
//
// Created by Peter Terpstra on 9/9/18.
// Copyright © 2018 Peter Terpstra. All rights reserved.
//
#include "ast.h"
#include <stdlib.h>
#define AST_CHILDREN_START 10
AstNode* make_node(const char* data) {
AstNode* node=malloc(sizeof(AstNode));
node->data=data;
node->num_children=0;
node->max_children=AST_CHILDREN_START;
node->children=malloc(sizeof(AstNode*)*AST_CHILDREN_START);
return node;
}
void add_child(AstNode* parent,AstNode* child) {
if (parent->num_children==parent->max_children) {
parent->children=realloc(parent->children, sizeof(AstNode*)*(parent->max_children+10));
(parent->max_children)+=10;
}
parent->children[parent->num_children]=child;
parent->num_children++;
}
void free_tree(AstNode* root) {
if (root->children) {
for (int i=0;i<(root->num_children);i++) {
free_tree(root->children[i]);
}
}
free(root);
}

25
cinc/ast.h Normal file
View File

@ -0,0 +1,25 @@
//
// ast.h
// cinc
//
// Created by Peter Terpstra on 9/9/18.
// Copyright © 2018 Peter Terpstra. All rights reserved.
//
#ifndef ast_h
#define ast_h
struct _astnode {
const char* data;
int num_children;
int max_children;
struct _astnode** children;
};
typedef struct _astnode AstNode;
AstNode* make_node(const char* data);
void add_child(AstNode* parent,AstNode* child);
void free_tree(AstNode* root);
#endif /* ast_h */

View File

@ -10,17 +10,12 @@
#include <stdbool.h>
#include <stdlib.h>
#include "tokenize.h"
#include "ast.h"
#include "parser.h"
int main(int argc, const char * argv[]) {
char* prgstr="int main() {\nreturn 0;\n}";
Token* tokens=tokenize(prgstr);
Token* tok=tokens;
while (tok) {
print_tok(tok);
if (tok->type==TYPE_EOF) {
break;
}
tok=tok->next;
}
AstNode* ast=parse(tokens);
free_toklist(tokens);
}

View File

@ -8,7 +8,10 @@
#include "parser.h"
#include "token.h"
#include "ast.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
static Token lahead;
@ -32,11 +35,11 @@ static const char* getid() {
return id;
}
static int get_num() {
static const char* get_num() {
if (lahead.type!=TYPE_NUM) {
exit(1);
}
int num=lahead.val->intval;
const char* num=lahead.val->strval;
advance();
return num;
}
@ -50,18 +53,52 @@ static const char* gettype() {
return id;
}
static char** func() {
static AstNode* expr() {
AstNode* expr_root=make_node("num");
add_child(expr_root, make_node(get_num()));
return expr_root;
}
static AstNode* statement() {
switch (lahead.type) {
case TYPE_RETURN: {
match(TYPE_RETURN);
AstNode* return_root=make_node("return");
add_child(return_root, expr());
match(';');
return return_root;
}
default:
printf("Error: Expected statement");
exit(1);
}
}
static AstNode* block() {
match('{');
AstNode* block_root=make_node("block");
while (lahead.type!='}') {
add_child(block_root, statement());
}
match('}');
return block_root;
}
static AstNode* func() {
const char* type=gettype();
const char* name=getid();
match('(');
match(')');
match('{');
//block code here
match('}');
//return ast here
AstNode* func_block=block();
AstNode* func_root=make_node("func");
add_child(func_root, make_node(type));
add_child(func_root, make_node(name));
add_child(func_root, func_block);
return func_root;
}
char** parse(Token* prg) {
AstNode* parse(Token* prg) {
lahead=*(prg);
return func();
}

View File

@ -9,6 +9,9 @@
#ifndef parser_h
#define parser_h
#include <stdio.h>
#include "token.h"
#include "ast.h"
AstNode* parse(Token* prg);
#endif /* parser_h */

View File

@ -44,14 +44,14 @@ Token* next_token(int* strpos, char* prg, Token* prev) {
}
return new_token(TYPE_IDENT, val_from_str(id), prev);
} else if (isdigit(current)) {
char* id=malloc(sizeof(char)*ID_MAX_SIZE+1);
char* num=malloc(sizeof(char)*ID_MAX_SIZE+1);
int length=1;
id[0]=current;
num[0]=current;
(*strpos)++;
while (true) {
current=prg[*strpos];
if (isdigit(current)) {
id[length]=current;
num[length]=current;
length++;
(*strpos)++;
} else {
@ -61,8 +61,8 @@ Token* next_token(int* strpos, char* prg, Token* prev) {
break;
}
}
id[length]=0;
return new_token(TYPE_NUM, val_from_int(atoi(id)), prev);
num[length]=0;
return new_token(TYPE_NUM, val_from_str(num), prev);
} else if (isblank(current) || current=='\n') {
(*strpos)++;
current=prg[*strpos];