|
@@ -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 */
|