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"
struct glider {
struct pair type, reg, launch;
struct pair type, reg, launch, landing;
enum launch_type how;
unsigned height_ft, pilot_min, dual_min, instr_min;
struct pair remarks;
@ -64,7 +64,7 @@ struct flight_tree_iterator { struct tree_flight_iterator _; };
|| !defined BASE && !defined GENERIC && !defined PROTO /* <!-- proto */
#include <stddef.h>
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 *);
void flights_(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,
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;
size_t line = 1;
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
semitext = glyph \ ";";
natural = [1-9][0-9]*;
airport = [A-Z0-9]{4,4};
*/
for( ; ; ) { /*!re2c /**/
/* Default ignore. */
@ -67,13 +68,19 @@ static int scan(struct flights *const f,
single engine day dual; pilot; instrument simulated; actual; remarks */
<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_reg> * { why = "reg 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; }
/* 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 {
const union line64 key
= {{ (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;
}
flight->glider.type.a = s0, flight->glider.type.b = s1;
continue;
}
<glider_reg> ws* @s0 semitext+ @s1 ws* ";" => glider_launch {
assert(flight && flight->type == GLIDER);
<glider_reg> ws* @s0 semitext+ @s1 ws* ";" => glider_launch
{ 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. */
catch:
@ -126,6 +170,7 @@ finally:
return f;
}
#if 0
struct flight *flights_add(struct flights *const flights,
const union line64 line) {
struct flight *flight;
@ -137,3 +182,4 @@ struct flight *flights_add(struct flights *const flights,
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;
s++;
}
*n = accum;
return 1;
return *n = accum, 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) {

View File

@ -6,6 +6,8 @@
struct pair { const char *a, *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_minutes(const char *, const char *, const char *, const char *,
uint32_t *);
int pair_is_equal(struct pair, struct pair);
int pair_is_string(struct pair, const char *);
uint32_t pair_djb2(const struct pair p);