enhanced the awk parser

This commit is contained in:
2009-08-07 02:27:14 +00:00
parent ff92573543
commit 3fc663609e
10 changed files with 545 additions and 540 deletions

View File

@ -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;
}
}

View File

@ -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 */

View File

@ -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

View File

@ -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)