broken code, but added attempt at writing grammar

This commit is contained in:
Ellen Arvidsson 2025-04-14 17:40:22 +02:00
parent fb95e5d026
commit 20e3757f44
18 changed files with 1145 additions and 142 deletions

247
src/msph/msph_token.c Normal file
View file

@ -0,0 +1,247 @@
#include <sys/errno.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "spho/err.h"
#define MSPH_ERR_SYS 0x0001
#define MSPH_ERR_TOOLONG 0x0002
#define MSPH_ERR(ctx, e) SPHO_ERR(ctx, e)
#define MSPH_TOKS_ERR(toks, e) MSPH_ERR((toks)->ctx, e)
struct msph_token_stream *
msph_token_stream_fopen(struct msph_ctx *ctx, const char *path)
{
FILE *f;
size_t res;
struct msph_token_stream *ret;
if ((f = fopen(path, "r")) == NULL) {
MSPH_ERR(ctx, MSPH_ERR_SYS);
return (NULL);
}
if ((ret = calloc(1, sizeof(struct msph_token_stream))) == NULL) {
MSPH_ERR(ctx, MSPH_ERR_SYS);
goto err;
}
ret->ctx = ctx;
ret->src.type = MSPH_TOKEN_SRC_FILE;
ret->src.inner.file.f = f;
ret->src.inner.file.eof = 0;
ret->src.inner.file.pos = ret->src.file.buf;
ret->src.inner.file.end = ret->src.file.buf;
ret->src.inner.file.read_ptr = ret->src.file.buf;
res = strlcpy(ret->src.file.name, path, sizeof(ret->src.file.name));
if (res >= sizeof(ret->src.file.name)) {
MSPH_ERR(ctx, MSPH_ERR_TOOLONG);
goto err;
}
return (ret);
err:
if (fclose(f) == EOF)
abort();
if (ret != NULL)
free(ret);
return (NULL);
}
struct msph_token_stream *
msph_token_stream_frombuf(struct msph_ctx *ctx, const char *buf, size_t len)
{
struct msph_token_stream *ret;
if ((ret = calloc(1, sizeof(struct msph_token_stream))) == NULL) {
MSPH_ERR(ctx, MSPH_ERR_SYS);
return (NULL);
}
ret->ctx = ctx;
ret->type = MSPH_TOKEN_SRC_STR;
ret->src.str.s = buf;
ret->src.str.len = len;
ret->src.str.pos = 0;
return (ret);
}
int
msph_token_stream_close(struct msph_token_stream *s)
{
int ret;
ret = -1;
switch (s->type) {
case MSPH_TOKEN_SRC_FILE:
ret = fclose(s->src.file.f);
break;
case MSPH_TOKEN_SRC_STR:
ret = 0;
break;
default:
break;
}
return (ret);
}
/* -1 or num tokens read */
ssize_t
msph_token_stream_read_tok(struct msph_token *ptr, size_t n,
struct msph_token_stream *s)
{
ssize_t ret;
size_t i;
int res;
ret = 0;
res = -1;
while ((res = read_single_tok(&ptr[i], s)) == 1) {
if (res == -1) {
ret = -1;
break;
}
ret++;
}
return (ret);
}
struct msph_token_matcher {
size_t pos_off;
size_t matchlen;
const int tok_type;
} msph_matcher[] = {
{ 0, 0, TOK_START },
{ 0, 0, TOK_IDENT },
{ 0, 0, TOK_END }
};
#define BUF_LEN(b) (sizeof(b) / sizeof(b[0]))
static int
file_char_at(struct msph_ctx *ctx, struct msph_token_src *src, size_t i,
char *out)
{
size_t nread;
size_t maxread;
struct msph_token_src_file *file;
ret = -1;
file = &src->inner.file;
if (file->pos + i < file->end) {
*out = file->buf[file->pos + i];
return (0);
}
if (file->end < file->pos &&
((file->pos + i) % BUF_LEN(file->buf)) < file->end) {
*out = file->buf[(file->pos + i) % BUF_LEN(file->buf)];
return (0);
}
if (file->eof) {
return (-1);
}
if (file->end < file->pos)
maxread = file->pos - file->end;
else
maxread = BUF_LEN(file->buf) - file->end;
maxread = file->end < file->pos ? file->pos - file->end :
BUF_LEN(file->buf) - file->end;
if (maxread == 0) {
MSPH_ERR(ctx, MSPH_ERR_TOOLONG);
return (-1);
}
ret = fread(&file->buf[file->end], sizeof(file->buf[0]), maxread,
file->f);
if (ret == 0) {
if (ferror(file->f)) {
MSPH_ERR(ctx, MSPH_ERR_SYS);
return (-1);
}
file->eof = 1;
return (-1);
}
}
static int
char_at(struct msph_token_src *src, size_t i, char *out)
{
int ret;
switch (src->type) {
case MSPH_TOKEN_SRC_FILE:
ret = file_char_at(s, i, out);
break;
case MSPH_TOKEN_SRC_STR:
ret = str_char_at(s, i, out);
break;
default:
break;
}
return (ret);
}
static int
tok_match(struct msph_token_matcher *m, struct msph_token_stream *s)
{
}
static void
tok_commit(struct msph_token *ptr, struct msph_token_stream *s,
struct msph_matcher *m)
{
SPHO_PRECOND(p != NULL && m != NULL);
SPHO_PRECOND(m->matchlen != 0);
}
/* 1: success, 0: failed match, -1: error */
static int
read_single_tok(struct msph_token *ptr, struct msph_token_stream *s)
{
int res;
size_t m;
size_t max_m;
max_m = 0;
for (m = 0; msph_matcher[m].type != TOK_END; m++) {
res = tok_match(&msph_matcher[m], s);
if (res == -1)
return (-1);
if (res == 0 &&
msph_matcher[m].matchlen > msph_matcher[max_m].matchlen) {
max_m = m;
}
}
if (max_m == 0)
return (0);
tok_commit(ptr, &msph_matcher[max_m]);
return (1);
}