icfp11/src/control_parser.rl

117 lines
2.9 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; }
2008-07-12 00:49:03 +00:00
action telemetrystart { }
action vehicle { }
2008-07-12 00:17:29 +00:00
2008-07-12 00:49:03 +00:00
SP = " ";
2008-07-12 00:17:29 +00:00
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); };
2008-07-12 00:39:26 +00:00
2008-07-12 00:49:03 +00:00
init = "I" SP dx SP dy SP double SP min_sensor SP max_sensor SP max_speed SP max_turn SP max_hard_turn SP ";";
x = double;
y = double;
r = double;
dir = double;
speed = double;
ctl = [ab\-] [Ll\-rR];
timestamp = double;
boulder = "b" SP x SP y SP r SP;
crater = "b" SP x SP y SP r SP;
homebase = "b" SP x SP y SP r SP;
martian = "m" SP x SP y SP dir SP speed SP;
object = boulder | crater | homebase | martian;
objects = object*;
telemetry = ( ("T" SP timestamp SP ctl SP x SP y SP dir SP speed SP) %vehicle objects) >telemetrystart ";";
2008-07-12 00:39:26 +00:00
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;
}