*** empty log message ***

This commit is contained in:
hyung-hwan 2006-01-20 07:33:46 +00:00
parent 7ac46c0ae0
commit 4a61107140
7 changed files with 363 additions and 29 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.15 2006-01-19 16:28:21 bacon Exp $ * $Id: awk.h,v 1.16 2006-01-20 07:29:53 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -36,7 +36,8 @@ enum
XP_AWK_EEXPR, /* expression expected */ XP_AWK_EEXPR, /* expression expected */
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 */
}; };
/* /*

View File

@ -1,4 +1,4 @@
SRCS = awk.c parse.c SRCS = awk.c parse.c tree.c sa.c
OBJS = $(SRCS:.c=.o) OBJS = $(SRCS:.c=.o)
OUT = libxpawk.a OUT = libxpawk.a

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.26 2006-01-19 16:28:21 bacon Exp $ * $Id: parse.c,v 1.27 2006-01-20 07:29:54 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -94,6 +94,8 @@ static xp_awk_node_t* __parse_break (xp_awk_t* awk);
static xp_awk_node_t* __parse_continue (xp_awk_t* awk); static xp_awk_node_t* __parse_continue (xp_awk_t* awk);
static xp_awk_node_t* __parse_return (xp_awk_t* awk); static xp_awk_node_t* __parse_return (xp_awk_t* awk);
static xp_awk_node_t* __parse_exit (xp_awk_t* awk); static xp_awk_node_t* __parse_exit (xp_awk_t* awk);
static xp_awk_node_t* __parse_next (xp_awk_t* awk);
static xp_awk_node_t* __parse_nextfile (xp_awk_t* awk);
static int __get_token (xp_awk_t* awk); static int __get_token (xp_awk_t* awk);
static int __get_char (xp_awk_t* awk); static int __get_char (xp_awk_t* awk);
@ -203,9 +205,91 @@ break;
static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk) static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk)
{ {
xp_char_t* name;
xp_awk_node_t* body;
/* TODO: *******************************/
/* skip the keyword 'function' */
if (__get_token(awk) == -1) return XP_NULL;
if (!MATCH(awk,TOKEN_IDENT)) PANIC (awk, XP_AWK_EIDENT);
name = xp_strdup (XP_STR_BUF(&awk->token.name));
if (name == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
/* skip the function name */
if (__get_token(awk) == -1) {
xp_free (name);
return XP_NULL; return XP_NULL;
} }
if (!MATCH(awk,TOKEN_LPAREN)) {
xp_free (name);
PANIC (awk, XP_AWK_ELPAREN);
}
if (__get_token(awk) == -1) {
xp_free (name);
return XP_NULL;
}
if (MATCH(awk,TOKEN_RPAREN)) {
/* no function parameter */
if (__get_token(awk) == -1) {
xp_free (name);
return XP_NULL;
}
}
else {
while (1) {
if (!MATCH(awk,TOKEN_IDENT)) {
xp_free (name);
PANIC (awk, XP_AWK_EIDENT);
}
if (__get_token(awk) == -1) {
xp_free (name);
return XP_NULL;
}
if (MATCH(awk,TOKEN_RPAREN)) break;
if (!MATCH(awk,TOKEN_COMMA)) {
xp_free (name);
PANIC (awk, XP_AWK_ECOMMA);
}
if (__get_token(awk) == -1) {
xp_free (name);
return XP_NULL;
}
}
if (__get_token(awk) == -1) {
xp_free (name);
return XP_NULL;
}
}
if (!MATCH(awk,TOKEN_LBRACE)) {
// TODO: cleanup
PANIC (awk, XP_AWK_ELBRACE);
}
if (__get_token(awk) == -1) {
// TODO: cleanup
return XP_NULL;
}
body = __parse_block (awk);
if (body == XP_NULL) {
// TODO: cleanup;
return XP_NULL;
}
// TODO: return something else...
return body;
}
static xp_awk_node_t* __parse_patnact (xp_awk_t* awk) static xp_awk_node_t* __parse_patnact (xp_awk_t* awk)
{ {
/* /*
@ -366,12 +450,13 @@ static xp_awk_node_t* __parse_statement_nb (xp_awk_t* awk)
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
node = __parse_exit(awk); node = __parse_exit(awk);
} }
/*
TODO: /* TODO:
else if (MATCH(awk,TOKEN_DELETE)) { else if (MATCH(awk,TOKEN_DELETE)) {
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
node = __parse_delete(awk); node = __parse_delete(awk);
} }
*/
else if (MATCH(awk,TOKEN_NEXT)) { else if (MATCH(awk,TOKEN_NEXT)) {
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
node = __parse_next(awk); node = __parse_next(awk);
@ -380,7 +465,6 @@ TODO:
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
node = __parse_nextfile(awk); node = __parse_nextfile(awk);
} }
*/
else { else {
node = __parse_expression(awk); node = __parse_expression(awk);
} }
@ -411,6 +495,46 @@ static xp_awk_node_t* __parse_expression (xp_awk_t* awk)
* <basic expression> ::= * <basic expression> ::=
*/ */
xp_awk_node_t* x, * y;
xp_awk_node_assign_t* node;
x = __parse_basic_expr (awk, XP_NULL);
if (x == XP_NULL) return XP_NULL;
if (!MATCH(awk,TOKEN_ASSIGN)) return x;
xp_assert (x->next == XP_NULL);
if (x->type != XP_AWK_NODE_VAR && x->type != XP_AWK_NODE_IDX) {
xp_awk_clrpt (x);
PANIC (awk, XP_AWK_EASSIGN);
}
if (__get_token(awk) == -1) {
xp_awk_clrpt (x);
return XP_NULL;
}
y = __parse_basic_expr (awk, XP_NULL);
if (y == XP_NULL) {
xp_awk_clrpt (x);
return XP_NULL;
}
node = (xp_awk_node_assign_t*)xp_malloc (xp_sizeof(xp_awk_node_assign_t));
if (node == XP_NULL) {
xp_awk_clrpt (x);
xp_awk_clrpt (y);
PANIC (awk, XP_AWK_ENOMEM);
}
node->type = XP_AWK_NODE_ASSIGN;
node->next = XP_NULL;
node->left = x;
node->right = y;
return (xp_awk_node_t*)node;
#if 0
xp_awk_node_t* x; xp_awk_node_t* x;
if (MATCH(awk,TOKEN_IDENT)) { if (MATCH(awk,TOKEN_IDENT)) {
@ -424,15 +548,6 @@ static xp_awk_node_t* __parse_expression (xp_awk_t* awk)
return XP_NULL; return XP_NULL;
} }
/*
if (MATCH(awk,TOKEN_LBRACK)) {
// TODO: hashidx....
xp_awk_node_t* node;
node = __parse_hashidx (awk, name);
if (node == XP_NULL) xp_free (name);
return (xp_awk_node_t*)node;
}
*/
if (MATCH(awk,TOKEN_ASSIGN)) { if (MATCH(awk,TOKEN_ASSIGN)) {
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
@ -463,8 +578,10 @@ static xp_awk_node_t* __parse_expression (xp_awk_t* awk)
} }
return x; return x;
#endif
} }
#if 0
static xp_awk_node_t* __parse_assignment (xp_awk_t* awk, xp_char_t* ident) static xp_awk_node_t* __parse_assignment (xp_awk_t* awk, xp_char_t* ident)
{ {
xp_awk_node_assign_t* node; xp_awk_node_assign_t* node;
@ -496,6 +613,7 @@ static xp_awk_node_t* __parse_assignment (xp_awk_t* awk, xp_char_t* ident)
return (xp_awk_node_t*)node; return (xp_awk_node_t*)node;
} }
#endif
static xp_awk_node_t* __parse_basic_expr (xp_awk_t* awk, xp_char_t* ident) static xp_awk_node_t* __parse_basic_expr (xp_awk_t* awk, xp_char_t* ident)
{ {
@ -734,36 +852,30 @@ static xp_awk_node_t* __parse_hashidx (xp_awk_t* awk, xp_char_t* name)
if (__get_token(awk) == -1) return XP_NULL; if (__get_token(awk) == -1) return XP_NULL;
xp_printf (XP_TEXT("----------------\n"));
idx = __parse_expression (awk); idx = __parse_expression (awk);
if (idx == XP_NULL) return XP_NULL; if (idx == XP_NULL) return XP_NULL;
xp_printf (XP_TEXT("+++++++++++++++++++\n"));
if (!MATCH(awk,TOKEN_RBRACK)) { if (!MATCH(awk,TOKEN_RBRACK)) {
xp_awk_clrpt (idx); xp_awk_clrpt (idx);
PANIC (awk, XP_AWK_ERBRACK); PANIC (awk, XP_AWK_ERBRACK);
} }
xp_printf (XP_TEXT("$$$$$$$$$$$$$$$$$$$$$$\n"));
if (__get_token(awk) == -1) { if (__get_token(awk) == -1) {
xp_awk_clrpt (idx); xp_awk_clrpt (idx);
return XP_NULL; return XP_NULL;
} }
xp_printf (XP_TEXT("#######################\n"));
node = (xp_awk_node_idx_t*) xp_malloc (xp_sizeof(xp_awk_node_idx_t)); node = (xp_awk_node_idx_t*) xp_malloc (xp_sizeof(xp_awk_node_idx_t));
if (node == XP_NULL) { if (node == XP_NULL) {
xp_awk_clrpt (idx); xp_awk_clrpt (idx);
PANIC (awk, XP_AWK_ENOMEM); PANIC (awk, XP_AWK_ENOMEM);
} }
xp_printf (XP_TEXT("~~~~~~~~~~~~~~~~~~~~~~~~~`\n"));
node->type = XP_AWK_NODE_IDX; node->type = XP_AWK_NODE_IDX;
node->next = XP_NULL; node->next = XP_NULL;
node->name = name; node->name = name;
node->idx = idx; node->idx = idx;
xp_printf (XP_TEXT("%%%%%%%%%%%%%%%%%%%%%%%%%[%s]\n"), XP_STR_BUF(&awk->token.name));
return (xp_awk_node_t*)node; return (xp_awk_node_t*)node;
} }
@ -1152,6 +1264,30 @@ static xp_awk_node_t* __parse_exit (xp_awk_t* awk)
return (xp_awk_node_t*)node; return (xp_awk_node_t*)node;
} }
static xp_awk_node_t* __parse_next (xp_awk_t* awk)
{
xp_awk_node_t* node;
node = (xp_awk_node_t*) xp_malloc (xp_sizeof(xp_awk_node_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_NEXT;
node->next = XP_NULL;
return node;
}
static xp_awk_node_t* __parse_nextfile (xp_awk_t* awk)
{
xp_awk_node_t* node;
node = (xp_awk_node_t*) xp_malloc (xp_sizeof(xp_awk_node_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_NEXTFILE;
node->next = XP_NULL;
return node;
}
static int __get_token (xp_awk_t* awk) static int __get_token (xp_awk_t* awk)
{ {
xp_cint_t c; xp_cint_t c;

87
ase/awk/sa.c Normal file
View File

@ -0,0 +1,87 @@
/*
* $Id: sa.c,v 1.1 2006-01-20 07:32:38 bacon Exp $
*/
#include <xp/awk/sa.h>
#ifdef __STAND_ALONE
xp_str_t* xp_str_open (xp_str_t* str, xp_size_t capa)
{
if (str == XP_NULL) {
str = (xp_str_t*)xp_malloc (sizeof(xp_str_t));
if (str == XP_NULL) return XP_NULL;
str->__dynamic = xp_true;
}
else str->__dynamic = xp_false;
str->buf = (xp_char_t*)xp_malloc (
xp_sizeof(xp_char_t) * (capa + 1));
if (str->buf == XP_NULL) {
if (str->__dynamic) xp_free (str);
return XP_NULL;
}
str->size = 0;
str->capa = capa;
str->buf[0] = XP_CHAR('\0');
return str;
}
void xp_str_close (xp_str_t* str)
{
xp_free (str->buf);
if (str->__dynamic) xp_free (str);
}
xp_size_t xp_str_cat (xp_str_t* str, const xp_char_t* s)
{
/* TODO: improve it */
return xp_str_ncat (str, s, xp_strlen(s));
}
static xp_size_t __strncpy (xp_char_t* buf, const xp_char_t* str, xp_size_t len)
{
const xp_char_t* end = str + len;
while (str < end) *buf++ = *str++;
*buf = XP_CHAR('\0');
return len;
}
xp_size_t xp_str_ncat (xp_str_t* str, const xp_char_t* s, xp_size_t len)
{
xp_char_t* buf;
xp_size_t capa;
if (len > str->capa - str->size) {
capa = str->size + len;
/* double the capa if necessary for concatenation */
if (capa < str->capa * 2) capa = str->capa * 2;
buf = (xp_char_t*)xp_realloc (
str->buf, xp_sizeof(xp_char_t) * (capa + 1));
if (buf == XP_NULL) return (xp_size_t)-1;
str->capa = capa;
str->buf = buf;
}
str->size += __strncpy (&str->buf[str->size], s, len);
str->buf[str->size] = XP_CHAR('\0');
return str->size;
}
xp_size_t xp_str_ccat (xp_str_t* str, xp_char_t c)
{
return xp_str_ncat (str, &c, 1);
}
void xp_str_clear (xp_str_t* str)
{
str->size = 0;
str->buf[0] = XP_CHAR('\0');
}
#endif

93
ase/awk/sa.h Normal file
View File

@ -0,0 +1,93 @@
/*
* $Id: sa.h,v 1.1 2006-01-20 07:32:38 bacon Exp $
*/
#ifndef _XP_AWK_SA_H_
#define _XP_AWK_SA_H_
#ifdef __STAND_ALONE
#include <stdio.h>
#include <wchar.h>
#include <wctype.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define xp_malloc malloc
#define xp_realloc realloc
#define xp_free free
#define xp_assert assert
#define xp_printf wprintf
#define xp_isdigit iswdigit
#define xp_isalpha iswalpha
#define xp_isalnum iswalnum
#define xp_isspace iswspace
#define xp_strcmp wcscmp
#define xp_strlen wcslen
#ifdef _WIN32
#define xp_strdup _wcsdup
#else
#define xp_strdup wcsdup
#endif
#define xp_main main
#define XP_CHAR(c) L##c
#define XP_TEXT(c) L##c
#define XP_CHAR_EOF WEOF
#define XP_NULL NULL
#define xp_sizeof(n) (sizeof(n))
#define xp_countof(n) (sizeof(n) / sizeof(n[0]))
#define xp_true (0 == 0)
#define xp_false (0 != 0)
typedef wchar_t xp_char_t;
typedef wint_t xp_cint_t;
typedef size_t xp_size_t;
typedef int xp_bool_t;
#ifdef _WIN32
typedef long xp_ssize_t;
#else
typedef ssize_t xp_ssize_t;
#endif
#define XP_STR_LEN(x) ((x)->size)
#define XP_STR_SIZE(x) ((x)->size + 1)
#define XP_STR_CAPA(x) ((x)->capa)
#define XP_STR_BUF(x) ((x)->buf)
typedef struct xp_str_t xp_str_t;
struct xp_str_t
{
xp_char_t* buf;
xp_size_t size;
xp_size_t capa;
xp_bool_t __dynamic;
};
#ifdef __cplusplus
extern "C" {
#endif
xp_str_t* xp_str_open (xp_str_t* str, xp_size_t capa);
void xp_str_close (xp_str_t* str);
xp_size_t xp_str_cat (xp_str_t* str, const xp_char_t* s);
xp_size_t xp_str_ncat (xp_str_t* str, const xp_char_t* s, xp_size_t len);
xp_size_t xp_str_ccat (xp_str_t* str, xp_char_t c);
void xp_str_clear (xp_str_t* str);
#ifdef __cplusplus
}
#endif
#endif
#endif

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tree.c,v 1.8 2006-01-19 16:28:21 bacon Exp $ * $Id: tree.c,v 1.9 2006-01-20 07:29:54 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -34,7 +34,8 @@ static int __print_expr_node (xp_awk_node_t* node)
{ {
switch (node->type) { switch (node->type) {
case XP_AWK_NODE_ASSIGN: case XP_AWK_NODE_ASSIGN:
xp_printf (XP_TEXT("%s = "), ((xp_awk_node_assign_t*)node)->left); if (__print_expr_node (((xp_awk_node_assign_t*)node)->left) == -1) return -1;
xp_printf (XP_TEXT(" = "));
if (__print_expr_node (((xp_awk_node_assign_t*)node)->right) == -1) return -1; if (__print_expr_node (((xp_awk_node_assign_t*)node)->right) == -1) return -1;
xp_assert ((((xp_awk_node_assign_t*)node)->right)->next == XP_NULL); xp_assert ((((xp_awk_node_assign_t*)node)->right)->next == XP_NULL);
break; break;
@ -44,7 +45,9 @@ static int __print_expr_node (xp_awk_node_t* node)
if (__print_expr_node (((xp_awk_node_expr_t*)node)->left) == -1) return -1; if (__print_expr_node (((xp_awk_node_expr_t*)node)->left) == -1) return -1;
xp_assert ((((xp_awk_node_expr_t*)node)->left)->next == XP_NULL); xp_assert ((((xp_awk_node_expr_t*)node)->left)->next == XP_NULL);
xp_printf (XP_TEXT(" %c "), __binop_char[((xp_awk_node_expr_t*)node)->opcode]); xp_printf (XP_TEXT(" %c "), __binop_char[((xp_awk_node_expr_t*)node)->opcode]);
if (((xp_awk_node_expr_t*)node)->right->type == XP_AWK_NODE_ASSIGN) xp_printf (XP_TEXT("("));
if (__print_expr_node (((xp_awk_node_expr_t*)node)->right) == -1) return -1; if (__print_expr_node (((xp_awk_node_expr_t*)node)->right) == -1) return -1;
if (((xp_awk_node_expr_t*)node)->right->type == XP_AWK_NODE_ASSIGN) xp_printf (XP_TEXT(")"));
xp_assert ((((xp_awk_node_expr_t*)node)->right)->next == XP_NULL); xp_assert ((((xp_awk_node_expr_t*)node)->right)->next == XP_NULL);
xp_printf (XP_TEXT(")")); xp_printf (XP_TEXT(")"));
break; break;
@ -227,6 +230,16 @@ static void __print_statements (xp_awk_node_t* tree, int depth)
} }
break; break;
case XP_AWK_NODE_NEXT:
__print_tabs (depth);
xp_printf (XP_TEXT("next;\n"));
break;
case XP_AWK_NODE_NEXTFILE:
__print_tabs (depth);
xp_printf (XP_TEXT("nextfile;\n"));
break;
default: default:
__print_tabs (depth); __print_tabs (depth);
if (__print_expr_node(p) == 0) { if (__print_expr_node(p) == 0) {
@ -293,6 +306,8 @@ void xp_awk_clrpt (xp_awk_node_t* tree)
case XP_AWK_NODE_BREAK: case XP_AWK_NODE_BREAK:
case XP_AWK_NODE_CONTINUE: case XP_AWK_NODE_CONTINUE:
case XP_AWK_NODE_NEXT:
case XP_AWK_NODE_NEXTFILE:
xp_free (p); xp_free (p);
break; break;
@ -303,7 +318,7 @@ void xp_awk_clrpt (xp_awk_node_t* tree)
break; break;
case XP_AWK_NODE_ASSIGN: case XP_AWK_NODE_ASSIGN:
xp_free (((xp_awk_node_assign_t*)p)->left); xp_awk_clrpt (((xp_awk_node_assign_t*)p)->left);
xp_awk_clrpt (((xp_awk_node_assign_t*)p)->right); xp_awk_clrpt (((xp_awk_node_assign_t*)p)->right);
xp_free (p); xp_free (p);
break; break;

View File

@ -1,5 +1,5 @@
/* /*
* $Id: tree.h,v 1.13 2006-01-19 16:28:21 bacon Exp $ * $Id: tree.h,v 1.14 2006-01-20 07:29:54 bacon Exp $
*/ */
#ifndef _XP_AWK_TREE_H_ #ifndef _XP_AWK_TREE_H_
@ -13,6 +13,8 @@ enum
XP_AWK_NODE_CONTINUE, XP_AWK_NODE_CONTINUE,
XP_AWK_NODE_RETURN, XP_AWK_NODE_RETURN,
XP_AWK_NODE_EXIT, XP_AWK_NODE_EXIT,
XP_AWK_NODE_NEXT,
XP_AWK_NODE_NEXTFILE,
XP_AWK_NODE_ASSIGN, XP_AWK_NODE_ASSIGN,
XP_AWK_NODE_BINARY, XP_AWK_NODE_BINARY,
XP_AWK_NODE_UNARY, XP_AWK_NODE_UNARY,
@ -56,7 +58,7 @@ struct xp_awk_node_block_t
struct xp_awk_node_assign_t struct xp_awk_node_assign_t
{ {
XP_AWK_NODE_HDR; XP_AWK_NODE_HDR;
xp_char_t* left; xp_awk_node_t* left;
xp_awk_node_t* right; xp_awk_node_t* right;
}; };