diff --git a/src/lex.h b/src/lex.h index 436f779..432dbab 100644 --- a/src/lex.h +++ b/src/lex.h @@ -6,9 +6,10 @@ 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), \ - /* Directive. */ X(SOURCE), X(DEFAULT), X(SIGNIFICANT), X(SCORE), X(MAP), \ - /* Arguments. */ X(ARG_KEYWORD), X(ARG_DATE), X(ARG_NATURAL), X(ARG_FREEFORM) + /* 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) #define X(n) n struct lex { diff --git a/src/lex.re_c.c b/src/lex.re_c.c index 3182503..cc34f5a 100644 --- a/src/lex.re_c.c +++ b/src/lex.re_c.c @@ -20,7 +20,7 @@ re2c:define:YYCTYPE = char; int lex_looks_like_year(const char *const a, int *const year) { const char *YYCURSOR = a, *YYMARKER = a, *s0; /*!stags:re2c format = 'const char *@@;\n'; */ - (void)yyt1; + (void)yyt2, (void)yyt3; assert(a && year); /*!re2c @s0 ("-"? [1-9][0-9]* | "0") "\x00" { @@ -41,6 +41,7 @@ int lex_looks_like_year(const char *const a, int *const year) { int lex_looks_like_month(const char *const a) { const char *YYCURSOR = a, *YYMARKER = a, *s0; /*!stags:re2c format = 'const char *@@;\n'; */ + (void)yyt1, (void)yyt2, (void)yyt3; assert(a); /*!re2c @s0 [0-1][0-9] "\x00" { @@ -54,6 +55,7 @@ int lex_looks_like_month(const char *const a) { int lex_looks_like_day(const char *const a) { const char *YYCURSOR = a, *YYMARKER = a, *s0; /*!stags:re2c format = 'const char *@@;\n'; */ + (void)yyt1, (void)yyt2, (void)yyt3; assert(a); /*!re2c @s0 [0-3][0-9] ".txt\x00" { @@ -67,7 +69,12 @@ int lex_looks_like_day(const char *const a) { /* This defines `enum condition`. */ /*!types:re2c*/ -#define EXPECT X(KEYWORD), X(DATE), X(FREEFORM) +/* "[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_CONS Y(freeform, FREEFORM) +#define EXPECT EXPECT_HEAD EXPECT_CONS /** scanner reads a file and extracts semantic information. Valid to access only while underlying pointers do not change. */ @@ -79,29 +86,31 @@ static struct scan { enum condition condition; size_t line; int is_ws_expected, is_source; -#define X(n) EXPECT_ ## n - /* "[something: expect; there; to; be; args]", in this case, expect would - be a stack of `size = 5` `EXPECT_KEYWORD`. */ +#define X(n, N) EXPECT_ ## N, +#define Y(n, N) EXPECT_ ## N struct { unsigned size; enum { EXPECT } expect[16]; } edict; #undef X -} scan; /* Terrible, gah. */ +#undef Y +} scan; /* Not suited for concurrency. Simple. */ +/** Resets the buffer to some `buffer`. */ void lex_reset(const char *const buffer) { scan.marker = scan.ctx_marker = scan.from = scan.cursor = scan.label = scan.buffer = buffer; - scan.condition = 0; + scan.condition = yycline; scan.line = 1; } /** I don't think `re2c` supports branching on variable conditions. It does now? */ static void expect_pop(void) { - printf(""); - if(!scan.edict.size) { printf("allfinished\n"); scan.condition = yycedict_end; return; } + if(!scan.edict.size) { scan.condition = yycedict_end; return; } switch(scan.edict.expect[--scan.edict.size]) { - case EXPECT_KEYWORD: printf("keyword\n");scan.condition = yycedict_keyword; break; - case EXPECT_DATE: printf("date\n");scan.condition = yycedict_date; break; - case EXPECT_FREEFORM: printf("freeform\n");scan.condition = yycedict_freeform; break; +#define X(n, N) case EXPECT_ ## N : scan.condition = yycedict_ ## n; break; +#define Y(n, N) case EXPECT_ ## N : scan.condition = yycedict_ ## n; break; + EXPECT +#undef X +#undef Y } } @@ -118,14 +127,10 @@ int lex_next(struct lex *const x) { re2c:define:YYSETCONDITION:naked = 1; */ const char *s0, *s1; - const size_t prev_line = scan.line; /*!stags:re2c format = 'const char *@@;\n'; */ assert(x); if(!scan.buffer) return 0; x->s0 = x->s1 = 0; - x->line = prev_line; - x->ws_before = 0; - x->new_paragraph = 0; scan: /*!re2c end = "\x00"; @@ -196,16 +201,17 @@ 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; expect_pop(); + { x->s0 = s0, x->s1 = s1; return x->symbol = ARG_KEYWORD, 1; } ws* @s0 date @s1 ws* ";"? / "]"? - { x->s0 = s0, x->s1 = s1; expect_pop(); + { x->s0 = s0, x->s1 = s1; return x->symbol = ARG_DATE, 1; } 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; expect_pop(); + { x->s0 = s0, x->s1 = s1; return x->symbol = ARG_FREEFORM, 1; } "]" => text { if(scan.edict.size) return 0;