From 7c2c4785e41dcc1aab48c42e59d01961aa44e84c Mon Sep 17 00:00:00 2001 From: Neil Date: Tue, 15 Feb 2022 19:48:50 -0800 Subject: [PATCH] caption --- src/interpret.c | 2 +- src/lex.h | 23 ++++++++++----- src/lex.re_c.c | 74 +++++++++++++++++++++++++++---------------------- 3 files changed, 58 insertions(+), 41 deletions(-) diff --git a/src/interpret.c b/src/interpret.c index 1a46365..1966c86 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -146,8 +146,8 @@ int main(int argc, char **argv) { } printf("Lexing finished: %s on %lu.\n", lex_symbols[lex.symbol], lex.line); + if(lex.symbol != END) { errno = EILSEQ; goto catch; } char_array_clear(&entry); - break; /* fixme */ } int_array_clear(&days); diff --git a/src/lex.h b/src/lex.h index 432dbab..18500a1 100644 --- a/src/lex.h +++ b/src/lex.h @@ -5,20 +5,29 @@ int lex_looks_like_month(const char *); int lex_looks_like_day(const char *); #define LEX_SYMBOL \ - /* Results. */ X(END), X(SYNTAX), X(ILLEGAL), X(NOT_FOUND), \ - /* Text. */ X(PARAGRAPH), X(TEXT), \ - /* Edicts. */ X(SOURCE), X(DEFAULT), X(SIGNIFICANT), X(SCORE), X(MAP), \ - /* Arguments. */ X(ARG_KEYWORD), X(ARG_DATE), X(ARG_NATURAL), \ - X(ARG_FREEFORM) + \ + /* Results. */ \ + X(END), X(SYNTAX), X(ILLEGAL), X(NOT_FOUND), \ + \ + /* Text. */ \ + X(PARAGRAPH), X(TEXT), X(CAPTION), \ + \ + /* Edicts. */ \ + X(SOURCE), X(DEFAULT), X(SOURCE_RECALL), \ + X(LOCATION), X(LOCATION_RECALL), \ + X(SIGNIFICANT), X(SIGNIFICANT_RECALL), \ + \ + /* Arguments. */ \ + X(ARG_KEYWORD), X(ARG_DATE), X(ARG_NATURAL), X(ARG_FREEFORM) -#define X(n) n struct lex { +#define X(n) n enum lex_symbol { LEX_SYMBOL } symbol; +#undef X int ws_before, new_paragraph; const char *s0, *s1; size_t line; }; -#undef X #define X(n) #n static const char *const lex_symbols[] = { LEX_SYMBOL }; #undef X diff --git a/src/lex.re_c.c b/src/lex.re_c.c index 24aff9a..8d6a506 100644 --- a/src/lex.re_c.c +++ b/src/lex.re_c.c @@ -72,7 +72,7 @@ int lex_looks_like_day(const char *const a) { /* "[edict: expect; there; to; be; args]", in this case, expect would be a stack of `size = 5` `EXPECT_KEYWORD`. This mirrors arguments in `LEX_SYMBOL` and should also be an `edict_*` in and . */ -#define EXPECT_HEAD X(keyword, KEYWORD) X(date, DATE) +#define EXPECT_HEAD X(keyword, KEYWORD) X(date, DATE) X(natural, NATURAL) #define EXPECT_CONS Y(freeform, FREEFORM) #define EXPECT EXPECT_HEAD EXPECT_CONS @@ -125,6 +125,15 @@ int lex_next(struct lex *const x) { re2c:define:YYGETCONDITION:naked = 1; re2c:define:YYSETCONDITION = 'scan.condition = @@;'; re2c:define:YYSETCONDITION:naked = 1; + sentinel = "\x00"; + illegal = [\x01-\x08\x0a-\x1f\x7f]; // unix-style control characters + newline = "\n"; + ws = [ \t]; + glyph = [^\x00-\x1f \x7f]; + keyword = [a-zA-Z_][a-zA-Z0-9_\-]{0,63}; + decimal = "-"? ([1-9][0-9]* | [0])? "." [0-9]+ | [1-9][0-9]* | [0]; + natural = [1-9][0-9]*; + date = "-"? natural "-" [0-1][0-9] "-" [0-1][0-9]; */ const char *s0, *s1; /*!stags:re2c format = 'const char *@@;\n'; */ @@ -133,39 +142,36 @@ int lex_next(struct lex *const x) { x->s0 = x->s1 = 0; scan: /*!re2c - sentinel = "\x00"; - illegal = [\x01-\x08\x0a-\x1f\x7f]; // unix-style control characters - newline = "\n"; - ws = [ \t]; - glyph = [^\x00-\x1f \x7f]; <*> illegal { return x->symbol = ILLEGAL, 0; } + <*> * { return x->symbol = SYNTAX, 0; } sentinel { return x->symbol = END, 0; } - + sentinel { return x->symbol = ILLEGAL, 0; } + newline => line { x->line = ++scan.line; goto scan; } newline { x->line = ++scan.line; return x->symbol = PARAGRAPH, 1; } - "![" :=> image + "--" :=> source + "->" :=> location "[" :=> edict "" / glyph :=> text - * { return x->symbol = SYNTAX, 1; } + ws* @s0 ([^] \ (sentinel | illegal | newline | ws)) + ([^] \ (sentinel | illegal | newline))* @s1 ws* / newline => expect_line + { x->s0 = s0, x->s1 = s1; return x->symbol = CAPTION, 1; } newline => line { x->line = ++scan.line; goto scan; } ws+ { goto scan; } - @s0 glyph+ @s1 { x->s0 = s0, x->s1 = s1; - return x->symbol = TEXT, 1; } + @s0 glyph+ @s1 + { x->s0 = s0, x->s1 = s1; return x->symbol = TEXT, 1; } - decimal = "-"? ([1-9][0-9]* | [0])? "." [0-9]+ | [1-9][0-9]* | [0]; + @s0 keyword @s1 => expect_line + { x->s0 = s0, x->s1 = s1; return x->symbol = SOURCE_RECALL, 1; } - ws* "osm" ws* "](geo:" @s0 decimal "," @s1 decimal ")" => text { - x->symbol = MAP, x->s0 = s0, x->s1 = s1; - printf("Got a map.\n"); - return 1; - } - * { printf("image(broken)\n");return 0; } + "" / "![" :=> map + @s0 keyword @s1 => expect_line + { x->s0 = s0, x->s1 = s1; return x->symbol = LOCATION_RECALL, 1; } - // - natural = [1-9][0-9]*; - id = [a-zA-Z_][a-zA-Z_\-0-9]{0,63}; - date = "-"? natural "-" [0-1][0-9] "-" [0-1][0-9]; + "![" ws* "osm" ws* "](geo:" @s0 decimal "," @s1 decimal ")" ws* + => expect_caption + { x->s0 = s0, x->s1 = s1; return x->symbol = LOCATION, 1; } "source" { if(scan.is_ws_expected || scan.edict.size) @@ -181,12 +187,12 @@ scan: scan.is_ws_expected = 1, scan.is_source = 0; return x->symbol = DEFAULT, 1; } - // score "significant" { if(scan.is_ws_expected || scan.edict.size) return x->symbol = SYNTAX, 0; scan.is_ws_expected = 1; - scan.edict.size = 2; + scan.edict.size = 3; + scan.edict.expect[2] = EXPECT_NATURAL; scan.edict.expect[1] = EXPECT_FREEFORM; scan.edict.expect[0] = EXPECT_DATE; return x->symbol = SIGNIFICANT, 1; } @@ -195,28 +201,30 @@ scan: return x->symbol = SYNTAX, 0; scan.is_ws_expected = 1; x->s0 = s0, x->s1 = s1; - return x->symbol = SCORE, 1; } + return x->symbol = SIGNIFICANT_RECALL, 1; } ws+ { scan.is_ws_expected = 0; goto scan; } ":" { if(!scan.edict.size) return x->symbol = SYNTAX, 0; scan.is_ws_expected = 0, scan.is_source = 0; expect_pop(); goto scan; } - { expect_pop(); } - ws* @s0 id @s1 ws* ";"? / "]"? - { x->s0 = s0, x->s1 = s1; + ws* @s0 keyword @s1 ws* ";"? + { x->s0 = s0, x->s1 = s1; expect_pop(); return x->symbol = ARG_KEYWORD, 1; } - ws* @s0 date @s1 ws* ";"? / "]"? - { x->s0 = s0, x->s1 = s1; + ws* @s0 date @s1 ws* ";"? + { x->s0 = s0, x->s1 = s1; expect_pop(); return x->symbol = ARG_DATE, 1; } + ws* @s0 natural @s1 ws* ";"? + { x->s0 = s0, x->s1 = s1; expect_pop(); + return x->symbol = ARG_NATURAL, 1; } + // fixme! ws* @s0 [^ \t\n\r\v\f;[\]\x00][^\t\n\r\v\f;[\]\x00]*[^ \t\n\r\v\f;[\]\x00]* @s1 ws* ";"? / "]"? - { x->s0 = s0, x->s1 = s1; + { x->s0 = s0, x->s1 = s1; expect_pop(); return x->symbol = ARG_FREEFORM, 1; } "]" => text - { if(scan.edict.size) return 0; - goto scan; } + { if(scan.edict.size) return 0; goto scan; } * { return x->symbol = SYNTAX, 0; } */