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;
|
|
|
|
}
|
|
|
|
|
2008-07-12 00:29:17 +00:00
|
|
|
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:29:17 +00:00
|
|
|
action parsedouble { ctx->d = extract_double(ctx, fpc); }
|
2008-07-12 00:17:29 +00:00
|
|
|
|
|
|
|
sp = " ";
|
|
|
|
|
2008-07-12 00:29:17 +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:29:17 +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 ";";
|
2008-07-12 00:17:29 +00:00
|
|
|
|
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;
|
|
|
|
}
|