#include "control_parser.h" #include #include typedef control_parser_ctx context; static void extract(context *ctx, char *fpc) { gsize len = (fpc - ctx->buffer->str) - ctx->mark; g_string_truncate(ctx->tmp, 0); g_string_append_len(ctx->tmp, ctx->buffer->str + ctx->mark, len); ctx->read += len; } %%{ machine control_parser; variable cs ctx->cs; action done { fbreak; } action mark { ctx->mark = fpc - ctx->buffer->str; } action parsedouble { extract(ctx, fpc); ctx->d = strtod(ctx->tmp->str, NULL); } sp = " "; double = ( (digit | '.')* ) >mark %parsedouble; init = "I" sp double sp double sp double sp double sp double sp double sp double sp double ";"; main := init @ done; }%% %% write data; static int control_parser_has_error(context *ctx) { return ctx->cs == control_parser_error; } static int control_parser_is_finished(context *ctx) { return ctx->cs >= control_parser_first_final; } void control_parser_new(trial *t) { context *ctx = t->parse_ctx = g_slice_new(context); %% write init; ctx->buffer = g_string_sized_new(0); ctx->tmp = g_string_sized_new(0); } void control_parser_reset(trial *t) { context *ctx = t->parse_ctx; %% write init; g_string_truncate(ctx->tmp, 0); } void control_parser_free(trial *t) { g_string_free(t->parse_ctx->buffer, TRUE); g_string_free(t->parse_ctx->tmp, TRUE); g_slice_free(context, t->parse_ctx); } run_t control_parse(trial *t) { context *ctx = t->parse_ctx; gsize wehave; if (0 < (wehave = ctx->buffer->len - ctx->read)) { char *p, *pe; p = ctx->buffer->str + ctx->read; pe = p + wehave; %% write exec; g_string_erase(ctx->buffer, 0, ctx->read); ctx->mark -= ctx->read; ctx->read = 0; } if (control_parser_has_error(ctx)) { fprintf(stderr, "Parse error\n"); return RUN_ERROR; } if (control_parser_is_finished(ctx)) return RUN_DONE; return RUN_GO_ON; }