icfp11/src/control_parser.rl

100 lines
2.5 KiB
Plaintext
Raw Normal View History

2008-07-12 00:17:29 +00:00
#include "control_parser.h"
#include <stdlib.h>
#include <stdio.h>
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;
}
static double extract_double(context *ctx, char *fpc) {
extract(ctx, fpc);
return strtod(ctx->tmp->str, NULL);
}
2008-07-12 00:17:29 +00:00
%%{
machine control_parser;
variable cs ctx->cs;
action done { fbreak; }
action mark { ctx->mark = fpc - ctx->buffer->str; }
action parsedouble { ctx->d = extract_double(ctx, fpc); }
2008-07-12 00:17:29 +00:00
sp = " ";
double = (digit | '.')*;
dx = double >mark % { t->map.dx = extract_double(ctx, fpc); };
dy = double >mark % { t->map.dy = extract_double(ctx, fpc); };
min_sensor = double >mark % { t->map.min_sensor = extract_double(ctx, fpc); };
max_sensor = double >mark % { t->map.max_sensor = extract_double(ctx, fpc); };
max_speed = double >mark % { t->map.max_speed = extract_double(ctx, fpc); };
max_turn = double >mark % { t->map.max_turn = extract_double(ctx, fpc); };
max_hard_turn = double >mark % { t->map.max_hard_turn = extract_double(ctx, fpc); };
# I dx dy time_limit min_sensor max_sensor max_speed max_turn max_hard_turn ;
init = "I" sp dx sp dy sp double sp min_sensor sp max_sensor sp max_speed sp max_turn sp max_hard_turn ";";
2008-07-12 00:17:29 +00:00
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;
}