interpret/src/scan_kjv.re.c

168 lines
5.4 KiB
C
Raw Normal View History

2022-12-29 07:54:59 +00:00
/** @license 2022 Neil Edelman, distributed under the terms of the
[MIT License](https://opensource.org/licenses/MIT).
Scan journal entries for kjv references. */
#include "../src/journal.h"
#include "../src/kjv.h"
#include "../src/helper.h"
#include <inttypes.h> /* C99 */
2022-12-29 07:54:59 +00:00
#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <limits.h>
/*!conditions:re2c*/
2022-12-29 08:51:45 +00:00
static int scan(union date32 date, const char *const buffer,
struct kjv *const kj) {
const char *YYCURSOR, *YYMARKER, *yyt1, *yyt2, *yyt3,
*s0, *s1, *t0, *t1, *line_start, *line_end;
2022-12-29 07:54:59 +00:00
enum kjv_book book = Revelation;
uint32_t chapter = 0, verse = 0, verse_end = 0;
2022-12-29 07:54:59 +00:00
enum YYCONDTYPE condition = yycline;
size_t line = 1;
2022-12-29 18:10:41 +00:00
char datestr[12] = {0};
int is_found = 0;
2022-12-29 08:51:45 +00:00
assert(buffer && kj);
YYCURSOR = YYMARKER = yyt1 = line_start = buffer;
2022-12-29 07:54:59 +00:00
/*!re2c /**/
re2c:define:YYCTYPE = char;
re2c:yyfill:enable = 0;
re2c:define:YYGETCONDITION = "condition";
re2c:define:YYSETCONDITION = "condition = @@;";
re2c:define:YYGETCONDITION:naked = 1;
re2c:define:YYSETCONDITION:naked = 1;
unix_control = [\x01-\x08\x0a-\x1f\x7f];
ws = [ \t];
glyph = [^] \ ("\x00" | "\n" | unix_control | ws);
natural = [1-9][0-9]*;
engage = ws+ "--" ws+;
2022-12-29 07:54:59 +00:00
lookat = ws* natural ":" natural [ab]?
("-" (natural ":")? natural [ab]?)? engage;
2022-12-29 07:54:59 +00:00
*/
for( ; ; ) { /*!re2c /**/
2022-12-29 18:10:41 +00:00
<skip, book> * { goto catch; }
<line> "\x00" { return 1; }
<line> "\n" @line_start {
fprintf(stderr, "\033[0;37m" "%4zu" "\033[0m" "\n", line);
line++;
continue;
}
<line> * :=> skip /* Guess it can't be simplified? */
2022-12-29 07:54:59 +00:00
<line> "Genesis" / lookat => book { book = Genesis; continue; }
<line> "Exodus" / lookat => book { book = Exodus; continue; }
/*| "Leviticus" | "Numbers" | "Deuteronomy"
| "Joshua" | "Judges" | "Ruth" | "I"{1,2} " Samuel" | "I"{1,2} " Kings"
| "I"{1,2} " Chronicles" | "Ezra" | "Nehemiah" | "Esther" | "Job"
| "Psalms" | "Proverbs" | "Ecclesiastes" | "Song of Solomon" | "Isaiah"
| "Jeremiah" | "Lamentations" | "Ezekiel" | "Daniel" | "Hosea" | "Joel"
| "Amos" | "Obadiah" | "Jonah" | "Micah" | "Nahum" | "Habakkuk"
| "Zephaniah" | "Haggai" | "Zechariah" | "Malachi" | "Matthew" | "Mark"
2022-12-29 08:51:45 +00:00
| "Luke" | "John" | "Acts" | */
<line> "Romans" / lookat => book { book = Romans; continue; }
/*| "I"{1,2} " Corinthians"
2022-12-29 07:54:59 +00:00
| "Galatians" | "Ephesians" | "Philippians" | "Colossians"
| "I"{1,2} " Thessalonians" | "I"{1,2} " Timothy" | "Titus" | "Philemon"
| "Hebrews" | "James" | "I"{1,2} " Peter" | "I"{1,3} " John" | "Jude"
| "Revelation") @s1 ws* / bible_ref ws+ "--" ws+ "``" */
//<line> [^\n\x00]* newline { printf("throw\n"); line++; continue; }
<book> ws+ @s0 natural @s1 ":" @t0 natural @t1 [ab]? {
if(chapter || verse || verse_end
|| !helper_natural(s0, s1, &chapter)
2022-12-29 18:10:41 +00:00
|| !helper_natural(t0, t1, &verse)) goto catch;
continue;
}
<book> "-" @s0 natural @s1 [ab]? { /* Verse range. */
if(!chapter || !verse || verse_end
|| !helper_natural(s0, s1, &verse_end)) goto catch;
continue;
}
<book> engage => skip {
2022-12-29 18:10:41 +00:00
const size_t old_set_words = kj->set_words;
char citestr[12];
if(!chapter || !verse || verse_end && verse_end <= verse)
goto catch;
union kjvcite cite
= { .book = book, .chapter = chapter, .verse = verse };
if(!datestr[0]) date32_to_string(date, &datestr); /* Only once. */
2022-12-29 18:10:41 +00:00
kjvcite_to_string(cite, &citestr);
for( ; ; verse++, cite.verse++) {
if(!kjv_add(kj, cite)) goto catch;
if(!verse_end || verse_end <= verse) break;
}
if(verse_end) {
printf("%s\t%zu\t%zu\t# %s-%" PRIu32 "\n",
datestr, old_set_words, kj->set_words, citestr, verse_end);
} else {
printf("%s\t%zu\t%zu\t# %s\n",
datestr, old_set_words, kj->set_words, citestr);
}
book = Revelation, chapter = 0, verse = 0, verse_end = 0;
is_found = 1;
continue;
}
<skip> [^\n\x00]* @line_end "\n" @s0 => line {
const size_t size = (size_t)(line_end - line_start);
int intsize = size > 40 ? 40 : (int)size;
fprintf(stderr, "%s%4zu: %.*s%s\n", is_found ? "\033[1;35m" : "",
line, intsize, line_start, is_found ? "\033[0m" : "");
line_start = s0, is_found = 0;
line++;
2022-12-29 07:54:59 +00:00
continue;
}
*/ }
2022-12-29 18:10:41 +00:00
catch:
if(!errno) errno = EILSEQ;
2022-12-29 07:54:59 +00:00
{
char a[12];
date32_to_string(date, &a);
fprintf(stderr, "%s line %zu: unexpected.\n", a, line);
}
return 0;
}
int main(void) {
int success = EXIT_SUCCESS;
2022-12-29 18:10:41 +00:00
struct journal j;
2022-12-29 07:54:59 +00:00
struct journal_iterator it;
2022-12-29 08:51:45 +00:00
struct kjv kj = kjv();
2022-12-29 07:54:59 +00:00
union date32 k;
union load *v;
2022-12-29 08:51:45 +00:00
size_t i;
2022-12-29 18:10:41 +00:00
/*scan((union date32){.year=2000, .month=1, .day=1}, "\n\n\n"
"Romans 3:23 -- ``For all have sinned, "
"and come short of the glory of God.''\n", &kj);*/
j = journal();
2022-12-29 07:54:59 +00:00
if(!journal_is_valid(&j)) goto catch;
2022-12-29 18:10:41 +00:00
fprintf(stderr, "Journal: %s.\n", journal_to_string(&j));
printf("set term postscript eps enhanced\n"
"set output \"kjv.eps\"\n"
"$Data <<EOD\n"
"# date\told\tnew / %zu\n", kj.total_words);
2022-12-29 08:51:45 +00:00
it = journal_begin(&j), i = 0; while(journal_next(&it, &k, &v)) {
2022-12-29 18:10:41 +00:00
if(!scan(k, v->text, &kj)) goto catch;
2022-12-29 08:51:45 +00:00
if(++i > 32) break;
2022-12-29 07:54:59 +00:00
}
printf("EOD\n"
"set monochrome\n"
"set xdata time\n"
"set timefmt \"%%Y-%%m-%%d\"\n"
"set xtics format \"%%Y-%%m-%%d\" rotate by -30\n"
"set ylabel \"KJV memorized\"\n"
"set format y \"%%g%%%%\"\n"
"unset key #set key bottom right\n"
"set grid\n"
"unset border\n"
"plot $Data using 1:($3-$2)*100/%zu smooth cumulative "
"with steps lw 2\n", kj.total_words);
2022-12-29 07:54:59 +00:00
goto finally;
catch:
success = EXIT_FAILURE;
perror("journal");
finally:
journal_(&j);
return success;
}