From 4f1f182a89a605b1e8df3293ffb416ba5c105233 Mon Sep 17 00:00:00 2001 From: Daniel Kolesa Date: Tue, 22 Jul 2014 15:27:11 +0100 Subject: [PATCH] eolian: lexer line context push/pop/restore/clear --- src/lib/eolian/eo_lexer.c | 43 ++++++++++++++++++++++++++++++++++++++++++- src/lib/eolian/eo_lexer.h | 14 ++++++++++++++ src/lib/eolian/eo_parser.c | 43 +++++++++++++++++++++++++------------------ 3 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/lib/eolian/eo_lexer.c b/src/lib/eolian/eo_lexer.c index 341d2c0..995fce1 100644 --- a/src/lib/eolian/eo_lexer.c +++ b/src/lib/eolian/eo_lexer.c @@ -600,6 +600,8 @@ eo_lexer_free(Eo_Lexer *ls) if (ls->buff ) eina_strbuf_free (ls->buff); if (ls->handle) eina_file_close (ls->handle); + eo_lexer_context_clear(ls); + EINA_LIST_FREE(ls->nodes, nd) { switch (nd->type) @@ -661,7 +663,11 @@ eo_lexer_lookahead(Eo_Lexer *ls) { assert (ls->lookahead.token < 0); ls->lookahead.kw = 0; - return (ls->lookahead.token = lex(ls, &ls->lookahead)); + eo_lexer_context_push(ls); + ls->lookahead.token = lex(ls, &ls->lookahead); + eo_lexer_context_restore(ls); + eo_lexer_context_pop(ls); + return ls->lookahead.token; } void @@ -753,3 +759,38 @@ eo_lexer_shutdown() } return _init_counter; } + +void +eo_lexer_context_push(Eo_Lexer *ls) +{ + Lexer_Ctx *ctx = malloc(sizeof(Lexer_Ctx)); + ctx->line = ls->line_number; + ctx->column = ls->column; + ctx->linestr = ls->stream_line; + ls->saved_ctxs = eina_list_prepend(ls->saved_ctxs, ctx); +} + +void +eo_lexer_context_pop(Eo_Lexer *ls) +{ + Lexer_Ctx *ctx = (Lexer_Ctx*)eina_list_data_get(ls->saved_ctxs); + free(ctx); + ls->saved_ctxs = eina_list_remove_list(ls->saved_ctxs, ls->saved_ctxs); +} + +void +eo_lexer_context_restore(Eo_Lexer *ls) +{ + if (!eina_list_count(ls->saved_ctxs)) return; + Lexer_Ctx *ctx = (Lexer_Ctx*)eina_list_data_get(ls->saved_ctxs); + ls->line_number = ctx->line; + ls->column = ctx->column; + ls->stream_line = ctx->linestr; +} + +void +eo_lexer_context_clear(Eo_Lexer *ls) +{ + Lexer_Ctx *ctx; + EINA_LIST_FREE(ls->saved_ctxs, ctx) free(ctx); +} diff --git a/src/lib/eolian/eo_lexer.h b/src/lib/eolian/eo_lexer.h index c3941a6..90b6d65 100644 --- a/src/lib/eolian/eo_lexer.h +++ b/src/lib/eolian/eo_lexer.h @@ -110,6 +110,12 @@ typedef struct _Eo_Node }; } Eo_Node; +typedef struct _Lexer_Ctx +{ + int line, column; + const char *linestr; +} Lexer_Ctx; + /* keeps all lexer state */ typedef struct _Eo_Lexer { @@ -147,6 +153,9 @@ typedef struct _Eo_Lexer /* this is jumped to when an error happens */ jmp_buf err_jmp; + /* saved context info */ + Eina_List *saved_ctxs; + /* represents the results of parsing */ Eina_List *nodes; /* represents the temporaries, every object that is allocated by the @@ -180,6 +189,11 @@ const char *eo_lexer_keyword_str_get(int kw); Eina_Bool eo_lexer_is_type_keyword(int kw); /* gets the C type name for a builtin type name - e.g. uchar -> unsigned char */ const char *eo_lexer_get_c_type (int kw); +/* save, restore and clear context (line, column, line string) */ +void eo_lexer_context_push (Eo_Lexer *ls); +void eo_lexer_context_pop (Eo_Lexer *ls); +void eo_lexer_context_restore(Eo_Lexer *ls); +void eo_lexer_context_clear (Eo_Lexer *ls); extern int _eo_lexer_log_dom; #ifdef CRITICAL diff --git a/src/lib/eolian/eo_parser.c b/src/lib/eolian/eo_parser.c index 35e753c..7af32c6 100644 --- a/src/lib/eolian/eo_parser.c +++ b/src/lib/eolian/eo_parser.c @@ -220,14 +220,15 @@ static Eolian_Type *parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, static Eolian_Type * parse_type(Eo_Lexer *ls) { - int line = ls->line_number, column = ls->column; - Eolian_Type *ret = parse_type_void(ls); + Eolian_Type *ret; + eo_lexer_context_push(ls); + ret = parse_type_void(ls); if (ret->type == EOLIAN_TYPE_VOID) { - ls->line_number = line; - ls->column = column; + eo_lexer_context_restore(ls); eo_lexer_syntax_error(ls, "non-void type expected"); } + eo_lexer_context_pop(ls); return ret; } @@ -235,14 +236,15 @@ static Eolian_Type * parse_type_struct_nonvoid(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon) { - int line = ls->line_number, column = ls->column; - Eolian_Type *ret = parse_type_struct(ls, allow_struct, allow_anon); + Eolian_Type *ret; + eo_lexer_context_push(ls); + ret = parse_type_struct(ls, allow_struct, allow_anon); if (ret->type == EOLIAN_TYPE_VOID) { - ls->line_number = line; - ls->column = column; + eo_lexer_context_restore(ls); eo_lexer_syntax_error(ls, "non-void type expected"); } + eo_lexer_context_pop(ls); return ret; } @@ -355,18 +357,19 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon) } case KW_own: { - int sline = ls->line_number, scolumn = ls->column, line, column; + int line, column; eo_lexer_get(ls); line = ls->line_number; column = ls->column; check_next(ls, '('); + eo_lexer_context_push(ls); def = parse_type_void(ls); if (def->type != EOLIAN_TYPE_POINTER) { - ls->line_number = sline; - ls->column = scolumn; + eo_lexer_context_restore(ls); eo_lexer_syntax_error(ls, "pointer type expected"); } + eo_lexer_context_pop(ls); def->is_own = EINA_TRUE; check_match(ls, ')', '(', line, column); goto parse_ptr; @@ -390,6 +393,7 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon) } /* todo: see typedef */ buf = push_strbuf(ls); + eo_lexer_context_push(ls); line = ls->line_number; col = ls->column; parse_name(ls, buf); @@ -401,13 +405,14 @@ parse_type_struct(Eo_Lexer *ls, Eina_Bool allow_struct, Eina_Bool allow_anon) sname); if (tp) { - ls->line_number = line; - ls->column = col; eina_stringshare_del(sname); + eo_lexer_context_restore(ls); redef_error(ls, EOLIAN_TYPE_STRUCT, tp); } + eo_lexer_context_pop(ls); return parse_struct(ls, sname, is_extern, line, col); } + eo_lexer_context_pop(ls); } else { @@ -498,6 +503,7 @@ parse_typedef(Eo_Lexer *ls) def->type = EOLIAN_TYPE_ALIAS; def->is_extern = is_extern; buf = push_strbuf(ls); + eo_lexer_context_push(ls); def->line = ls->line_number; def->column = ls->column; parse_name(ls, buf); @@ -506,10 +512,10 @@ parse_typedef(Eo_Lexer *ls) Eolian_Type *tp = (Eolian_Type*)eina_hash_find(_aliases, def->full_name); if (tp) { - ls->line_number = def->line; - ls->column = def->column; + eo_lexer_context_restore(ls); redef_error(ls, EOLIAN_TYPE_ALIAS, tp); } + eo_lexer_context_pop(ls); def->file = get_filename(ls); (void)!!test_next(ls, ':'); def->base_type = parse_type_struct_nonvoid(ls, EINA_TRUE, EINA_TRUE); @@ -1161,8 +1167,8 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) } case KW_struct: { - int line, col; const char *name; + int line, col; Eolian_Type *tp; Eina_Bool is_extern = EINA_FALSE; Eina_Strbuf *buf; @@ -1173,6 +1179,7 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) eo_lexer_get(ls); } buf = push_strbuf(ls); + eo_lexer_context_push(ls); line = ls->line_number; col = ls->column; parse_name(ls, buf); @@ -1181,11 +1188,11 @@ parse_unit(Eo_Lexer *ls, Eina_Bool eot) tp = (Eolian_Type*)eina_hash_find(_structs, name); if (tp) { - ls->line_number = line; - ls->column = col; eina_stringshare_del(name); + eo_lexer_context_restore(ls); redef_error(ls, EOLIAN_TYPE_STRUCT, tp); } + eo_lexer_context_pop(ls); pop_strbuf(ls); parse_struct(ls, name, is_extern, line, col); pop_type(ls); -- 2.7.4