broken code, but added attempt at writing grammar
This commit is contained in:
parent
fb95e5d026
commit
20e3757f44
18 changed files with 1145 additions and 142 deletions
247
src/msph/msph_token.c
Normal file
247
src/msph/msph_token.c
Normal 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);
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue