working on parsing glider

This commit is contained in:
Neil 2023-02-12 22:21:42 -08:00
parent aec01b255e
commit 1c2872cab6
4 changed files with 70 additions and 14 deletions

View File

@ -26,7 +26,7 @@ static const char *flight_type_string[] = { FLIGHT_TYPE };
#include "pair.h" #include "pair.h"
struct glider { struct glider {
struct pair type, reg, launch; struct pair type, reg, launch, landing;
enum launch_type how; enum launch_type how;
unsigned height_ft, pilot_min, dual_min, instr_min; unsigned height_ft, pilot_min, dual_min, instr_min;
struct pair remarks; struct pair remarks;
@ -64,7 +64,7 @@ struct flight_tree_iterator { struct tree_flight_iterator _; };
|| !defined BASE && !defined GENERIC && !defined PROTO /* <!-- proto */ || !defined BASE && !defined GENERIC && !defined PROTO /* <!-- proto */
#include <stddef.h> #include <stddef.h>
struct flights { struct flight_tree _; }; struct flights { struct flight_tree _; };
struct flight *flights_add(struct flights *, const union line64); /*struct flight *flights_add(struct flights *, const union line64);*/
struct flights flights(/*const*/ struct journal *); struct flights flights(/*const*/ struct journal *);
void flights_(struct flights *); void flights_(struct flights *);
const char *flights_to_string(const struct flights *); const char *flights_to_string(const struct flights *);

View File

@ -29,7 +29,7 @@ static int flight_compare(const union line64 a, const union line64 b)
static int scan(struct flights *const f, static int scan(struct flights *const f,
union date32 date, const char *const text) { union date32 date, const char *const text) {
const char *YYCURSOR, *YYMARKER, *yyt1, *yyt2, *s0, *s1; const char *YYCURSOR, *YYMARKER, *yyt1, *yyt2, *yyt3, *s0, *s1, *t0, *t1;
enum YYCONDTYPE condition = yycline; enum YYCONDTYPE condition = yycline;
size_t line = 1; size_t line = 1;
char datestr[12] = {0}; char datestr[12] = {0};
@ -50,6 +50,7 @@ static int scan(struct flights *const f,
glyph = [^\x00-\x20\x7f]; // [^\n\t ] + all the other weird glyph = [^\x00-\x20\x7f]; // [^\n\t ] + all the other weird
semitext = glyph \ ";"; semitext = glyph \ ";";
natural = [1-9][0-9]*; natural = [1-9][0-9]*;
airport = [A-Z0-9]{4,4};
*/ */
for( ; ; ) { /*!re2c /**/ for( ; ; ) { /*!re2c /**/
/* Default ignore. */ /* Default ignore. */
@ -67,13 +68,19 @@ static int scan(struct flights *const f,
single engine day dual; pilot; instrument simulated; actual; remarks */ single engine day dual; pilot; instrument simulated; actual; remarks */
<flight> * { why = "default unrecognized"; goto catch; } <flight> * { why = "default unrecognized"; goto catch; }
/* type, reg, launch, how, height, landing, pilot, dual, instr, remarks
eg, [glider] 2-33A; C-GCLK; CYQQ; A; 2000'; CYQQ; ;:13;; Peters D1 */
<glider_type> * { why = "type unrecognized"; goto catch; } <glider_type> * { why = "type unrecognized"; goto catch; }
<glider_reg> * { why = "reg unrecognized"; goto catch; } <glider_reg> * { why = "reg unrecognized"; goto catch; }
<glider_launch> * { why = "launch unrecognized"; goto catch; } <glider_launch> * { why = "launch unrecognized"; goto catch; }
<glider_how> * { why = "how unrecognized"; goto catch; }
<glider_height> * { why = "height unrecognized"; goto catch; }
<glider_landing> * { why = "landing unrecognized"; goto catch; }
<glider_pilot> * { why = "pilot unrecognized"; goto catch; }
<glider_dual> * { why = "dual unrecognized"; goto catch; }
<glider_instr> * { why = "instr unrecognized"; goto catch; }
<glider_err> * { why = "planned"; goto catch; } <glider_err> * { why = "planned"; goto catch; }
/* type, reg, launch, how, height, landing, pilot, dual, instr, remarks
[glider] 2-33A; C-GCLK; CYQQ; A; 2000'; CYQQ; ;:13;; Peters D1 */
<glider_type> ws* @s0 semitext+ @s1 ws* ";" => glider_reg { <glider_type> ws* @s0 semitext+ @s1 ws* ";" => glider_reg {
const union line64 key const union line64 key
= {{ (uint32_t)line, {{ date.day, date.month, date.year }} }}; = {{ (uint32_t)line, {{ date.day, date.month, date.year }} }};
@ -85,15 +92,52 @@ static int scan(struct flights *const f,
case TREE_ABSENT: flight->type = GLIDER; break; case TREE_ABSENT: flight->type = GLIDER; break;
} }
flight->glider.type.a = s0, flight->glider.type.b = s1; flight->glider.type.a = s0, flight->glider.type.b = s1;
continue;
} }
<glider_reg> ws* @s0 semitext+ @s1 ws* ";" => glider_launch { <glider_reg> ws* @s0 semitext+ @s1 ws* ";" => glider_launch
assert(flight && flight->type == GLIDER); { flight->glider.reg.a = s0, flight->glider.reg.b = s1; continue; }
<glider_launch> ws* @s0 airport @s1 ws* ";" => glider_how
{ flight->glider.launch.a = s0, flight->glider.launch.b = s1;
continue; }
<glider_how> ws* @s0 [MWA] ws* ";" => glider_height {
switch(*s0) {
case 'M': flight->glider.how = MotorCarTow; break;
case 'W': flight->glider.how = Winch; break;
case 'A': flight->glider.how = AeroTow; break;
default: assert(0); break;
}
continue;
} }
<glider_launch> ws* @s0 semitext+ @s1 *ws* ";" => glider_err { <glider_height> ws* @s0 natural @s1 "'" ws* ";" => glider_landing
{ if(!pair_to_natural(s0, s1, &flight->glider.height_ft));
continue; }
<glider_landing> ws* @s0 airport @s1 ws* ";" => glider_pilot
{ flight->glider.landing.a = s0, flight->glider.landing.b = s1;
continue; }
<glider_pilot> ws* ";" => glider_dual /* not PIC */
{ flight->glider.pilot_min = 0; continue; }
<glider_pilot> ws* @s0 natural? @s1 ":" @t0 natural @t1 ws* ";"
=> glider_dual {
if(!pair_to_minutes(s0, s1, t0, t1, &flight->glider.pilot_min))
{ why = "pilot time"; goto catch; }
continue;
}
<glider_dual> ws* ";" => glider_instr
{ flight->glider.dual_min = 0; continue; }
<glider_dual> ws* @s0 natural? @s1 ":" @t0 natural @t1 ws* ";"
=> glider_instr {
if(!pair_to_minutes(s0, s1, t0, t1, &flight->glider.dual_min))
{ why = "dual time"; goto catch; }
continue;
}
<glider_instr> ws* ";" => glider_err /* not PIC */
{ flight->glider.instr_min = 0; continue; }
<glider_instr> ws* @s0 natural? @s1 ":" @t0 natural @t1 ws* ";"
=> glider_err {
if(!pair_to_minutes(s0, s1, t0, t1, &flight->glider.instr_min))
{ why = "instr time"; goto catch; }
continue;
} }
/* "M" - Motor Car Tow
"W" - Winch
"A" - Aero Tow */
*/ } */ }
assert(0); /* Never gets here. */ assert(0); /* Never gets here. */
catch: catch:
@ -126,6 +170,7 @@ finally:
return f; return f;
} }
#if 0
struct flight *flights_add(struct flights *const flights, struct flight *flights_add(struct flights *const flights,
const union line64 line) { const union line64 line) {
struct flight *flight; struct flight *flight;
@ -137,3 +182,4 @@ struct flight *flights_add(struct flights *const flights,
case TREE_ABSENT: return flight; case TREE_ABSENT: return flight;
} }
} }
#endif

View File

@ -27,8 +27,16 @@ int pair_to_natural(const char *s, const char *const e, uint32_t *const n) {
accum = next; accum = next;
s++; s++;
} }
*n = accum; return *n = accum, 1;
return 1; }
/** `h0` "1" `h1` ":" `m0` "30" `m1` -> 90 `n` @return Valid. */
int pair_to_minutes(const char *h0, const char *const h1,
const char *m0, const char *const m1, uint32_t *const n) {
uint32_t hours, minutes;
return pair_to_natural(h0, h1, &hours) && pair_to_natural(m0, m1, &minutes)
&& minutes < 60 && hours <= UINT32_MAX / 60 - minutes
? (*n = hours * 60 + minutes, 1) : 0;
} }
int pair_is_equal(struct pair x, struct pair y) { int pair_is_equal(struct pair x, struct pair y) {

View File

@ -6,6 +6,8 @@
struct pair { const char *a, *b; }; struct pair { const char *a, *b; };
struct pair pair(const char *const a, const char *const b); struct pair pair(const char *const a, const char *const b);
int pair_to_natural(const char *, const char *, uint32_t *); int pair_to_natural(const char *, const char *, uint32_t *);
int pair_to_minutes(const char *, const char *, const char *, const char *,
uint32_t *);
int pair_is_equal(struct pair, struct pair); int pair_is_equal(struct pair, struct pair);
int pair_is_string(struct pair, const char *); int pair_is_string(struct pair, const char *);
uint32_t pair_djb2(const struct pair p); uint32_t pair_djb2(const struct pair p);