*** empty log message ***
This commit is contained in:
parent
4f47e897ef
commit
f25b760df8
@ -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>
|
||||
@ -24,7 +24,6 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk)
|
||||
}
|
||||
|
||||
awk->opt = 0;
|
||||
awk->tree = XP_NULL;
|
||||
awk->errnum = XP_AWK_ENOERR;
|
||||
|
||||
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->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.ungotc_count = 0;
|
||||
|
||||
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)
|
||||
{
|
||||
|
||||
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;
|
||||
xp_str_close (&awk->token.name);
|
||||
|
@ -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_
|
||||
@ -37,7 +37,10 @@ enum
|
||||
|
||||
XP_AWK_EWHILE, /* keyword 'while' is 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 */
|
||||
int opt;
|
||||
|
||||
/* parse tree */
|
||||
xp_awk_node_t* tree;
|
||||
|
||||
/* io functions */
|
||||
xp_awk_io_t src_func;
|
||||
xp_awk_io_t in_func;
|
||||
@ -82,15 +82,25 @@ struct xp_awk_t
|
||||
void* in_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 */
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
xp_cint_t curc;
|
||||
xp_cint_t ungotc[5];
|
||||
xp_size_t ungotc_count;
|
||||
} lex;
|
||||
|
||||
/* token */
|
||||
struct {
|
||||
struct
|
||||
{
|
||||
int type;
|
||||
xp_str_t name;
|
||||
} token;
|
||||
|
157
ase/awk/parse.c
157
ase/awk/parse.c
@ -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>
|
||||
@ -71,9 +71,11 @@ enum {
|
||||
BINOP_MOD
|
||||
};
|
||||
|
||||
static xp_awk_node_t* __parse_program (xp_awk_t* awk);
|
||||
static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk);
|
||||
static xp_awk_node_t* __parse_patnact (xp_awk_t* awk);
|
||||
static xp_awk_node_t* __parse_progunit (xp_awk_t* awk);
|
||||
static xp_awk_node_t* __parse_function (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_statement (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)
|
||||
{
|
||||
xp_awk_node_t* node;
|
||||
|
||||
GET_CHAR (awk);
|
||||
GET_TOKEN (awk);
|
||||
|
||||
node = __parse_program(awk);
|
||||
if (node == XP_NULL) {
|
||||
while (1) {
|
||||
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);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
xp_printf (XP_TEXT("end - %d\n"), awk->errnum);
|
||||
awk->tree = node;
|
||||
xp_printf (XP_TEXT("sucessful end - %d\n"), awk->errnum);
|
||||
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 }
|
||||
@ -187,33 +191,72 @@ static xp_awk_node_t* __parse_program (xp_awk_t* awk)
|
||||
*/
|
||||
xp_awk_node_t* node;
|
||||
|
||||
while (1) {
|
||||
if (MATCH(awk,TOKEN_FUNCTION)) {
|
||||
node = __parse_funcdcl(awk);
|
||||
node = __parse_function(awk);
|
||||
if (node == XP_NULL) {
|
||||
// TODO: cleanup
|
||||
return XP_NULL;
|
||||
}
|
||||
}
|
||||
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 {
|
||||
node = __parse_patnact(awk);
|
||||
/* pattern-less actions */
|
||||
node = __parse_action (awk);
|
||||
if (node == XP_NULL) {
|
||||
// TODO: cleanup
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
if (node == XP_NULL) return XP_NULL;
|
||||
xp_printf (XP_TEXT(">>>>> breaking ... for testing ...\n"));
|
||||
break;
|
||||
// TODO: weave the action block into awk->tree.actions...
|
||||
}
|
||||
|
||||
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_awk_func_t* func;
|
||||
xp_awk_node_t* body;
|
||||
|
||||
/* TODO: *******************************/
|
||||
|
||||
/* skip the keyword 'function' */
|
||||
if (__get_token(awk) == -1) return XP_NULL;
|
||||
|
||||
/* function name */
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
||||
/* parameter name list */
|
||||
if (MATCH(awk,TOKEN_RPAREN)) {
|
||||
/* no function parameter */
|
||||
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) {
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name);
|
||||
return XP_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (!MATCH(awk,TOKEN_LBRACE)) {
|
||||
// TODO: cleanup
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name);
|
||||
PANIC (awk, XP_AWK_ELBRACE);
|
||||
}
|
||||
if (__get_token(awk) == -1) {
|
||||
// TODO: cleanup
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name);
|
||||
return XP_NULL;
|
||||
}
|
||||
|
||||
/* function body */
|
||||
body = __parse_block (awk);
|
||||
if (body == XP_NULL) {
|
||||
// TODO: cleanup;
|
||||
// TODO: cleanup parameter name list
|
||||
xp_free (name);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (MATCH(awk,TOKEN_BEGIN)) {
|
||||
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 (awk->tree.begin != XP_NULL) PANIC (awk, XP_AWK_EDUPBEGIN);
|
||||
if (__get_token(awk) == -1) return XP_NULL;
|
||||
|
||||
node = __parse_block(awk);
|
||||
node = __parse_action (awk);
|
||||
if (node == XP_NULL) return XP_NULL;
|
||||
|
||||
awk->tree.begin = 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? */
|
||||
static xp_awk_node_t* __parse_block (xp_awk_t* awk)
|
||||
{
|
||||
|
@ -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_
|
||||
@ -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_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 \
|
||||
int type; \
|
||||
xp_awk_node_t* next
|
||||
|
@ -77,7 +77,14 @@ int xp_main (int argc, xp_char_t* argv[])
|
||||
}
|
||||
|
||||
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);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user