diff --git a/src/control.h b/src/control.h index 8d7fbc3..1cd3190 100644 --- a/src/control.h +++ b/src/control.h @@ -66,6 +66,7 @@ struct trial { timestamp last_ts; GQueue telemetry; vehicle vehicle; /* our view */ + int alive; /* internal */ int socket; diff --git a/src/control_parser.c b/src/control_parser.c new file mode 100644 index 0000000..cc31bf0 --- /dev/null +++ b/src/control_parser.c @@ -0,0 +1,285 @@ +#line 1 "control_parser.rl" + +#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; +} + +static double extract_double(context *ctx, char *fpc) { + extract(ctx, fpc); + return strtod(ctx->tmp->str, NULL); +} + +#line 45 "control_parser.rl" + + + +#line 27 "control_parser.c" +static const char _control_parser_actions[] = { + 0, 1, 1, 1, 2, 1, 3, 1, + 4, 1, 5, 1, 6, 1, 7, 2, + 1, 2, 2, 1, 3, 2, 1, 4, + 2, 1, 5, 2, 1, 6, 2, 1, + 7, 2, 8, 0, 3, 1, 8, 0 + +}; + +static const char _control_parser_key_offsets[] = { + 0, 0, 1, 2, 6, 10, 14, 18, + 22, 26, 30, 34, 38, 42, 46, 50, + 54, 58, 62 +}; + +static const char _control_parser_trans_keys[] = { + 73, 32, 32, 46, 48, 57, 32, 46, + 48, 57, 32, 46, 48, 57, 32, 46, + 48, 57, 32, 46, 48, 57, 32, 46, + 48, 57, 32, 46, 48, 57, 46, 59, + 48, 57, 46, 59, 48, 57, 32, 46, + 48, 57, 32, 46, 48, 57, 32, 46, + 48, 57, 32, 46, 48, 57, 32, 46, + 48, 57, 32, 46, 48, 57, 0 +}; + +static const char _control_parser_single_lengths[] = { + 0, 1, 1, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 0 +}; + +static const char _control_parser_range_lengths[] = { + 0, 0, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0 +}; + +static const char _control_parser_index_offsets[] = { + 0, 0, 2, 4, 8, 12, 16, 20, + 24, 28, 32, 36, 40, 44, 48, 52, + 56, 60, 64 +}; + +static const char _control_parser_trans_targs[] = { + 2, 0, 3, 0, 4, 17, 17, 0, + 5, 16, 16, 0, 6, 5, 5, 0, + 7, 15, 15, 0, 8, 14, 14, 0, + 9, 13, 13, 0, 10, 12, 12, 0, + 11, 18, 11, 0, 11, 18, 11, 0, + 10, 12, 12, 0, 9, 13, 13, 0, + 8, 14, 14, 0, 7, 15, 15, 0, + 5, 16, 16, 0, 4, 17, 17, 0, + 0, 0 +}; + +static const char _control_parser_trans_actions[] = { + 0, 0, 0, 0, 15, 1, 1, 0, + 18, 1, 1, 0, 0, 0, 0, 0, + 21, 1, 1, 0, 24, 1, 1, 0, + 27, 1, 1, 0, 30, 1, 1, 0, + 1, 36, 1, 0, 0, 33, 0, 0, + 13, 0, 0, 0, 11, 0, 0, 0, + 9, 0, 0, 0, 7, 0, 0, 0, + 5, 0, 0, 0, 3, 0, 0, 0, + 0, 0 +}; + +static const int control_parser_start = 1; +static const int control_parser_first_final = 18; +static const int control_parser_error = 0; + +static const int control_parser_en_main = 1; + +#line 48 "control_parser.rl" + +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); + +#line 115 "control_parser.c" + { + ( ctx->cs) = control_parser_start; + } +#line 60 "control_parser.rl" + 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; + +#line 127 "control_parser.c" + { + ( ctx->cs) = control_parser_start; + } +#line 67 "control_parser.rl" + 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; + + +#line 152 "control_parser.c" + { + int _klen; + unsigned int _trans; + const char *_acts; + unsigned int _nacts; + const char *_keys; + + if ( p == pe ) + goto _test_eof; + if ( ( ctx->cs) == 0 ) + goto _out; +_resume: + _keys = _control_parser_trans_keys + _control_parser_key_offsets[( ctx->cs)]; + _trans = _control_parser_index_offsets[( ctx->cs)]; + + _klen = _control_parser_single_lengths[( ctx->cs)]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + _klen - 1; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + ((_upper-_lower) >> 1); + if ( (*p) < *_mid ) + _upper = _mid - 1; + else if ( (*p) > *_mid ) + _lower = _mid + 1; + else { + _trans += (_mid - _keys); + goto _match; + } + } + _keys += _klen; + _trans += _klen; + } + + _klen = _control_parser_range_lengths[( ctx->cs)]; + if ( _klen > 0 ) { + const char *_lower = _keys; + const char *_mid; + const char *_upper = _keys + (_klen<<1) - 2; + while (1) { + if ( _upper < _lower ) + break; + + _mid = _lower + (((_upper-_lower) >> 1) & ~1); + if ( (*p) < _mid[0] ) + _upper = _mid - 2; + else if ( (*p) > _mid[1] ) + _lower = _mid + 2; + else { + _trans += ((_mid - _keys)>>1); + goto _match; + } + } + _trans += _klen; + } + +_match: + ( ctx->cs) = _control_parser_trans_targs[_trans]; + + if ( _control_parser_trans_actions[_trans] == 0 ) + goto _again; + + _acts = _control_parser_actions + _control_parser_trans_actions[_trans]; + _nacts = (unsigned int) *_acts++; + while ( _nacts-- > 0 ) + { + switch ( *_acts++ ) + { + case 0: +#line 26 "control_parser.rl" + { {p++; goto _out; } } + break; + case 1: +#line 27 "control_parser.rl" + { ctx->mark = p - ctx->buffer->str; } + break; + case 2: +#line 34 "control_parser.rl" + { t->map.dx = extract_double(ctx, p); } + break; + case 3: +#line 35 "control_parser.rl" + { t->map.dy = extract_double(ctx, p); } + break; + case 4: +#line 36 "control_parser.rl" + { t->map.min_sensor = extract_double(ctx, p); } + break; + case 5: +#line 37 "control_parser.rl" + { t->map.max_sensor = extract_double(ctx, p); } + break; + case 6: +#line 38 "control_parser.rl" + { t->map.max_speed = extract_double(ctx, p); } + break; + case 7: +#line 39 "control_parser.rl" + { t->map.max_turn = extract_double(ctx, p); } + break; + case 8: +#line 40 "control_parser.rl" + { t->map.max_hard_turn = extract_double(ctx, p); } + break; +#line 261 "control_parser.c" + } + } + +_again: + if ( ( ctx->cs) == 0 ) + goto _out; + if ( ++p != pe ) + goto _resume; + _test_eof: {} + _out: {} + } +#line 87 "control_parser.rl" + + 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; +} diff --git a/src/control_parser.rl b/src/control_parser.rl index 500f00a..483c861 100644 --- a/src/control_parser.rl +++ b/src/control_parser.rl @@ -13,6 +13,11 @@ static void extract(context *ctx, char *fpc) { ctx->read += len; } +static double extract_double(context *ctx, char *fpc) { + extract(ctx, fpc); + return strtod(ctx->tmp->str, NULL); +} + %%{ machine control_parser; @@ -20,16 +25,21 @@ static void extract(context *ctx, char *fpc) { action done { fbreak; } action mark { ctx->mark = fpc - ctx->buffer->str; } - action parsedouble { - extract(ctx, fpc); - ctx->d = strtod(ctx->tmp->str, NULL); - } + action parsedouble { ctx->d = extract_double(ctx, fpc); } sp = " "; - double = ( (digit | '.')* ) >mark %parsedouble; - - init = "I" sp double sp double sp double sp double sp double sp double sp double sp double ";"; + 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 ";"; main := init @ done; }%% diff --git a/src/wscript b/src/wscript index be103bc..901738f 100644 --- a/src/wscript +++ b/src/wscript @@ -6,7 +6,7 @@ main_source = ''' main.c control.c - control_parser.rl + control_parser.c path.c ''' diff --git a/wscript b/wscript index a40f3da..6a2c943 100644 --- a/wscript +++ b/wscript @@ -62,17 +62,18 @@ def PKGCONFIG(conf, name, uselib = None, define = '', version = '', mandatory = def set_options(opt): opt.tool_options('compiler_cc') - opt.tool_options('ragel', tooldir = '.') + #opt.tool_options('ragel', tooldir = '.') def configure(conf): conf.check_tool('compiler_cc') - conf.check_tool('ragel', tooldir = '.') + #conf.check_tool('ragel', tooldir = '.') common_ccflags = [ '-std=gnu99', '-Wall', '-g', '-Wshadow', '-W', '-pedantic', # '-fPIC', '-D_GNU_SOURCE', ] conf.env['CCFLAGS'] += common_ccflags + conf.env['LIB'] += ['m'] PKGCONFIG(conf, "glib-2.0", uselib = 'glib', mandatory = 1) incdir = conf.env['CPPPATH_glib'][0]