This commit is contained in:
Neil 2022-07-16 22:24:33 -07:00
parent 4accda5d56
commit d13bf4ea1b
3 changed files with 66 additions and 19 deletions

View File

@ -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);
}

View File

@ -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)

View File

@ -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 <fn:lex_next> and <fn:expect_pop>. */
#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; }
<expect_line> newline => line { x->line = ++scan.line; goto scan; }
/* This is lazy! break them up into separate words. */
<expect_caption> 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:
<map> "(" @s0 decimal "," @s1 decimal ")" => expect_caption
{ x->s0 = s0, x->s1 = s1; return x->symbol = LOCATION, 1; }
/* How did it get into my journal? */
<edict> "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; }
<edict> "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. */
<edict> "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. */
<edict> "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; }
<edict> @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]. */
<edict> ws+ { scan.is_ws_expected = 0; goto scan; }
<edict> ":"
{ if(!scan.edict.size) return x->symbol = SYNTAX, 0;
@ -261,10 +267,14 @@ scan:
<edict_natural> ws* @s0 natural @s1 ws* ";"?
{ x->s0 = s0, x->s1 = s1; expect_pop();
return x->symbol = ARG_NATURAL, 1; }
<edict_freeform>
<edict_restrict_text>
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; }
<edict_end_text>
ws* @s0 (glyph \ [[\]]) ((glyph \ [[\]]) | ws)* @s1 ws*
{ x->s0 = s0, x->s1 = s1; expect_pop();
return x->symbol = ARG_END_TEXT, 1; }
<edict, edict_end> "]" => expect_line
{ if(scan.edict.size) return 0; goto scan; }
*/