Added interpret that does nothing.
This commit is contained in:
parent
9a0a8ae809
commit
e786b40167
20
Makefile
20
Makefile
@ -29,7 +29,7 @@ else
|
|||||||
CF += -g
|
CF += -g
|
||||||
endif
|
endif
|
||||||
|
|
||||||
projects := bin/test-text bin/test-kjv bin/test-journal
|
projects := bin/test-text bin/test-kjv bin/test-journal bin/interpret
|
||||||
#docs := $(patsubst test/test_%.c, doc/%.md, $(wildcard test/test_*.c))
|
#docs := $(patsubst test/test_%.c, doc/%.md, $(wildcard test/test_*.c))
|
||||||
|
|
||||||
default: $(projects)
|
default: $(projects)
|
||||||
@ -38,29 +38,29 @@ default: $(projects)
|
|||||||
bin/test-text: build/test_text.o build/text.o
|
bin/test-text: build/test_text.o build/text.o
|
||||||
bin/test-kjv: build/test_kjv.o build/text.o build/kjv.o
|
bin/test-kjv: build/test_kjv.o build/text.o build/kjv.o
|
||||||
bin/test-journal: build/test_journal.o build/text.o build/journal.o
|
bin/test-journal: build/test_journal.o build/text.o build/journal.o
|
||||||
# and h
|
bin/interpret: build/interpret.o build/scan.o build/journal.o build/kjv.o build/text.o
|
||||||
|
|
||||||
bin/%:
|
bin/%:
|
||||||
# linking test $@
|
@echo "\033[1;36mlinking $@\033[0m"
|
||||||
@mkdir -p bin
|
@mkdir -p bin
|
||||||
$(CC) $(OF) -o $@ $^
|
$(CC) $(OF) -o $@ $^
|
||||||
|
|
||||||
build/%.o: src/%.c
|
build/%.o: src/%.c src/%.h
|
||||||
# compile src $@
|
@echo "\033[0;36mcompile src $@\033[0m"
|
||||||
@mkdir -p build
|
@mkdir -p build
|
||||||
$(CC) $(CF) -c -o $@ $<
|
$(CC) $(CF) -c -o $@ $<
|
||||||
|
|
||||||
build/%.o: test/%.c
|
build/%.o: test/%.c
|
||||||
# compile test $@
|
@echo "\033[0;36mcompile test $@\033[0m"
|
||||||
@mkdir -p build
|
@mkdir -p build
|
||||||
$(CC) $(CF) -c -o $@ $<
|
$(CC) $(CF) -c -o $@ $<
|
||||||
|
|
||||||
build/%.o: build/%.c
|
build/%.o: build/%.c src/%.h
|
||||||
# compile generated $@
|
@echo "\033[0;36mcompile generated $@\033[0m"
|
||||||
$(CC) $(CF) -c -o $@ $<
|
$(CC) $(CF) -c -o $@ $<
|
||||||
|
|
||||||
build/%.c: src/%.re.c
|
build/%.c: src/%.re.c
|
||||||
# https://re2c.org/ generate $@
|
@echo "\033[0;34mhttps://re2c.org/ generate $@\033[0m"
|
||||||
@mkdir -p build
|
@mkdir -p build
|
||||||
re2c -W --tags --conditions -o $@ $<
|
re2c -W --tags --conditions -o $@ $<
|
||||||
|
|
||||||
@ -68,7 +68,7 @@ build/%.c: src/%.re.c
|
|||||||
# # https://github.com/neil-edelman/cdoc documentation
|
# # https://github.com/neil-edelman/cdoc documentation
|
||||||
# -cdoc -o $@ $<
|
# -cdoc -o $@ $<
|
||||||
|
|
||||||
.SECONDARY: build/kjv.c build/journal.c
|
.SECONDARY: build/kjv.c build/journal.c build/scan.c
|
||||||
.PHONY: clean release test
|
.PHONY: clean release test
|
||||||
|
|
||||||
test: $(projects)
|
test: $(projects)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include <stddef.h>
|
#include "journal.h"
|
||||||
|
|
||||||
int lex_looks_like_year(const char *, int *);
|
int lex_looks_like_year(const char *, int *);
|
||||||
int lex_looks_like_month(const char *);
|
int lex_looks_like_month(const char *);
|
||||||
@ -46,7 +46,16 @@ int lex_looks_like_day(const char *);
|
|||||||
X(KJV_TEXT, &word_vt), \
|
X(KJV_TEXT, &word_vt), \
|
||||||
X(KJV_NEXT, 0)
|
X(KJV_NEXT, 0)
|
||||||
|
|
||||||
|
int scan(union date32 date, const char *const buffer);
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
struct scan {
|
||||||
|
const char *marker, *from, *cursor, *limit, *label, *buffer;
|
||||||
|
int condition;
|
||||||
|
size_t line;
|
||||||
|
int is_ws_expected;
|
||||||
|
};
|
||||||
|
|
||||||
struct lex {
|
struct lex {
|
||||||
size_t line;
|
size_t line;
|
||||||
@ -59,5 +68,7 @@ struct lex {
|
|||||||
static const char *const lex_symbols[] = { FOR_SYMBOL(STR1) };
|
static const char *const lex_symbols[] = { FOR_SYMBOL(STR1) };
|
||||||
#undef X
|
#undef X
|
||||||
|
|
||||||
void lex_reset(const char *const buffer);
|
struct scan scan(const char *);
|
||||||
int lex_next(struct lex *);
|
int scan_next(struct scan *const s, struct lex *const x);
|
||||||
|
|
||||||
|
#endif
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
@std C89/90 */
|
@std C89/90 */
|
||||||
|
|
||||||
#include "../src/lex.h"
|
#include "../src/scan.h"
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -20,64 +20,42 @@
|
|||||||
/* This defines `enum condition`. */
|
/* This defines `enum condition`. */
|
||||||
/*!types:re2c*/
|
/*!types:re2c*/
|
||||||
|
|
||||||
/* In this case, expect
|
int scan(union date32 date, const char *const buffer) {
|
||||||
would be a stack of `size = 5` `EXPECT_KEYWORD`. This mirrors arguments in
|
const char *YYCURSOR = buffer;
|
||||||
`LEX_SYMBOL` and should also be an `edict_*` in <fn:lex_next> and
|
/*!re2c /**/
|
||||||
<fn:expect_pop>. */
|
re2c:define:YYCTYPE = char;
|
||||||
#define EXPECT_HEAD X(keyword, KEYWORD) X(date, DATE) X(natural, NATURAL) \
|
re2c:yyfill:enable = 0;
|
||||||
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
|
|
||||||
access only while underlying pointers do not change. This is a singleton, not
|
|
||||||
concurrent: convenient and bad. */
|
|
||||||
static struct scan {
|
|
||||||
/* `re2c` variables; these point directly into `buffer`. */
|
|
||||||
const char *marker, /**ctx_marker,*/ *from, *cursor;
|
|
||||||
/* Weird `c2re` stuff: these fields have to come after when >5? */
|
|
||||||
const char *label, *buffer;
|
|
||||||
enum condition condition;
|
|
||||||
size_t line;
|
|
||||||
int is_ws_expected, is_source;
|
|
||||||
#define X(n, N) EXPECT_ ## N,
|
|
||||||
#define Y(n, N) EXPECT_ ## N
|
|
||||||
struct { unsigned size; enum { EXPECT } expect[16]; } edict;
|
|
||||||
#undef X
|
|
||||||
#undef Y
|
|
||||||
} scan;
|
|
||||||
|
|
||||||
/** 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;
|
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
struct scan scan(const char *const buffer) {
|
||||||
|
struct scan scan;
|
||||||
|
scan.marker = scan.from = scan.cursor = scan.label = scan.buffer = buffer;
|
||||||
scan.condition = yycline;
|
scan.condition = yycline;
|
||||||
scan.line = 1;
|
scan.line = 1;
|
||||||
|
return scan;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** I don't think `re2c` supports branching on variable conditions.
|
int scan_next(struct scan *const s, struct lex *const x) {
|
||||||
It does now? */
|
|
||||||
static void expect_pop(void) {
|
|
||||||
if(!scan.edict.size) { scan.condition = yycedict_end; return; }
|
|
||||||
switch(scan.edict.expect[--scan.edict.size]) {
|
|
||||||
#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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int lex_next(struct lex *const x) {
|
|
||||||
/*!re2c /**/
|
/*!re2c /**/
|
||||||
re2c:flags:tags = 1;
|
re2c:flags:tags = 1;
|
||||||
re2c:define:YYCURSOR = scan.cursor;
|
re2c:define:YYCTYPE = char;
|
||||||
re2c:define:YYMARKER = scan.marker;
|
re2c:yyfill:enable = 0;
|
||||||
/*re2c:define:YYCTXMARKER = scan.ctx_marker;*/
|
re2c:define:YYCURSOR = s->cursor;
|
||||||
|
re2c:define:YYMARKER = s->marker;
|
||||||
re2c:define:YYCONDTYPE = 'condition';
|
re2c:define:YYCONDTYPE = 'condition';
|
||||||
re2c:define:YYGETCONDITION = 'scan.condition';
|
re2c:define:YYGETCONDITION = 's->condition';
|
||||||
re2c:define:YYGETCONDITION:naked = 1;
|
re2c:define:YYGETCONDITION:naked = 1;
|
||||||
re2c:define:YYSETCONDITION = 'scan.condition = @@;';
|
re2c:define:YYSETCONDITION = 's->condition = @@;';
|
||||||
re2c:define:YYSETCONDITION:naked = 1;
|
re2c:define:YYSETCONDITION:naked = 1;
|
||||||
sentinel = "\x00";
|
sentinel = "\x00";
|
||||||
newline = "\n";
|
newline = "\n";
|
||||||
@ -91,28 +69,28 @@ int lex_next(struct lex *const x) {
|
|||||||
*/
|
*/
|
||||||
const char *s0, *s1;
|
const char *s0, *s1;
|
||||||
/*!stags:re2c format = 'const char *@@;\n'; */
|
/*!stags:re2c format = 'const char *@@;\n'; */
|
||||||
assert(x);
|
assert(s && x);
|
||||||
if(!scan.buffer) return 0;
|
if(!s->buffer) return 0;
|
||||||
x->line = scan.line;
|
x->line = s->line;
|
||||||
x->s0 = x->s1 = 0;
|
x->s0 = x->s1 = 0;
|
||||||
scan:
|
scan:
|
||||||
/*!re2c /**/
|
/*!re2c /**/
|
||||||
<*> unix_control { return x->symbol = ILLEGAL, 0; }
|
<*> unix_control { return x->symbol = ILLEGAL, 0; }
|
||||||
<*> * { return x->symbol = SYNTAX, 0; }
|
<*> * { return x->symbol = SYNTAX, 0; }
|
||||||
<*> sentinel /* New line always delimits. */
|
<*> sentinel /* New line always delimits. */
|
||||||
{ return x->symbol = scan.condition == yycline ? END : ILLEGAL, 0; }
|
{ return x->symbol = s->condition == yycline ? END : ILLEGAL, 0; }
|
||||||
<expect_line> newline => line { x->line = ++scan.line; goto scan; }
|
<expect_line> newline => line { x->line = ++s->line; goto scan; }
|
||||||
/* Symbols that go at the beginning of a line. */
|
/* Symbols that go at the beginning of a line. */
|
||||||
<line> newline { x->line = ++scan.line; goto scan; }
|
<line> newline { x->line = ++s->line; goto scan; }
|
||||||
<line> "[" :=> edict
|
<line> "[" :=> edict
|
||||||
<line> "--" :=> source
|
<line> "--" :=> source
|
||||||
<line> "->" :=> location
|
<line> "->" :=> location
|
||||||
<line> * :=> text
|
|
||||||
<line> "!" => text { return x->symbol = COMPLETE, 1; }
|
<line> "!" => text { return x->symbol = COMPLETE, 1; }
|
||||||
<line> "^" => text { return x->symbol = CANCELLED, 1; }
|
<line> "^" => text { return x->symbol = CANCELLED, 1; }
|
||||||
<line> "#" => text { return x->symbol = HEADING, 1; }
|
<line> "#" => text { return x->symbol = HEADING, 1; }
|
||||||
|
<line> * :=> text
|
||||||
|
|
||||||
<text> newline => line { x->line = ++scan.line; goto scan; }
|
<text> newline => line { x->line = ++s->line; goto scan; }
|
||||||
<text, bible> ws+ { goto scan; }
|
<text, bible> ws+ { goto scan; }
|
||||||
<text> @s0 glyph+ @s1
|
<text> @s0 glyph+ @s1
|
||||||
{ x->s0 = s0, x->s1 = s1; return x->symbol = TEXT, 1; }
|
{ x->s0 = s0, x->s1 = s1; return x->symbol = TEXT, 1; }
|
||||||
@ -144,7 +122,7 @@ scan:
|
|||||||
{ x->s0 = s0, x->s1 = s1; return x->symbol = KJV_TEXT, 1; }
|
{ x->s0 = s0, x->s1 = s1; return x->symbol = KJV_TEXT, 1; }
|
||||||
/* Multiple verses can be present, but they end in ''.
|
/* Multiple verses can be present, but they end in ''.
|
||||||
Not strictly enforced. */
|
Not strictly enforced. */
|
||||||
<bible> newline / (newline | "``") { x->line = ++scan.line; goto scan; }
|
<bible> newline / (newline | "``") { x->line = ++s->line; goto scan; }
|
||||||
<bible> newline { return x->symbol = SYNTAX, 0; }
|
<bible> newline { return x->symbol = SYNTAX, 0; }
|
||||||
|
|
||||||
<source> @s0 keyword @s1 => expect_line
|
<source> @s0 keyword @s1 => expect_line
|
||||||
@ -180,50 +158,50 @@ scan:
|
|||||||
|
|
||||||
/* How did it get into my journal? */
|
/* How did it get into my journal? */
|
||||||
<edict> "source"
|
<edict> "source"
|
||||||
{ if(scan.is_ws_expected || scan.edict.size)
|
{ if(s->is_ws_expected || s->edict.size)
|
||||||
return x->symbol = SYNTAX, 0;
|
return x->symbol = SYNTAX, 0;
|
||||||
scan.is_ws_expected = 1, scan.is_source = 1;
|
s->is_ws_expected = 1, s->is_source = 1;
|
||||||
scan.edict.size = 2;
|
s->edict.size = 2;
|
||||||
scan.edict.expect[1] = EXPECT_KEYWORD;
|
s->edict.expect[1] = EXPECT_KEYWORD;
|
||||||
scan.edict.expect[0] = EXPECT_END_TEXT;
|
s->edict.expect[0] = EXPECT_END_TEXT;
|
||||||
return x->symbol = SOURCE, 1; }
|
return x->symbol = SOURCE, 1; }
|
||||||
<edict> "default"
|
<edict> "default"
|
||||||
{ if(scan.is_ws_expected || !scan.is_source)
|
{ if(s->is_ws_expected || !s->is_source)
|
||||||
return x->symbol = SYNTAX, 0;
|
return x->symbol = SYNTAX, 0;
|
||||||
scan.is_ws_expected = 1, scan.is_source = 0;
|
s->is_ws_expected = 1, s->is_source = 0;
|
||||||
return x->symbol = DEFAULT, 1; }
|
return x->symbol = DEFAULT, 1; }
|
||||||
|
|
||||||
/* Editorializing; looking back. */
|
/* Editorializing; looking back. */
|
||||||
<edict> "ed"
|
<edict> "ed"
|
||||||
{ if(scan.is_ws_expected || scan.edict.size)
|
{ if(s->is_ws_expected || s->edict.size)
|
||||||
return x->symbol = SYNTAX, 0;
|
return x->symbol = SYNTAX, 0;
|
||||||
scan.is_ws_expected = 1; /* no idea, just copy; probably should do sth */
|
s->is_ws_expected = 1; /* no idea, just copy; probably should do sth */
|
||||||
scan.edict.size = 1;
|
s->edict.size = 1;
|
||||||
scan.edict.expect[0] = EXPECT_END_TEXT; /* Pithy comment. */
|
s->edict.expect[0] = EXPECT_END_TEXT; /* Pithy comment. */
|
||||||
return x->symbol = EDITORIALIZING, 1; }
|
return x->symbol = EDITORIALIZING, 1; }
|
||||||
|
|
||||||
/* Score. */
|
/* Score. */
|
||||||
<edict> "significant"
|
<edict> "significant"
|
||||||
{ if(scan.is_ws_expected || scan.edict.size)
|
{ if(s->is_ws_expected || s->edict.size)
|
||||||
return x->symbol = SYNTAX, 0;
|
return x->symbol = SYNTAX, 0;
|
||||||
scan.is_ws_expected = 1;
|
s->is_ws_expected = 1;
|
||||||
scan.edict.size = 3;
|
s->edict.size = 3;
|
||||||
scan.edict.expect[2] = EXPECT_NATURAL; /* Ordinal. */
|
s->edict.expect[2] = EXPECT_NATURAL; /* Ordinal. */
|
||||||
scan.edict.expect[1] = EXPECT_RESTRICT_TEXT; /* Name. */
|
s->edict.expect[1] = EXPECT_RESTRICT_TEXT; /* Name. */
|
||||||
scan.edict.expect[0] = EXPECT_DATE; /* Birthday. */
|
s->edict.expect[0] = EXPECT_DATE; /* Birthday. */
|
||||||
return x->symbol = SIGNIFICANT, 1; }
|
return x->symbol = SIGNIFICANT, 1; }
|
||||||
<edict> @s0 natural @s1
|
<edict> @s0 natural @s1
|
||||||
{ if(scan.is_ws_expected || scan.edict.size)
|
{ if(s->is_ws_expected || s->edict.size)
|
||||||
return x->symbol = SYNTAX, 0;
|
return x->symbol = SYNTAX, 0;
|
||||||
scan.is_ws_expected = 1;
|
s->is_ws_expected = 1;
|
||||||
x->s0 = s0, x->s1 = s1;
|
x->s0 = s0, x->s1 = s1;
|
||||||
return x->symbol = SIGNIFICANT_RECALL, 1; }
|
return x->symbol = SIGNIFICANT_RECALL, 1; }
|
||||||
|
|
||||||
/* General [edict: whatever]. */
|
/* General [edict: whatever]. */
|
||||||
<edict> ws+ { scan.is_ws_expected = 0; goto scan; }
|
<edict> ws+ { s->is_ws_expected = 0; goto scan; }
|
||||||
<edict> ":"
|
<edict> ":"
|
||||||
{ if(!scan.edict.size) return x->symbol = SYNTAX, 0;
|
{ if(!s->edict.size) return x->symbol = SYNTAX, 0;
|
||||||
scan.is_ws_expected = 0, scan.is_source = 0;
|
s->is_ws_expected = 0, s->is_source = 0;
|
||||||
expect_pop(); goto scan; }
|
expect_pop(); goto scan; }
|
||||||
<edict_keyword> ws* @s0 keyword @s1 ws* ";"?
|
<edict_keyword> ws* @s0 keyword @s1 ws* ";"?
|
||||||
{ x->s0 = s0, x->s1 = s1; expect_pop();
|
{ x->s0 = s0, x->s1 = s1; expect_pop();
|
||||||
@ -243,6 +221,8 @@ scan:
|
|||||||
{ x->s0 = s0, x->s1 = s1; expect_pop();
|
{ x->s0 = s0, x->s1 = s1; expect_pop();
|
||||||
return x->symbol = ARG_END_TEXT, 1; }
|
return x->symbol = ARG_END_TEXT, 1; }
|
||||||
<edict, edict_end> "]" => expect_line
|
<edict, edict_end> "]" => expect_line
|
||||||
{ if(scan.edict.size) return 0; goto scan; }
|
{ if(s->edict.size) return 0; goto scan; }
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
8
test/interpret.c
Normal file
8
test/interpret.c
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
return EXIT_SUCCESS;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user