diff --git a/src/interpret.c b/src/interpret.c index cebcfa7..4de0707 100644 --- a/src/interpret.c +++ b/src/interpret.c @@ -249,7 +249,8 @@ int main(int argc, char **argv) { closedir(dir), dir = 0; /* Sort the years for sensible ordering of parsing. */ qsort(years.data, years.size, sizeof *years.data, &void_int_cmp); - fprintf(stderr, "(In %s: %s.)\n", argv[1], int_array_to_string(&years)); + fprintf(stderr, "Years in <<%s>>: %s.\n", + argv[1], int_array_to_string(&years)); /* Go though each year. */ for(y = years.data, y_end = y + years.size; y < y_end; y++) { @@ -270,7 +271,8 @@ int main(int argc, char **argv) { } closedir(dir), dir = 0; qsort(months.data, months.size, sizeof *months.data, &void_int_cmp); - fprintf(stderr, "(In %s: %s.)\n", fn, int_array_to_string(&months)); + fprintf(stderr, "Months in <<%s>>: %s.)\n", + fn, int_array_to_string(&months)); /* Go though each month. */ for(m = months.data, m_end = m + months.size; m < m_end; m++) { @@ -291,7 +293,8 @@ int main(int argc, char **argv) { } closedir(dir), dir = 0; qsort(days.data, days.size, sizeof *days.data, &void_int_cmp); - fprintf(stderr, "(In %s: %s.)\n", fn, int_array_to_string(&days)); + fprintf(stderr, "Days in <<%s>>: %s.\n", + fn, int_array_to_string(&days)); for(d = days.data, d_end = d + days.size; d < d_end; d++) { struct lex *lex = 0; @@ -307,16 +310,50 @@ int main(int argc, char **argv) { page->entry = char_array(); page->meaning = lex_array(); if(!append_file(&page->entry, fn)) goto syntax; + struct { + int content; + enum lex_symbol expected; + } context = { 0, TEXT }; for(lex_reset(page->entry.data); ; ) { if(!(lex = lex_array_new(&page->meaning))) goto syntax; if(!lex_next(lex)) { if(lex->symbol != END) { errno = EILSEQ; goto syntax; } + break; /* Terminated successfully. */ + } + /* Debug print. */ + if(context.content && context.expected != lex->symbol) { + printf("//\n"); + context.content = 0; + } else { + context.content = 1; + } + switch(lex->symbol) { + case TEXT: printf("[%.*s]", + (int)(lex->s1 - lex->s0), lex->s0); + context.expected = TEXT; break; + case PARAGRAPH: printf("\n"); break; + case BIBLE_BOOK: printf("book:[%.*s]", + (int)(lex->s1 - lex->s0), lex->s0); + context.expected = BIBLE_CHAPTER_VERSE; break; + case BIBLE_CHAPTER_VERSE: printf("[ch. %.*s]", + (int)(lex->s1 - lex->s0), lex->s0); + context.expected = BIBLE_TEXT; break; + case BIBLE_TEXT: printf("[%.*s]", + (int)(lex->s1 - lex->s0), lex->s0); break; + case BIBLE_NEXT: printf("(next)\n"); break; + default: + fprintf(stderr, "%lu: %s", + (unsigned long)lex->line, lex_symbols[lex->symbol]); + if(lex->s0 && lex->s1) { + if(lex->s0 + INT_MAX < lex->s1) + intent = "line too long", errno = EILSEQ; + else + fprintf(stderr, " <<%.*s>>", + (int)(lex->s1 - lex->s0), lex->s0); + } + fprintf(stderr, ".\n"); break; } - /* fixme: print the books */ - if(lex->symbol == BIBLE_BOOK - || lex->symbol == BIBLE_CHAPTER_VERSE) - printf("[%.*s]\n", (int)(lex->s1 - lex->s0), lex->s0); } continue; syntax: @@ -348,7 +385,7 @@ syntax: int_array_clear(&months); if(chdir("..") == -1) goto catch; /* fixme: Expand, contact is the next thing that it doesn't get. */ - if(*y == 1996) break; + if(*y == 1993/*1996*/) break; } page_tree_bulk_finish(&journal); int_array_(&years), int_array_(&months), int_array_(&days); @@ -371,7 +408,6 @@ finally: struct page *const page = entry.value; char z[12]; date32_to_string(*entry.key, &z); - /*printf("Freeing %s.\n", z);*/ lex_array_(&page->meaning); char_array_(&page->entry); } diff --git a/src/lex.h b/src/lex.h index 5fc1c57..a5b9099 100644 --- a/src/lex.h +++ b/src/lex.h @@ -18,7 +18,8 @@ int lex_looks_like_day(const char *); X(SIGNIFICANT), X(SIGNIFICANT_RECALL), X(EDITORIALIZING), \ \ /* Arguments. */ \ - X(ARG_KEYWORD), X(ARG_DATE), X(ARG_NATURAL), X(ARG_FREEFORM), \ + X(ARG_KEYWORD), X(ARG_DATE), X(ARG_NATURAL), X(ARG_RESTRICT_TEXT), \ + X(ARG_END_TEXT), \ \ /* Bible */ \ X(BIBLE_BOOK), X(BIBLE_CHAPTER_VERSE), X(BIBLE_TEXT), X(BIBLE_NEXT) diff --git a/src/lex.re_c.c b/src/lex.re_c.c index 7d79094..cfe0068 100644 --- a/src/lex.re_c.c +++ b/src/lex.re_c.c @@ -75,8 +75,9 @@ 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) X(natural, NATURAL) -#define EXPECT_CONS Y(freeform, FREEFORM) +#define EXPECT_HEAD X(keyword, KEYWORD) X(date, DATE) X(natural, NATURAL) \ + X(restrict_text, RESTRICT_TEXT) +#define EXPECT_CONS Y(end_text, END_TEXT) #define EXPECT EXPECT_HEAD EXPECT_CONS /** Scan reads one file as a time and extracts semantic information. Valid to @@ -152,6 +153,7 @@ scan: <*> sentinel { return x->symbol = scan.condition == yycline ? END : ILLEGAL, 0; } newline => line { x->line = ++scan.line; goto scan; } + /* This is lazy! break them up into separate words. */ ws* @s0 glyph (glyph | ws)* @s1 ws* / newline => expect_line { x->s0 = s0, x->s1 = s1; return x->symbol = CAPTION, 1; } @@ -209,13 +211,14 @@ scan: "(" @s0 decimal "," @s1 decimal ")" => expect_caption { x->s0 = s0, x->s1 = s1; return x->symbol = LOCATION, 1; } + /* How did it get into my journal? */ "source" { if(scan.is_ws_expected || scan.edict.size) return x->symbol = SYNTAX, 0; scan.is_ws_expected = 1, scan.is_source = 1; scan.edict.size = 2; scan.edict.expect[1] = EXPECT_KEYWORD; - scan.edict.expect[0] = EXPECT_FREEFORM; + scan.edict.expect[0] = EXPECT_END_TEXT; return x->symbol = SOURCE, 1; } "default" { if(scan.is_ws_expected || !scan.is_source) @@ -223,22 +226,24 @@ scan: scan.is_ws_expected = 1, scan.is_source = 0; return x->symbol = DEFAULT, 1; } + /* Editorializing; looking back. */ "ed" { if(scan.is_ws_expected || scan.edict.size) return x->symbol = SYNTAX, 0; scan.is_ws_expected = 1; /* no idea, just copy; probably should do sth */ scan.edict.size = 1; - scan.edict.expect[0] = EXPECT_FREEFORM; + scan.edict.expect[0] = EXPECT_END_TEXT; /* Pithy comment. */ return x->symbol = EDITORIALIZING, 1; } + /* Score. */ "significant" { if(scan.is_ws_expected || scan.edict.size) return x->symbol = SYNTAX, 0; scan.is_ws_expected = 1; scan.edict.size = 3; - scan.edict.expect[2] = EXPECT_NATURAL; - scan.edict.expect[1] = EXPECT_FREEFORM; - scan.edict.expect[0] = EXPECT_DATE; + scan.edict.expect[2] = EXPECT_NATURAL; /* Ordinal. */ + scan.edict.expect[1] = EXPECT_RESTRICT_TEXT; /* Name. */ + scan.edict.expect[0] = EXPECT_DATE; /* Birthday. */ return x->symbol = SIGNIFICANT, 1; } @s0 natural @s1 { if(scan.is_ws_expected || scan.edict.size) @@ -247,6 +252,7 @@ scan: x->s0 = s0, x->s1 = s1; return x->symbol = SIGNIFICANT_RECALL, 1; } + /* General [edict: whatever]. */ ws+ { scan.is_ws_expected = 0; goto scan; } ":" { if(!scan.edict.size) return x->symbol = SYNTAX, 0; @@ -261,10 +267,14 @@ scan: ws* @s0 natural @s1 ws* ";"? { x->s0 = s0, x->s1 = s1; expect_pop(); return x->symbol = ARG_NATURAL, 1; } - + ws* @s0 (glyph \ [;[\]]) ((glyph \ [;[\]]) | ws)* @s1 ws* ";"? { x->s0 = s0, x->s1 = s1; expect_pop(); - return x->symbol = ARG_FREEFORM, 1; } + return x->symbol = ARG_RESTRICT_TEXT, 1; } + + ws* @s0 (glyph \ [[\]]) ((glyph \ [[\]]) | ws)* @s1 ws* + { x->s0 = s0, x->s1 = s1; expect_pop(); + return x->symbol = ARG_END_TEXT, 1; } "]" => expect_line { if(scan.edict.size) return 0; goto scan; } */