#include "parsen.h" #include "gm-parser.h" #include "gm-debug.h" typedef struct _ParserState { GList *code; gchar *line; gint cur_line; gint cur_char; GList *errors; GList *warnings; } ParserState; static void gm_parser_error(void *data, const char *msg) { ParserState *state = (ParserState *)data; GmParserError *r = g_new0(GmParserError, 1); r->line = state->cur_line; r->ch = state->cur_char; r->message = g_strdup(msg); state->errors = g_list_append(state->errors, r); } static void gm_parser_warning(void *data, const char *msg) { ParserState *state = (ParserState *)data; GmParserError *r = g_new0(GmParserError, 1); r->line = state->cur_line; r->ch = state->cur_char; r->message = g_strdup(msg); state->warnings = g_list_append(state->warnings, r); } static int gm_parser_getc(void *data) { ParserState *state = (ParserState *)data; guchar c; gchar *line; if (state->line == NULL) { return EOF; } else if ((c = state->line[state->cur_char]) == '\n' || c == '\0') { state->code = state->code->next; if (state->code != NULL) { state->line = (gchar *)(state->code->data); } else { state->line = NULL; } ++state->cur_line; state->cur_char = 0; return '\n'; } else { ++state->cur_char; return c; } } void gm_parser_init_state(ParserState *state) { state->cur_line = 0; state->cur_char = 0; state->errors = NULL; state->warnings = NULL; } void gm_parser_init_result(GmParserResult *result) { result->isOk = TRUE; result->warnings = NULL; result->errors = NULL; } static Parser_Client list_parser_client = { gm_parser_error, gm_parser_warning, gm_parser_getc }; GmParserResult * gm_parser_parse(GList *code) { ParserState state; GmParserResult *result = g_new0(GmParserResult, 1); gm_parser_init_result(result); if (!code) { return result; } gm_parser_init_state(&state); state.code = code; state.line = (gchar *)(code->data); parse_program(current_version, list_parser_client, &state); result->errors = state.errors; result->warnings = state.warnings; result->isOk = (result->errors == NULL && result->warnings == NULL); return result; } void gm_parser_error_free(GmParserError *error) { g_free(error->message); g_free(error); } void gm_parser_result_free(GmParserResult *result) { GList *item; for (item = result->errors; item; item = item->next) { gm_parser_error_free((GmParserError *)(item->data)); } for (item = result->warnings; item; item = item->next) { gm_parser_error_free((GmParserError *)(item->data)); } g_list_free(result->errors); g_list_free(result->warnings); g_free(result); }