*** empty log message ***

This commit is contained in:
hyung-hwan 2006-01-22 15:11:17 +00:00
parent 4f47e897ef
commit f25b760df8
5 changed files with 157 additions and 70 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.c,v 1.9 2006-01-19 16:28:21 bacon Exp $ * $Id: awk.c,v 1.10 2006-01-22 15:11:17 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -24,7 +24,6 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
} }
awk->opt = 0; awk->opt = 0;
awk->tree = XP_NULL;
awk->errnum = XP_AWK_ENOERR; awk->errnum = XP_AWK_ENOERR;
awk->src_func = XP_NULL; awk->src_func = XP_NULL;
@ -35,23 +34,25 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
awk->in_arg = XP_NULL; awk->in_arg = XP_NULL;
awk->out_arg = XP_NULL; awk->out_arg = XP_NULL;
awk->tree.begin = XP_NULL;
awk->tree.end = XP_NULL;
//awk->tree.funcs = XP_NULL;
awk->lex.curc = XP_CHAR_EOF; awk->lex.curc = XP_CHAR_EOF;
awk->lex.ungotc_count = 0; awk->lex.ungotc_count = 0;
return awk; return awk;
} }
static void __collapse_tree (xp_awk_t* awk)
{
/* TODO: collapse the tree */
/* TODO */
awk->tree = XP_NULL;
}
int xp_awk_close (xp_awk_t* awk) int xp_awk_close (xp_awk_t* awk)
{ {
if (awk->tree != XP_NULL) __collapse_tree (awk); if (awk->tree.begin != XP_NULL) xp_awk_clrpt (awk->tree.begin);
if (awk->tree.end != XP_NULL) xp_awk_clrpt (awk->tree.end);
/*
// TODO: destroy function list
if (awk->tree.funcs != XP_NULL)
*/
if (xp_awk_detsrc(awk) == -1) return -1; if (xp_awk_detsrc(awk) == -1) return -1;
xp_str_close (&awk->token.name); xp_str_close (&awk->token.name);

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.16 2006-01-20 07:29:53 bacon Exp $ * $Id: awk.h,v 1.17 2006-01-22 15:11:17 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -37,7 +37,10 @@ enum
XP_AWK_EWHILE, /* keyword 'while' is expected */ XP_AWK_EWHILE, /* keyword 'while' is expected */
XP_AWK_EASSIGN, /* assignment statement expected */ XP_AWK_EASSIGN, /* assignment statement expected */
XP_AWK_EIDENT /* identifier expected */ XP_AWK_EIDENT, /* identifier expected */
XP_AWK_EDUPBEGIN, /* duplicate BEGIN */
XP_AWK_EDUPEND, /* duplicate END */
XP_AWK_EDUPFUNC /* duplicate function name */
}; };
/* /*
@ -70,9 +73,6 @@ struct xp_awk_t
/* options */ /* options */
int opt; int opt;
/* parse tree */
xp_awk_node_t* tree;
/* io functions */ /* io functions */
xp_awk_io_t src_func; xp_awk_io_t src_func;
xp_awk_io_t in_func; xp_awk_io_t in_func;
@ -82,15 +82,25 @@ struct xp_awk_t
void* in_arg; void* in_arg;
void* out_arg; void* out_arg;
/* parse tree */
struct
{
//xp_awk_hash_t* funcs;
xp_awk_node_t* begin;
xp_awk_node_t* end;
} tree;
/* source buffer management */ /* source buffer management */
struct { struct
{
xp_cint_t curc; xp_cint_t curc;
xp_cint_t ungotc[5]; xp_cint_t ungotc[5];
xp_size_t ungotc_count; xp_size_t ungotc_count;
} lex; } lex;
/* token */ /* token */
struct { struct
{
int type; int type;
xp_str_t name; xp_str_t name;
} token; } token;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.28 2006-01-20 15:58:42 bacon Exp $ * $Id: parse.c,v 1.29 2006-01-22 15:11:17 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -71,9 +71,11 @@ enum {
BINOP_MOD BINOP_MOD
}; };
static xp_awk_node_t* __parse_program (xp_awk_t* awk); static xp_awk_node_t* __parse_progunit (xp_awk_t* awk);
static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk); static xp_awk_node_t* __parse_function (xp_awk_t* awk);
static xp_awk_node_t* __parse_patnact (xp_awk_t* awk); static xp_awk_node_t* __parse_begin (xp_awk_t* awk);
static xp_awk_node_t* __parse_end (xp_awk_t* awk);
static xp_awk_node_t* __parse_action (xp_awk_t* awk);
static xp_awk_node_t* __parse_block (xp_awk_t* awk); static xp_awk_node_t* __parse_block (xp_awk_t* awk);
static xp_awk_node_t* __parse_statement (xp_awk_t* awk); static xp_awk_node_t* __parse_statement (xp_awk_t* awk);
static xp_awk_node_t* __parse_statement_nb (xp_awk_t* awk); static xp_awk_node_t* __parse_statement_nb (xp_awk_t* awk);
@ -163,23 +165,25 @@ static struct __kwent __kwtab[] =
int xp_awk_parse (xp_awk_t* awk) int xp_awk_parse (xp_awk_t* awk)
{ {
xp_awk_node_t* node;
GET_CHAR (awk); GET_CHAR (awk);
GET_TOKEN (awk); GET_TOKEN (awk);
node = __parse_program(awk); while (1) {
if (node == XP_NULL) { if (MATCH(awk,TOKEN_EOF)) break;
if (__parse_progunit(awk) == XP_NULL) {
// TODO: cleanup the parse tree created so far....
xp_printf (XP_TEXT("error - %d\n"), awk->errnum); xp_printf (XP_TEXT("error - %d\n"), awk->errnum);
return -1; return -1;
}
} }
xp_printf (XP_TEXT("end - %d\n"), awk->errnum); xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum);
awk->tree = node;
return 0; return 0;
} }
static xp_awk_node_t* __parse_program (xp_awk_t* awk) static xp_awk_node_t* __parse_progunit (xp_awk_t* awk)
{ {
/* /*
pattern { action } pattern { action }
@ -187,33 +191,72 @@ static xp_awk_node_t* __parse_program (xp_awk_t* awk)
*/ */
xp_awk_node_t* node; xp_awk_node_t* node;
while (1) { if (MATCH(awk,TOKEN_FUNCTION)) {
if (MATCH(awk,TOKEN_FUNCTION)) { node = __parse_function(awk);
node = __parse_funcdcl(awk); if (node == XP_NULL) {
// TODO: cleanup
return XP_NULL;
} }
else { }
node = __parse_patnact(awk); else if (MATCH(awk,TOKEN_BEGIN)) {
node = __parse_begin (awk);
if (node == XP_NULL) {
// TODO: cleanup
return XP_NULL;
}
}
else if (MATCH(awk, TOKEN_END)) {
node = __parse_end (awk);
if (node == XP_NULL) {
// TODO: cleanup
return XP_NULL;
}
}
/* TODO: process patterns and expressions */
/*
expressions
/regular expression/
pattern && pattern
pattern || pattern
!pattern
(pattern)
pattern, pattern
*/
else {
/* pattern-less actions */
node = __parse_action (awk);
if (node == XP_NULL) {
// TODO: cleanup
return XP_NULL;
} }
if (node == XP_NULL) return XP_NULL; // TODO: weave the action block into awk->tree.actions...
xp_printf (XP_TEXT(">>>>> breaking ... for testing ...\n"));
break;
} }
return node; return node;
} }
static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk) static xp_bool_t __function_defined (xp_awk_t* awk, const xp_char_t* name)
{
// TODO: complete this...
return xp_false;
}
static xp_awk_node_t* __parse_function (xp_awk_t* awk)
{ {
xp_char_t* name; xp_char_t* name;
xp_awk_func_t* func;
xp_awk_node_t* body; xp_awk_node_t* body;
/* TODO: *******************************/
/* skip the keyword 'function' */
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
/* function name */
if (!MATCH(awk,TOKEN_IDENT)) PANIC (awk, XP_AWK_EIDENT); if (!MATCH(awk,TOKEN_IDENT)) PANIC (awk, XP_AWK_EIDENT);
if (__function_defined(awk,XP_STR_BUF(&awk->token.name))) {
PANIC (awk, XP_AWK_EDUPFUNC);
}
name = xp_strdup (XP_STR_BUF(&awk->token.name)); name = xp_strdup (XP_STR_BUF(&awk->token.name));
if (name == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); if (name == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
@ -233,6 +276,7 @@ static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk)
return XP_NULL; return XP_NULL;
} }
/* parameter name list */
if (MATCH(awk,TOKEN_RPAREN)) { if (MATCH(awk,TOKEN_RPAREN)) {
/* no function parameter */ /* no function parameter */
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
@ -266,64 +310,81 @@ static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk)
} }
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
// TODO: cleanup parameter name list
xp_free (name); xp_free (name);
return XP_NULL; return XP_NULL;
} }
} }
if (!MATCH(awk,TOKEN_LBRACE)) { if (!MATCH(awk,TOKEN_LBRACE)) {
// TODO: cleanup // TODO: cleanup parameter name list
xp_free (name);
PANIC (awk, XP_AWK_ELBRACE); PANIC (awk, XP_AWK_ELBRACE);
} }
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
// TODO: cleanup // TODO: cleanup parameter name list
xp_free (name);
return XP_NULL; return XP_NULL;
} }
/* function body */
body = __parse_block (awk); body = __parse_block (awk);
if (body == XP_NULL) { if (body == XP_NULL) {
// TODO: cleanup; // TODO: cleanup parameter name list
xp_free (name);
return XP_NULL; return XP_NULL;
} }
// TODO: return something else... func = (xp_awk_func_t*) xp_malloc (xp_sizeof(xp_awk_func_t));
if (func == XP_NULL) {
xp_free (name);
xp_awk_clrpt (body);
return XP_NULL;
}
func->name = name;
func->nargs = 0;
func->body = body;
/* TODO: weave the function body into awk->tree.funcs */
return body; return body;
} }
static xp_awk_node_t* __parse_patnact (xp_awk_t* awk) static xp_awk_node_t* __parse_begin (xp_awk_t* awk)
{ {
/*
BEGIN
END
expressions
/regular expression/
pattern && pattern
pattern || pattern
!pattern
(pattern)
pattern, pattern
*/
xp_awk_node_t* node; xp_awk_node_t* node;
if (MATCH(awk,TOKEN_BEGIN)) { if (awk->tree.begin != XP_NULL) PANIC (awk, XP_AWK_EDUPBEGIN);
if (__get_token(awk) == -1) return XP_NULL;
}
else if (MATCH(awk,TOKEN_END)) {
if (__get_token(awk) == -1) return XP_NULL;
}
/* patterns ...
* etc */
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
node = __parse_block(awk); node = __parse_action (awk);
if (node == XP_NULL) return XP_NULL; if (node == XP_NULL) return XP_NULL;
awk->tree.begin = node;
return node; return node;
} }
static xp_awk_node_t* __parse_end (xp_awk_t* awk)
{
xp_awk_node_t* node;
if (awk->tree.end != XP_NULL) PANIC (awk, XP_AWK_EDUPEND);
if (__get_token(awk) == -1) return XP_NULL;
node = __parse_action (awk);
if (node == XP_NULL) return XP_NULL;
awk->tree.end = node;
return node;
}
static xp_awk_node_t* __parse_action (xp_awk_t* awk)
{
if (!MATCH(awk,TOKEN_LBRACE)) PANIC (awk, XP_AWK_ELBRACE);
if (__get_token(awk) == -1) return XP_NULL;
return __parse_block(awk);
}
/* TODO: what is the best name for the parsing routine for the outermost block? */ /* TODO: what is the best name for the parsing routine for the outermost block? */
static xp_awk_node_t* __parse_block (xp_awk_t* awk) static xp_awk_node_t* __parse_block (xp_awk_t* awk)
{ {

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tree.h,v 1.14 2006-01-20 07:29:54 bacon Exp $ * $Id: tree.h,v 1.15 2006-01-22 15:11:17 bacon Exp $
*/ */
#ifndef _XP_AWK_TREE_H_ #ifndef _XP_AWK_TREE_H_
@ -40,6 +40,14 @@ typedef struct xp_awk_node_if_t xp_awk_node_if_t;
typedef struct xp_awk_node_while_t xp_awk_node_while_t; typedef struct xp_awk_node_while_t xp_awk_node_while_t;
typedef struct xp_awk_node_for_t xp_awk_node_for_t; typedef struct xp_awk_node_for_t xp_awk_node_for_t;
struct xp_awk_func_t
{
xp_char_t* name;
xp_size_t nargs;
xp_awk_node_t* body;
};
#define XP_AWK_NODE_HDR \ #define XP_AWK_NODE_HDR \
int type; \ int type; \
xp_awk_node_t* next xp_awk_node_t* next

View File

@ -77,7 +77,14 @@ int xp_main (int argc, xp_char_t* argv[])
} }
xp_printf (XP_TEXT("-----------------------------------------------\n")); xp_printf (XP_TEXT("-----------------------------------------------\n"));
xp_awk_prnpt (awk.tree); if (awk.tree.begin != XP_NULL) {
xp_printf (XP_TEXT("BEGIN "));
xp_awk_prnpt (awk.tree.begin);
}
if (awk.tree.end != XP_NULL) {
xp_printf (XP_TEXT("END "));
xp_awk_prnpt (awk.tree.end);
}
xp_awk_close (&awk); xp_awk_close (&awk);
return 0; return 0;