This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
gnoemoe/gnoemoe/parser/gm-parser.c

132 lines
2.6 KiB
C

#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);
}