Have to have some kind of persistent data.

This commit is contained in:
Neil 2022-12-13 14:37:50 -08:00
parent f00ed7f1bf
commit 0236cab5d5
1 changed files with 29 additions and 12 deletions

View File

@ -11,6 +11,7 @@
#include <unistd.h> /* chdir (POSIX) (because I'm lazy) */
/* Dynamic contiguous string that is used to load files. */
#define ARRAY_NAME char
#define ARRAY_TYPE char
@ -46,7 +47,8 @@ finally:
return success;
}
/** [`s`,`e`) => `n` */
/** Helper to parse unsigned; [`s`,`e`) => `n`. */
static int parse_natural(const char *s, const char *const e, unsigned *const n) {
unsigned accum = 0;
while(s < e) {
@ -60,6 +62,7 @@ static int parse_natural(const char *s, const char *const e, unsigned *const n)
}
/* Enumerate books. */
#define BOOKS \
X(Genesis),\
@ -139,6 +142,10 @@ static const char *kjv_book_string[] = { BOOKS };
#undef X
#undef BOOKS
/* Parse filename of books. This works with
<https://github.com/scrollmapper/bible_databases/tree/master/txt/KJV> */
/*!re2c /**/
re2c:yyfill:enable = 0;
re2c:define:YYCTYPE = char;
@ -160,6 +167,9 @@ static int kjv_filename(const char *fn, unsigned *const book_no) {
*/
}
/* Parse book contents. */
struct lex {
size_t line;
const char *cursor;
@ -192,23 +202,29 @@ static int lex_next_verse(struct lex *const lex) {
lex->error = 0;
scan:
/*!re2c /**/
<*> * { printf("catch\n"); return errno = EILSEQ, lex->error = 1, 0; }
<line> [^[\]\n\x00]* "\n" { printf("comment\n"); lex->line++; goto scan; }
<line> "\x00" { printf("eof\n"); return 0; }
<*> * { return errno = EILSEQ, lex->error = 1, 0; }
<line> [^[\]\n\x00]* "\n" { lex->line++; goto scan; }
<line> "\x00" { return 0; }
<line> "[" @s0 natural @s1 ":" @t0 natural @t1 "]" => verse {
if(!parse_natural(s0, s1, &lex->chapter)
|| !parse_natural(t0, t1, &lex->verse))
return errno = EILSEQ, lex->error = 1, 0;
lex->words = 0;
printf("%u:%u", lex->chapter, lex->verse);
/*printf("%u:%u", lex->chapter, lex->verse);*/
goto scan;
}
<verse> whitespace+ { goto scan; }
<verse> @s0 word @s1 { lex->words++; goto scan; }
<verse> "\n" { printf(" -> %u\n", lex->words); lex->line++; return 1; }
<verse> "\n" { /*printf(" -> %u\n", lex->words);*/ lex->line++; return 1; }
*/
}
/* Reversible hash map to store data on bible. */
/* */
#include <stdint.h>
int main(void) {
const char *const dir_name = "KJV";
struct char_array kjv[KJV_BOOK_SIZE] = { 0 };
@ -226,8 +242,8 @@ int main(void) {
unsigned ordinal;
enum kjv_book b;
if(!kjv_filename(de->d_name, &ordinal)) /* Extract ordinal. */
{ fprintf(stderr, "Ignored <%s>.\n", de->d_name); continue; }
fprintf(stderr, "<%s> ordinal: %u\n", de->d_name, ordinal);
{ /*fprintf(stderr, "Ignored <%s>.\n", de->d_name);*/ continue; }
/*fprintf(stderr, "<%s> ordinal: %u\n", de->d_name, ordinal);*/
if(ordinal < 1 || ordinal > KJV_BOOK_SIZE)
{ errno = ERANGE; goto catch; } /* Not in range. */
if(kjv[b = ordinal - 1].data) /* Convert to zero-based. */
@ -239,11 +255,12 @@ int main(void) {
/* Parse. */
for(i = 0; i < KJV_BOOK_SIZE; i++) {
struct lex x = lex(kjv[i].data);
if(!x.cursor) { fprintf(stderr, "Missing book %s.\n",
kjv_book_string[i]); errno = EDOM; goto catch; }
printf("%s: cumulative %zu.\n", kjv_book_string[i], words);
if(!x.cursor) { fprintf(stderr, "Missing book [%u]%s.\n",
i + 1, kjv_book_string[i]); errno = EDOM; goto catch; }
printf("[%u]%s: cumulative %zu.\n", i + 1, kjv_book_string[i], words);
while(lex_next_verse(&x)) words += x.words;
if(x.error) goto catch;
if(x.error) { fprintf(stderr, "[%u]%s on line %zu\n",
i + 1, kjv_book_string[i], x.line); goto catch; }
}
printf("kjv: %zu words\n", words);