enhanced the awk parser
This commit is contained in:
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.c 247 2009-07-31 13:01:04Z hyunghwan.chung $
|
||||
* $Id: awk.c 248 2009-08-06 08:27:14Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -51,9 +51,10 @@ static int init_token (qse_mmgr_t* mmgr, qse_awk_token_t* token)
|
||||
token->name = qse_str_open (mmgr, 0, 128);
|
||||
if (token->name == QSE_NULL) return -1;
|
||||
|
||||
token->file = QSE_NULL;
|
||||
token->type = 0;
|
||||
token->line = 0;
|
||||
token->column = 0;
|
||||
token->lin = 0;
|
||||
token->col = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -70,9 +71,10 @@ static void fini_token (qse_awk_token_t* token)
|
||||
static void clear_token (qse_awk_token_t* token)
|
||||
{
|
||||
if (token->name != QSE_NULL) qse_str_clear (token->name);
|
||||
token->file = QSE_NULL;
|
||||
token->type = 0;
|
||||
token->line = 0;
|
||||
token->column = 0;
|
||||
token->lin = 0;
|
||||
token->col = 0;
|
||||
}
|
||||
|
||||
qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
|
||||
@ -132,6 +134,13 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
|
||||
qse_map_setscale (awk->rwtab, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
|
||||
qse_map_setscale (awk->rwtab, QSE_MAP_VAL, QSE_SIZEOF(qse_char_t));
|
||||
|
||||
awk->sio.names = qse_map_open (mmgr, QSE_SIZEOF(awk), 128, 70);
|
||||
if (awk->sio.names == QSE_NULL) goto oops;
|
||||
*(qse_awk_t**)QSE_XTN(awk->sio.names) = awk;
|
||||
qse_map_setcopier (awk->sio.names, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
|
||||
qse_map_setscale (awk->sio.names, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
|
||||
awk->sio.inp = &awk->sio.arg;
|
||||
|
||||
/* TODO: initial map size?? */
|
||||
awk->tree.funs = qse_map_open (mmgr, QSE_SIZEOF(awk), 512, 70);
|
||||
if (awk->tree.funs == QSE_NULL) goto oops;
|
||||
@ -150,9 +159,12 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
|
||||
awk->parse.named = qse_map_open (mmgr, QSE_SIZEOF(awk), 256, 70);
|
||||
if (awk->parse.named == QSE_NULL) goto oops;
|
||||
*(qse_awk_t**)QSE_XTN(awk->parse.named) = awk;
|
||||
qse_map_setcopier (awk->parse.named, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
|
||||
qse_map_setcopier (awk->parse.named, QSE_MAP_VAL, QSE_MAP_COPIER_INLINE);
|
||||
qse_map_setscale (awk->parse.named, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
|
||||
qse_map_setcopier (
|
||||
awk->parse.named, QSE_MAP_KEY, QSE_MAP_COPIER_INLINE);
|
||||
qse_map_setcopier (
|
||||
awk->parse.named, QSE_MAP_VAL, QSE_MAP_COPIER_INLINE);
|
||||
qse_map_setscale (
|
||||
awk->parse.named, QSE_MAP_KEY, QSE_SIZEOF(qse_char_t));
|
||||
|
||||
awk->parse.gbls = qse_lda_open (mmgr, QSE_SIZEOF(awk), 128);
|
||||
awk->parse.lcls = qse_lda_open (mmgr, QSE_SIZEOF(awk), 64);
|
||||
@ -174,9 +186,6 @@ qse_awk_t* qse_awk_open (qse_mmgr_t* mmgr, qse_size_t xtn, qse_awk_prm_t* prm)
|
||||
qse_lda_setcopier (awk->parse.params, QSE_LDA_COPIER_INLINE);
|
||||
qse_lda_setscale (awk->parse.params, QSE_SIZEOF(qse_char_t));
|
||||
|
||||
awk->parse.nlcls_max = 0;
|
||||
awk->sio.inp = &awk->sio.arg;
|
||||
|
||||
awk->option = QSE_AWK_CLASSIC;
|
||||
awk->errinf.num = QSE_AWK_ENOERR;
|
||||
awk->errinf.lin = 0;
|
||||
@ -213,6 +222,7 @@ oops:
|
||||
if (awk->parse.named) qse_map_close (awk->parse.named);
|
||||
if (awk->parse.funs) qse_map_close (awk->parse.funs);
|
||||
if (awk->tree.funs) qse_map_close (awk->tree.funs);
|
||||
if (awk->sio.names) qse_map_close (awk->sio.names);
|
||||
if (awk->rwtab) qse_map_close (awk->rwtab);
|
||||
if (awk->wtab) qse_map_close (awk->wtab);
|
||||
fini_token (&awk->ntoken);
|
||||
@ -236,6 +246,8 @@ int qse_awk_close (qse_awk_t* awk)
|
||||
qse_map_close (awk->parse.funs);
|
||||
|
||||
qse_map_close (awk->tree.funs);
|
||||
qse_map_close (awk->sio.names);
|
||||
|
||||
qse_map_close (awk->rwtab);
|
||||
qse_map_close (awk->wtab);
|
||||
|
||||
@ -253,15 +265,6 @@ int qse_awk_clear (qse_awk_t* awk)
|
||||
{
|
||||
awk->stopall = QSE_FALSE;
|
||||
|
||||
awk->sio.lex.curc = QSE_CHAR_EOF;
|
||||
awk->sio.lex.ungotc_count = 0;
|
||||
awk->sio.lex.line = 1;
|
||||
awk->sio.lex.column = 1;
|
||||
awk->sio.arg.b.pos = 0;
|
||||
awk->sio.arg.b.len = 0;
|
||||
|
||||
QSE_ASSERT (awk->sio.inp == &awk->sio.arg);
|
||||
|
||||
clear_token (&awk->token);
|
||||
clear_token (&awk->ntoken);
|
||||
clear_token (&awk->ptoken);
|
||||
@ -323,6 +326,20 @@ int qse_awk_clear (qse_awk_t* awk)
|
||||
awk->tree.chain_tail = QSE_NULL;
|
||||
awk->tree.chain_size = 0;
|
||||
|
||||
QSE_ASSERT (awk->sio.inp == &awk->sio.arg);
|
||||
qse_map_clear (awk->sio.names);
|
||||
|
||||
awk->sio.last.c = QSE_CHAR_EOF;
|
||||
awk->sio.last.lin = 0;
|
||||
awk->sio.last.col = 0;
|
||||
awk->sio.last.file = QSE_NULL;
|
||||
awk->sio.nungots = 0;
|
||||
|
||||
awk->sio.arg.lin = 1;
|
||||
awk->sio.arg.col = 1;
|
||||
awk->sio.arg.b.pos = 0;
|
||||
awk->sio.arg.b.len = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -429,3 +446,51 @@ int qse_awk_setword (
|
||||
return 0;
|
||||
}
|
||||
|
||||
qse_size_t qse_awk_getmaxdepth (qse_awk_t* awk, int type)
|
||||
{
|
||||
return (type == QSE_AWK_DEPTH_BLOCK_PARSE)? awk->parse.depth.max.block:
|
||||
(type == QSE_AWK_DEPTH_BLOCK_RUN)? awk->run.depth.max.block:
|
||||
(type == QSE_AWK_DEPTH_EXPR_PARSE)? awk->parse.depth.max.expr:
|
||||
(type == QSE_AWK_DEPTH_EXPR_RUN)? awk->run.depth.max.expr:
|
||||
(type == QSE_AWK_DEPTH_REX_BUILD)? awk->rex.depth.max.build:
|
||||
(type == QSE_AWK_DEPTH_REX_MATCH)? awk->rex.depth.max.match:
|
||||
(type == QSE_AWK_DEPTH_INCLUDE)? awk->parse.depth.max.incl: 0;
|
||||
}
|
||||
|
||||
void qse_awk_setmaxdepth (qse_awk_t* awk, int types, qse_size_t depth)
|
||||
{
|
||||
if (types & QSE_AWK_DEPTH_BLOCK_PARSE)
|
||||
{
|
||||
awk->parse.depth.max.block = depth;
|
||||
}
|
||||
|
||||
if (types & QSE_AWK_DEPTH_EXPR_PARSE)
|
||||
{
|
||||
awk->parse.depth.max.expr = depth;
|
||||
}
|
||||
|
||||
if (types & QSE_AWK_DEPTH_BLOCK_RUN)
|
||||
{
|
||||
awk->run.depth.max.block = depth;
|
||||
}
|
||||
|
||||
if (types & QSE_AWK_DEPTH_EXPR_RUN)
|
||||
{
|
||||
awk->run.depth.max.expr = depth;
|
||||
}
|
||||
|
||||
if (types & QSE_AWK_DEPTH_REX_BUILD)
|
||||
{
|
||||
awk->rex.depth.max.build = depth;
|
||||
}
|
||||
|
||||
if (types & QSE_AWK_DEPTH_REX_MATCH)
|
||||
{
|
||||
awk->rex.depth.max.match = depth;
|
||||
}
|
||||
|
||||
if (types & QSE_AWK_DEPTH_INCLUDE)
|
||||
{
|
||||
awk->parse.depth.max.incl = depth;
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: awk.h 247 2009-07-31 13:01:04Z hyunghwan.chung $
|
||||
* $Id: awk.h 248 2009-08-06 08:27:14Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -99,10 +99,20 @@ struct qse_awk_tree_t
|
||||
typedef struct qse_awk_token_t qse_awk_token_t;
|
||||
struct qse_awk_token_t
|
||||
{
|
||||
int type;
|
||||
qse_str_t* name;
|
||||
qse_size_t line;
|
||||
qse_size_t column;
|
||||
int type;
|
||||
qse_str_t* name;
|
||||
const qse_char_t* file;
|
||||
qse_size_t lin;
|
||||
qse_size_t col;
|
||||
};
|
||||
|
||||
typedef struct qse_awk_lxc_t qse_awk_lxc_t;
|
||||
struct qse_awk_lxc_t
|
||||
{
|
||||
qse_cint_t c;
|
||||
qse_size_t lin;
|
||||
qse_size_t col;
|
||||
const qse_char_t* file;
|
||||
};
|
||||
|
||||
struct qse_awk_t
|
||||
@ -168,10 +178,6 @@ struct qse_awk_t
|
||||
|
||||
/* maximum number of local variables */
|
||||
qse_size_t nlcls_max;
|
||||
|
||||
qse_awk_nde_t* (*parse_block) (
|
||||
qse_awk_t*,qse_size_t,qse_bool_t);
|
||||
|
||||
} parse;
|
||||
|
||||
/* source code management */
|
||||
@ -180,20 +186,14 @@ struct qse_awk_t
|
||||
qse_awk_sio_fun_t inf;
|
||||
qse_awk_sio_fun_t outf;
|
||||
|
||||
struct
|
||||
{
|
||||
qse_cint_t curc;
|
||||
qse_cint_t ungotc[5];
|
||||
qse_size_t ungotc_line[5];
|
||||
qse_size_t ungotc_column[5];
|
||||
qse_size_t ungotc_count;
|
||||
qse_awk_lxc_t last;
|
||||
|
||||
qse_size_t line;
|
||||
qse_size_t column;
|
||||
} lex;
|
||||
qse_size_t nungots;
|
||||
qse_awk_lxc_t ungot[5];
|
||||
|
||||
qse_awk_sio_arg_t arg;
|
||||
qse_awk_sio_arg_t arg; /* for the top level source */
|
||||
qse_awk_sio_arg_t* inp; /* current input */
|
||||
qse_map_t* names;
|
||||
} sio;
|
||||
|
||||
/* previous token */
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: err.c 247 2009-07-31 13:01:04Z hyunghwan.chung $
|
||||
* $Id: err.c 248 2009-08-06 08:27:14Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -45,7 +45,6 @@ const qse_char_t* qse_awk_dflerrstr (qse_awk_t* awk, qse_awk_errnum_t errnum)
|
||||
|
||||
QSE_T("invalid character '${0}'"),
|
||||
QSE_T("invalid digit '${0}'"),
|
||||
QSE_T("failed to unget character"),
|
||||
|
||||
QSE_T("unexpected end of source"),
|
||||
QSE_T("comment not closed properly"),
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* $Id: map.c 120 2009-04-10 05:00:00Z hyunghwan.chung $
|
||||
* $Id: map.c 248 2009-08-06 08:27:14Z hyunghwan.chung $
|
||||
*
|
||||
Copyright 2006-2009 Chung, Hyung-Hwan.
|
||||
|
||||
@ -46,6 +46,11 @@ QSE_IMPLEMENT_COMMON_FUNCTIONS (map)
|
||||
#define KTOB(map,len) ((len)*(map)->scale[QSE_MAP_KEY])
|
||||
#define VTOB(map,len) ((len)*(map)->scale[QSE_MAP_VAL])
|
||||
|
||||
#define UPSERT 1
|
||||
#define UPDATE 2
|
||||
#define ENSERT 3
|
||||
#define INSERT 4
|
||||
|
||||
static int reorganize (map_t* map);
|
||||
|
||||
static size_t hash_key (map_t* map, const void* kptr, size_t klen)
|
||||
@ -411,8 +416,8 @@ pair_t* qse_map_search (map_t* map, const void* kptr, size_t klen)
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
pair_t* qse_map_upsert (
|
||||
map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen)
|
||||
static pair_t* insert (
|
||||
map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen, int opt)
|
||||
{
|
||||
pair_t* pair, * p, * prev, * next;
|
||||
size_t hc;
|
||||
@ -427,23 +432,44 @@ pair_t* qse_map_upsert (
|
||||
|
||||
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
p = change_pair_val (map, pair, vptr, vlen);
|
||||
if (p == QSE_NULL) return QSE_NULL; /* change error */
|
||||
if (p != pair)
|
||||
/* found a pair with a matching key */
|
||||
switch (opt)
|
||||
{
|
||||
/* the pair has been reallocated. relink it */
|
||||
if (prev == QSE_NULL) map->bucket[hc] = p;
|
||||
else NEXT(prev) = p;
|
||||
NEXT(p) = next;
|
||||
}
|
||||
case UPSERT:
|
||||
case UPDATE:
|
||||
p = change_pair_val (map, pair, vptr, vlen);
|
||||
if (p == QSE_NULL)
|
||||
{
|
||||
/* error in change the value */
|
||||
return QSE_NULL;
|
||||
}
|
||||
if (p != pair)
|
||||
{
|
||||
/* pair reallocated.
|
||||
* relink it */
|
||||
if (prev == QSE_NULL)
|
||||
map->bucket[hc] = p;
|
||||
else NEXT(prev) = p;
|
||||
NEXT(p) = next;
|
||||
}
|
||||
return p;
|
||||
|
||||
return p; /* value changed for the existing key */
|
||||
case ENSERT:
|
||||
/* return existing pair */
|
||||
return pair;
|
||||
|
||||
case INSERT:
|
||||
/* return failure */
|
||||
return QSE_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
prev = pair;
|
||||
pair = next;
|
||||
}
|
||||
|
||||
if (opt == UPDATE) return QSE_NULL;
|
||||
|
||||
if (map->threshold > 0 && map->size >= map->threshold)
|
||||
{
|
||||
if (reorganize(map) == 0) /* ignore the error */
|
||||
@ -464,78 +490,29 @@ pair_t* qse_map_upsert (
|
||||
return pair; /* new key added */
|
||||
}
|
||||
|
||||
pair_t* qse_map_insert (map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen)
|
||||
pair_t* qse_map_upsert (
|
||||
map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen)
|
||||
{
|
||||
pair_t* pair;
|
||||
size_t hc;
|
||||
|
||||
hc = map->hasher(map,kptr,klen) % map->capa;
|
||||
pair = map->bucket[hc];
|
||||
|
||||
while (pair != QSE_NULL)
|
||||
{
|
||||
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
return QSE_NULL;
|
||||
}
|
||||
|
||||
pair = NEXT(pair);
|
||||
}
|
||||
|
||||
if (map->threshold > 0 && map->size >= map->threshold)
|
||||
{
|
||||
if (reorganize(map) == 0) /* ignore the error */
|
||||
{
|
||||
hc = map->hasher(map,kptr,klen) % map->capa;
|
||||
}
|
||||
}
|
||||
|
||||
QSE_ASSERT (pair == QSE_NULL);
|
||||
|
||||
pair = alloc_pair (map, kptr, klen, vptr, vlen);
|
||||
if (pair == QSE_NULL) return QSE_NULL;
|
||||
|
||||
NEXT(pair) = map->bucket[hc];
|
||||
map->bucket[hc] = pair;
|
||||
map->size++;
|
||||
|
||||
return pair;
|
||||
return insert (map, kptr, klen, vptr, vlen, UPSERT);
|
||||
}
|
||||
|
||||
pair_t* qse_map_update (map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen)
|
||||
pair_t* qse_map_ensert (
|
||||
map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen)
|
||||
{
|
||||
pair_t* pair, * p, * prev, * next;
|
||||
size_t hc;
|
||||
return insert (map, kptr, klen, vptr, vlen, ENSERT);
|
||||
}
|
||||
|
||||
hc = map->hasher(map,kptr,klen) % map->capa;
|
||||
pair = map->bucket[hc];
|
||||
prev = QSE_NULL;
|
||||
pair_t* qse_map_insert (
|
||||
map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen)
|
||||
{
|
||||
return insert (map, kptr, klen, vptr, vlen, INSERT);
|
||||
}
|
||||
|
||||
while (pair != QSE_NULL)
|
||||
{
|
||||
next = NEXT(pair);
|
||||
|
||||
if (map->comper (map, KPTR(pair), KLEN(pair), kptr, klen) == 0)
|
||||
{
|
||||
p = change_pair_val (map, pair, vptr, vlen);
|
||||
|
||||
if (p == QSE_NULL) return QSE_NULL; /* change error */
|
||||
if (p != pair)
|
||||
{
|
||||
/* the pair has been reallocated. relink it */
|
||||
if (prev == QSE_NULL) map->bucket[hc] = p;
|
||||
else NEXT(prev) = p;
|
||||
NEXT(p) = next;
|
||||
}
|
||||
|
||||
return p; /* value changed for the existing key */
|
||||
}
|
||||
|
||||
prev = pair;
|
||||
pair = next;
|
||||
}
|
||||
|
||||
return QSE_NULL;
|
||||
pair_t* qse_map_update (
|
||||
map_t* map, void* kptr, size_t klen, void* vptr, size_t vlen)
|
||||
{
|
||||
return insert (map, kptr, klen, vptr, vlen, UPDATE);
|
||||
}
|
||||
|
||||
int qse_map_delete (map_t* map, const void* kptr, size_t klen)
|
||||
|
Reference in New Issue
Block a user