Parser working
This commit is contained in:
parent
a75baf7296
commit
b94fa9d49a
@ -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
39
cinc/ast.c
Normal 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
25
cinc/ast.h
Normal 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 */
|
11
cinc/main.c
11
cinc/main.c
@ -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);
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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];
|
||||
|
Loading…
Reference in New Issue
Block a user