caption
This commit is contained in:
parent
2caa6f458b
commit
7c2c4785e4
@ -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);
|
||||
|
23
src/lex.h
23
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
|
||||
|
@ -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 <fn:lex_next> and <fn:expect_pop>. */
|
||||
#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; }
|
||||
<line> sentinel { return x->symbol = END, 0; }
|
||||
<text, text, image, edict, edict_keyword, edict_date, edict_freeform, edict_end>
|
||||
<text, expect_line, expect_caption, text, image, edict, edict_keyword, edict_date, edict_freeform, edict_end>
|
||||
sentinel { return x->symbol = ILLEGAL, 0; }
|
||||
<expect_line> newline => line { x->line = ++scan.line; goto scan; }
|
||||
<line> newline { x->line = ++scan.line; return x->symbol = PARAGRAPH, 1; }
|
||||
<line> "![" :=> image
|
||||
<line> "--" :=> source
|
||||
<line> "->" :=> location
|
||||
<line> "[" :=> edict
|
||||
<line> "" / glyph :=> text
|
||||
<line> * { return x->symbol = SYNTAX, 1; }
|
||||
<expect_caption> 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; }
|
||||
|
||||
<text> newline => line { x->line = ++scan.line; goto scan; }
|
||||
<text> ws+ { goto scan; }
|
||||
<text> @s0 glyph+ @s1 { x->s0 = s0, x->s1 = s1;
|
||||
return x->symbol = TEXT, 1; }
|
||||
<text> @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];
|
||||
<source> @s0 keyword @s1 => expect_line
|
||||
{ x->s0 = s0, x->s1 = s1; return x->symbol = SOURCE_RECALL, 1; }
|
||||
|
||||
<image> 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;
|
||||
}
|
||||
<image> * { printf("image(broken)\n");return 0; }
|
||||
<location> "" / "![" :=> map
|
||||
<location> @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];
|
||||
<map> "![" ws* "osm" ws* "](geo:" @s0 decimal "," @s1 decimal ")" ws*
|
||||
=> expect_caption
|
||||
{ x->s0 = s0, x->s1 = s1; return x->symbol = LOCATION, 1; }
|
||||
|
||||
<edict> "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
|
||||
<edict> "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; }
|
||||
|
||||
<edict> ws+ { scan.is_ws_expected = 0; goto scan; }
|
||||
<edict> ":"
|
||||
{ if(!scan.edict.size) return x->symbol = SYNTAX, 0;
|
||||
scan.is_ws_expected = 0, scan.is_source = 0;
|
||||
expect_pop(); goto scan; }
|
||||
<! edict_keyword, edict_date, edict_freeform> { expect_pop(); }
|
||||
<edict_keyword> ws* @s0 id @s1 ws* ";"? / "]"?
|
||||
{ x->s0 = s0, x->s1 = s1;
|
||||
<edict_keyword> ws* @s0 keyword @s1 ws* ";"?
|
||||
{ x->s0 = s0, x->s1 = s1; expect_pop();
|
||||
return x->symbol = ARG_KEYWORD, 1; }
|
||||
<edict_date> ws* @s0 date @s1 ws* ";"? / "]"?
|
||||
{ x->s0 = s0, x->s1 = s1;
|
||||
<edict_date> ws* @s0 date @s1 ws* ";"?
|
||||
{ x->s0 = s0, x->s1 = s1; expect_pop();
|
||||
return x->symbol = ARG_DATE, 1; }
|
||||
<edict_natural> ws* @s0 natural @s1 ws* ";"?
|
||||
{ x->s0 = s0, x->s1 = s1; expect_pop();
|
||||
return x->symbol = ARG_NATURAL, 1; }
|
||||
// fixme!
|
||||
<edict_freeform> 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; }
|
||||
<edict, edict_end> "]" => text
|
||||
{ if(scan.edict.size) return 0;
|
||||
goto scan; }
|
||||
{ if(scan.edict.size) return 0; goto scan; }
|
||||
<edict, edict_keyword, edict_date, edict_freeform, edict_end> *
|
||||
{ return x->symbol = SYNTAX, 0; }
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user