125 lines
2.0 KiB
C
125 lines
2.0 KiB
C
|
|
#include <lex/util.h>
|
|
#include <string.h>
|
|
#include <stdlib.h>
|
|
#include <glib.h>
|
|
#include <mem/cache.h>
|
|
|
|
// implementation based on:
|
|
// https://github.com/sunxfancy/flex-bison-examples/blob/master/error-handling/ccalc.c
|
|
|
|
char* buffer = NULL;
|
|
|
|
static int eof = 0;
|
|
static int nRow = 0;
|
|
static int nBuffer = 0;
|
|
static int lBuffer = 0;
|
|
static int nTokenStart = 0;
|
|
static int nTokenLength = 0;
|
|
static int nTokenNextStart = 0;
|
|
|
|
void lex_init(void) {
|
|
buffer = mem_alloc(MemoryNamespaceStatic, MAX_READ_BUFFER_SIZE);
|
|
}
|
|
|
|
void lex_reset(void) {
|
|
eof = 0;
|
|
nRow = 0;
|
|
nBuffer = 0;
|
|
lBuffer = 0;
|
|
nTokenStart = 0;
|
|
nTokenLength = 0;
|
|
nTokenNextStart = 0;
|
|
}
|
|
|
|
void beginToken(char *t) {
|
|
nTokenStart = nTokenNextStart;
|
|
nTokenLength = (int) strlen(t);
|
|
nTokenNextStart = nBuffer + 1;
|
|
|
|
yylloc.first_line = nRow;
|
|
yylloc.first_column = nTokenStart;
|
|
yylloc.last_line = nRow;
|
|
yylloc.last_column = nTokenStart + nTokenLength - 1;
|
|
}
|
|
|
|
int nextChar(char *dst) {
|
|
int frc;
|
|
|
|
if (eof)
|
|
return 0;
|
|
|
|
while (nBuffer >= lBuffer) {
|
|
frc = getNextLine();
|
|
if (frc != 0) {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
dst[0] = buffer[nBuffer];
|
|
nBuffer += 1;
|
|
|
|
return dst[0] != 0;
|
|
}
|
|
|
|
int getNextLine(void) {
|
|
char *p;
|
|
|
|
nBuffer = 0;
|
|
nTokenStart = -1;
|
|
nTokenNextStart = 1;
|
|
eof = 0;
|
|
|
|
p = fgets(buffer, MAX_READ_BUFFER_SIZE, yyin);
|
|
if (p == NULL) {
|
|
if (ferror(yyin)) {
|
|
return -1;
|
|
}
|
|
eof = 1;
|
|
return 1;
|
|
}
|
|
|
|
nRow += 1;
|
|
lBuffer = (int) strlen(buffer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
struct ConstEscSeq {
|
|
char* esc;
|
|
char* rep;
|
|
};
|
|
|
|
static struct ConstEscSeq sequences[] = {
|
|
{
|
|
"\\n",
|
|
"\n"
|
|
},
|
|
{
|
|
"\\\\",
|
|
"\\"
|
|
},
|
|
{
|
|
"\\t",
|
|
"\t"
|
|
},
|
|
{
|
|
"\\r",
|
|
"\r"
|
|
}
|
|
};
|
|
|
|
char* collapse_escape_sequences(char* string) {
|
|
GString* unesc = g_string_new(string);
|
|
|
|
for (int i = 0; i < 4; i++) {
|
|
g_string_replace(unesc, sequences[i].esc, sequences[i].rep, 0);
|
|
}
|
|
|
|
char* str = mem_strdup(MemoryNamespaceLex, unesc->str);
|
|
|
|
g_string_free(unesc, TRUE);
|
|
|
|
return str;
|
|
}
|