Prechádzať zdrojové kódy

Adding simple c parser

Vinicius Teshima 11 mesiacov pred
rodič
commit
cc67d6c6d4
3 zmenil súbory, kde vykonal 282 pridanie a 7 odobranie
  1. 26 7
      src/cint.c
  2. 86 0
      src/da.h
  3. 170 0
      src/parser.h

+ 26 - 7
src/cint.c

@@ -2,6 +2,7 @@
 #include <stdlib.h>
 
 #define IMP
+#include "./parser.h"
 #include "./lexer.h"
 #include "./da.h"
 #include "./str.h"
@@ -24,18 +25,17 @@ main(int argc, const char *argv[])
 {
 	struct str str;
 
-	const char *src_path = "./main.c";
+	/* const char *src_path = "./main.c"; */
+	/* const char *src_path = "./src/cint.c"; */
+	const char *src_path = "./t.c";
 	enum file_err ferr;
 	char *src = NULL;
 	size_t src_size = 0;
 
 	struct lexer l = {0};
-	struct token t = {0};
-
-	struct token ts[256] = {0};
-	size_t ts_size = 0;
+	struct parser p = {0};
 
-	size_t i = 0;
+	struct parser_err perr = {0};
 
 	src = (char *) file_read_all(src_path, &src_size, &ferr);
 	if ( ferr != FILE_ERR_OK ) {
@@ -47,6 +47,14 @@ main(int argc, const char *argv[])
 	str = str_from_cstr(src, src_size);
 
 	l = lexer_create(str);
+	/*
+	{
+	struct token t = {0};
+
+	struct token ts[2048] = {0};
+	size_t ts_size = 0;
+
+	size_t i = 0;
 	t = lexer_next_token(&l, NULL);
 	for ( ; t.typ.code != TT_EOF; t = lexer_next_token(&l, NULL) ) {
 		ts[ts_size++] = t;
@@ -54,9 +62,20 @@ main(int argc, const char *argv[])
 
 	for ( i = 0; i < ts_size; ++i ) {
 		printf("%ld, %d - %s -> `%.*s`\n", i,
-		       ts[i].typ.code, ts[i].typ.name, 
+		       ts[i].typ.code, ts[i].typ.name,
 		       (int) ts[i].lit.size, ts[i].lit.data);
 	}
+	}
+	*/
+
+	p = parser_create(l, &perr);
+	if ( perr.code != PARSER_ERR_OK ) {
+		fprintf(stderr, "Failed to create parser: `%s`\n", perr.name);
+	}
+	parser_parse_program(&p, &perr);
+	if ( perr.code != PARSER_ERR_OK ) {
+		fprintf(stderr, "Failed to parse program: `%s`\n", perr.name);
+	}
 
 	free(src);
 

+ 86 - 0
src/da.h

@@ -0,0 +1,86 @@
+#ifndef DA_H
+#define DA_H
+
+#define CONCAT(a, b) CONCAT_INNER(a, b)
+#define CONCAT_INNER(a, b) a ## b
+
+#define UNIQUE_NAME(base) CONCAT(base, __COUNTER__)
+
+#include <stdlib.h>
+
+#define DA_DEF_STRUCT(type, name)		\
+	struct name {				\
+		type *items;			\
+		size_t size;			\
+		size_t cap;			\
+	}
+
+#define DA_DEF_STRUCT_ITEM(type, name)		\
+	struct {				\
+		type *items;			\
+		size_t size;			\
+		size_t cap;			\
+	} name
+
+#define DA_CREATE(da, item_size)				\
+	do {							\
+		(da).cap = 16;					\
+		(da).size = 0;					\
+		(da).items = calloc((da).cap, item_size);	\
+	} while(0)
+
+#define DA_DESTROY(da)					\
+	do {						\
+		free((da).items);			\
+	} while(0)
+
+#define DA_CLEAR(da)					\
+	do {						\
+		(da).size = 0;				\
+	} while(0)
+
+#define _DA_DELETE(da, index, i)					\
+	do {								\
+		if ( index > (da).size ) {				\
+			break;						\
+		}							\
+		memmove((da).items+index, (da).items+index+1,		\
+			(da).cap - (index+1));				\
+		--(da).size;						\
+	} while(0)
+
+#define DA_DELETE(da, index) \
+	_DA_DELETE(da, index, UNIQUE_NAME(_i))
+
+#define _DA_INSERT(da, item, index, i)					\
+	do {								\
+		if ( index > (da.size) ) {				\
+			break;						\
+		}							\
+		if ( (da).size+1 >= (da).cap ) {			\
+			(da).cap *= 2;					\
+			(da).items = realloc((da).items,		\
+					     (da).cap * sizeof(*(da).items)); \
+		}							\
+		memmove((da).items+index+1, (da).items+index,		\
+			(da).cap - index);				\
+		(da).items[index] = item;				\
+		(da).size++;						\
+	} while(0)
+
+#define DA_INSERT(da, item, index) \
+	_DA_INSERT(da, item, index, UNIQUE_NAME(_i))
+
+#define DA_APPEND(da, item)						\
+	do {								\
+		if ( (da).size+1 >= (da).cap ) {			\
+			(da).cap *= 2;					\
+			(da).items = realloc((da).items,		\
+					     (da).cap * sizeof(*(da).items)); \
+		}							\
+		(da).items[(da).size++] = item;			\
+	} while(0)
+
+#define DA_TAIL(da) (da).items[(da).size-1]
+
+#endif

+ 170 - 0
src/parser.h

@@ -0,0 +1,170 @@
+#ifndef PARSER_H
+#define PARSER_H
+
+#include <stddef.h>
+
+#include "lexer.h"
+#include "token.h"
+
+struct expresion {
+	char reserved;
+};
+
+struct stmt_var_def {
+	struct token type;
+	struct token ident;
+	struct expresion exp;
+};
+
+struct stmt {
+	char reserved[sizeof(struct stmt_var_def)];
+};
+
+struct parser {
+	struct lexer l;
+	struct token cur_tk;
+	struct token peek_tk;
+	struct stmt prog[1024];
+};
+
+enum parser_err_code {
+	PARSER_ERR_OK = 0,
+	PARSER_ERR_FAILED_READ_NEXT_TOKEN
+};
+
+struct parser_err {
+	enum parser_err_code code;
+	const char *name;
+};
+
+struct parser parser_create(struct lexer l, struct parser_err *err);
+
+void parser_next_token(struct parser *p, struct parser_err *err);
+
+void parser_parse_program(struct parser *p, struct parser_err *err);
+
+struct parser_err parser_err_create(enum parser_err_code code);
+void _parser_set_err(struct parser_err *err, enum parser_err_code code);
+
+#if defined(IMP) || defined(PARSER_IMP)
+
+struct parser
+parser_create(struct lexer l, struct parser_err *err)
+{
+	struct parser_err _err = {0};
+	struct parser p_empty = {0};
+	struct parser p = {0};
+	p.l = l;
+	parser_next_token(&p, &_err);
+	if ( _err.code != PARSER_ERR_OK ) {
+		goto ret_err;
+	}
+	parser_next_token(&p, &_err);
+	if ( _err.code != PARSER_ERR_OK ) {
+		goto ret_err;
+	}
+	return p;
+ret_err:
+	if ( err != NULL ) {
+		*err = _err;
+	}
+	return p_empty;
+}
+
+void
+parser_next_token(struct parser *p, struct parser_err *err)
+{
+	struct lexer_err l_err = {0};
+	p->cur_tk = p->peek_tk;
+	p->peek_tk = lexer_next_token(&p->l, &l_err);
+	if ( l_err.code != LEXER_ERR_OK ) {
+		_parser_set_err(err, PARSER_ERR_FAILED_READ_NEXT_TOKEN);
+		return;
+	}
+	_parser_set_err(err, PARSER_ERR_OK);
+	return;
+}
+
+void
+parser_parse_program(struct parser *p, struct parser_err *err)
+{
+	struct parser_err _err = {0};
+	goto jump_start;
+
+loop:
+	parser_next_token(p, &_err);
+	if ( _err.code != PARSER_ERR_OK ) {
+		goto ret_err;
+	}
+jump_start:
+
+	switch ( p->cur_tk.typ.code ) {
+	case TT_ILLEGAL:
+	case TT_EOF:
+		goto out_loop;
+	case TT_TYPE: {
+		struct token type = p->cur_tk;
+
+		if ( p->peek_tk.typ.code == TT_IDENT ) {
+			struct token ident = p->peek_tk;
+
+			parser_next_token(p, &_err);
+			if ( _err.code != PARSER_ERR_OK ) {
+				goto ret_err;
+			}
+
+			if ( p->peek_tk.typ.code == TT_ASSIGN ) {
+				/*struct stmt_var_def vd = {0};
+				vd.type = type;
+				vd.ident = ident;*/
+				printf("type: `%.*s`, ident: `%.*s`\n", 
+					(int)type.lit.size, type.lit.data,
+					(int)ident.lit.size, ident.lit.data);
+			}
+		}
+		goto loop; 
+	}
+	default:
+		goto loop;
+	}
+
+out_loop:
+	_parser_set_err(err, PARSER_ERR_OK);
+	return;
+
+ret_err:
+	if ( err != NULL ) {
+		*err = _err;
+	}
+	return;
+}
+
+
+struct parser_err
+parser_err_create(enum parser_err_code code)
+{
+#define _PARSER_ERR_CASE(it) case it: pe.name = #it; break;
+	struct parser_err pe = {0};
+	pe.code = code;
+
+	switch ( code ) {
+	_PARSER_ERR_CASE(PARSER_ERR_OK);
+	_PARSER_ERR_CASE(PARSER_ERR_FAILED_READ_NEXT_TOKEN);
+	}
+
+	return pe;
+#undef _PARSER_ERR_CASE
+}
+
+void 
+_parser_set_err(struct parser_err *err, enum parser_err_code code)
+{
+	if ( err != NULL ) {
+		*err = parser_err_create(code);
+	}
+}
+
+#endif /* defined(IMP) || defined(PARSER_IMP) */
+
+
+#endif /* PARSER_H */