*** empty log message ***

This commit is contained in:
hyung-hwan 2006-01-10 13:57:54 +00:00
parent f444159f50
commit 9f8e0c20bc
3 changed files with 248 additions and 112 deletions

View File

@ -1,5 +1,5 @@
/* /*
* $Id: awk.h,v 1.8 2006-01-09 16:03:55 bacon Exp $ * $Id: awk.h,v 1.9 2006-01-10 13:57:54 bacon Exp $
*/ */
#ifndef _XP_AWK_AWK_H_ #ifndef _XP_AWK_AWK_H_
@ -23,7 +23,8 @@ enum
XP_AWK_EENDSRC, /* unexpected end of source */ XP_AWK_EENDSRC, /* unexpected end of source */
XP_AWK_ELBRACE, /* left brace expected */ XP_AWK_ELBRACE, /* left brace expected */
XP_AWK_ESEMICOLON /* semicolon expected */ XP_AWK_ESEMICOLON, /* semicolon expected */
XP_AWK_EEXPR /* expression expected */
}; };
/* /*

View File

@ -1,5 +1,5 @@
/* /*
* $Id: parse.c,v 1.11 2006-01-09 16:03:55 bacon Exp $ * $Id: parse.c,v 1.12 2006-01-10 13:57:54 bacon Exp $
*/ */
#include <xp/awk/awk.h> #include <xp/awk/awk.h>
@ -23,6 +23,9 @@ enum
TOKEN_MINUS, TOKEN_MINUS,
TOKEN_MINUS_MINUS, TOKEN_MINUS_MINUS,
TOKEN_MINUS_ASSIGN, TOKEN_MINUS_ASSIGN,
TOKEN_MUL,
TOKEN_DIV,
TOKEN_MOD,
TOKEN_LPAREN, TOKEN_LPAREN,
TOKEN_RPAREN, TOKEN_RPAREN,
@ -57,6 +60,12 @@ 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_funcdcl (xp_awk_t* awk);
static xp_awk_node_t* __parse_patnact (xp_awk_t* awk); static xp_awk_node_t* __parse_patnact (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_stat (xp_awk_t* awk);
static xp_awk_node_t* __parse_expr (xp_awk_t* awk);
static xp_awk_node_t* __parse_additive (xp_awk_t* awk)
static xp_awk_node_t* __parse_multiplicative (xp_awk_t* awk)
static xp_awk_node_t* __parse_unary (xp_awk_t* awk)
static xp_awk_node_t* __parse_primary (xp_awk_t* awk)
static xp_awk_node_t* __parse_if (xp_awk_t* awk); static xp_awk_node_t* __parse_if (xp_awk_t* awk);
static xp_awk_node_t* __parse_while (xp_awk_t* awk); static xp_awk_node_t* __parse_while (xp_awk_t* awk);
static xp_awk_node_t* __parse_for (xp_awk_t* awk); static xp_awk_node_t* __parse_for (xp_awk_t* awk);
@ -156,7 +165,7 @@ void __print_parse_tree (xp_awk_node_t* tree, int depth)
__print_tabs (depth); __print_tabs (depth);
xp_printf (XP_TEXT("continue;\n")); xp_printf (XP_TEXT("continue;\n"));
} }
p = p->sbls; p = p->next;
} }
} }
@ -255,97 +264,59 @@ static xp_awk_node_t* __parse_patnact (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)
{ {
xp_awk_node_block_t* blk; xp_awk_node_block_t* blk;
xp_awk_node_t* x, * y; xp_awk_node_t* node, * prev;
int saved_token; int saved_token;
xp_printf (XP_TEXT("__parse_block....\n")); xp_printf (XP_TEXT("__parse_block....\n"));
blk = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t)); blk = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t));
if (blk == XP_NULL) { if (blk == XP_NULL) {
/* TODO: do some clean-up */ /* TODO: do some clean-up */
PANIC (awk, XP_AWK_ENOMEM); PANIC (awk, XP_AWK_ENOMEM);
} }
blk->type = XP_AWK_NODE_BLOCK; blk->type = XP_AWK_NODE_BLOCK;
blk->sbls = XP_NULL; blk->next = XP_NULL;
blk->body = XP_NULL; blk->body = prev = XP_NULL;
x = XP_NULL;
while (1) { while (1) {
saved_token = awk->token.type; saved_token = awk->token.type;
if (MATCH(awk,TOKEN_EOF)) { if (MATCH(awk,TOKEN_EOF)) {
/* TODO: do come clean-up */
PANIC (awk, XP_AWK_EENDSRC); PANIC (awk, XP_AWK_EENDSRC);
} }
if (MATCH(awk,TOKEN_RBRACE)) { if (MATCH(awk,TOKEN_RBRACE)) {
/* TODO: should finalize a block */ /* TODO: should finalize a block */
CONSUME (awk); CONSUME (awk);
break; break;
} }
if (MATCH(awk, TOKEN_SEMICOLON)) {
/* null statement */
CONSUME (awk);
continue;
}
if (MATCH(awk,TOKEN_LBRACE)) { if (MATCH(awk,TOKEN_LBRACE)) {
/* nested block */ /* nested block */
CONSUME (awk); CONSUME (awk);
y = __parse_block(awk); node = __parse_block(awk);
}
else if (MATCH(awk,TOKEN_IF)) {
CONSUME (awk);
y = __parse_if(awk);
}
else if (MATCH(awk,TOKEN_WHILE)) {
CONSUME (awk);
y = __parse_while(awk);
}
else if (MATCH(awk,TOKEN_FOR)) {
CONSUME (awk);
y = __parse_for(awk);
}
else if (MATCH(awk,TOKEN_DO)) {
CONSUME (awk);
y = __parse_do(awk);
}
else if (MATCH(awk,TOKEN_BREAK)) {
CONSUME (awk);
y = __parse_break(awk);
}
else if (MATCH(awk,TOKEN_CONTINUE)) {
CONSUME (awk);
y = __parse_continue(awk);
}
else if (MATCH(awk,TOKEN_RETURN)) {
CONSUME (awk);
/* TOOD: */
}
else if (MATCH(awk,TOKEN_EXIT)) {
CONSUME (awk);
/* TOOD: */
}
else if (MATCH(awk,TOKEN_DELETE)) {
CONSUME (awk);
/* TOOD: */
}
else if (MATCH(awk,TOKEN_NEXT)) {
CONSUME (awk);
/* TOOD: */
}
else if (MATCH(awk,TOKEN_NEXTFILE)) {
CONSUME (awk);
/* TOOD: */
} }
else node = __parse_stat (awk);
if (y == XP_NULL) return XP_NULL; if (node == XP_NULL) return XP_NULL;
if (blk->body == XP_NULL) {
blk->body = y; if (prev == XP_NULL) blk->body = node;
x = y; else prev->next = node;
} prev = node;
else {
x->sbls = y;
x = y;
}
if (saved_token != TOKEN_LBRACE) { if (saved_token != TOKEN_LBRACE) {
if (!MATCH(awk,TOKEN_SEMICOLON)) PANIC (awk, XP_AWK_ESEMICOLON); if (!MATCH(awk,TOKEN_SEMICOLON)) {
/* TODO: do some clean-up */
PANIC (awk, XP_AWK_ESEMICOLON);
}
CONSUME (awk); CONSUME (awk);
} }
} }
@ -353,6 +324,164 @@ xp_printf (XP_TEXT("__parse_block....\n"));
return (xp_awk_node_t*)blk; return (xp_awk_node_t*)blk;
} }
static xp_awk_node_t* __parse_stat (xp_awk_t* awk)
{
xp_awk_node_t* node;
if (MATCH(awk,TOKEN_IF)) {
CONSUME (awk);
node = __parse_if(awk);
}
else if (MATCH(awk,TOKEN_WHILE)) {
CONSUME (awk);
node = __parse_while(awk);
}
else if (MATCH(awk,TOKEN_FOR)) {
CONSUME (awk);
node = __parse_for(awk);
}
else if (MATCH(awk,TOKEN_DO)) {
CONSUME (awk);
node = __parse_do(awk);
}
else if (MATCH(awk,TOKEN_BREAK)) {
CONSUME (awk);
node = __parse_break(awk);
}
else if (MATCH(awk,TOKEN_CONTINUE)) {
CONSUME (awk);
node = __parse_continue(awk);
}
else if (MATCH(awk,TOKEN_RETURN)) {
CONSUME (awk);
/* TOOD: */
node = XP_NULL;
}
else if (MATCH(awk,TOKEN_EXIT)) {
CONSUME (awk);
/* TOOD: */
node = XP_NULL;
}
else if (MATCH(awk,TOKEN_DELETE)) {
CONSUME (awk);
/* TOOD: */
node = XP_NULL;
}
else if (MATCH(awk,TOKEN_NEXT)) {
CONSUME (awk);
/* TOOD: */
node = XP_NULL;
}
else if (MATCH(awk,TOKEN_NEXTFILE)) {
CONSUME (awk);
/* TOOD: */
node = XP_NULL;
}
else {
node = __parse_expr(awk);
}
return node;
}
static xp_awk_node_t* __parse_expr (xp_awk_t* awk)
{
return parse_additive (xp_awk_t* awk);
}
static xp_awk_node_t* __parse_additive (xp_awk_t* awk)
{
xp_node_t* top, * left, * right;
left = __parse_multiplicative (awk);
if (left == XP_NULL) return XP_NULL;
while (MATCH(awk,TOKEN_MUL) ||
MATCH(awk,TOKEN_DIV) ||
MATCH(awk,TOKEN_MOD)) {
CONSUME (awk);
right = __parse_multiplicative (awk);
if (right == XP_NULL) {
// TODO: memory clean-up
return XP_NULL;
}
}
return top;
}
static xp_awk_node_t* __parse_multiplicative (xp_awk_t* awk)
{
xp_node_t* top, * left, * right;
left = __parse_unary (awk);
if (left == XP_NULL) return XP_NULL;
while (MATCH(awk,TOKEN_MUL) ||
MATCH(awk,TOKEN_DIV) ||
MATCH(awk,TOKEN_MOD)) {
CONSUME (awk);
right = __parse_unary (awk);
if (right == XP_NULL) {
// TODO: memory clean-up
return XP_NULL;
}
}
return top;
}
static xp_awk_node_t* __parse_unary (xp_awk_t* awk)
{
return __parse_primary (awk);
}
static xp_awk_node_t* __parse_primary (xp_awk_t* awk)
{
if (MATCH(awk,TOKEN_IDENT)) {
xp_awk_node_term_t* node;
node = (xp_awk_node_term_t*)xp_malloc(xp_sizeof(xp_awk_node_term_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_IDT;
node->next = XP_NULL;
node->value = token_value....
CONSUME (awk);
}
else if (MATCH(awk,TOKEN_STRING)) {
xp_awk_node_term_t* node;
node = (xp_awk_node_term_t*)xp_malloc(xp_sizeof(xp_awk_node_term_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_STR;
node->next = XP_NULL;
node->value = token_value;
CONSUME (awk);
}
else if (MATCH(awk,TOKEN_LPAREN)) {
xp_awk_node_t* tmp;
xp_awk_node_term_t* node;
CONSUME (awk);
tmp = __parse_expr (awk);
if (tmp == XP_NULL) return XP_NULL;
node = (xp_awk_node_term_t*)xp_malloc(xp_sizeof(xp_awk_node_term_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_EXPR;
node->next = XP_NULL;
node->value = tmp;
}
/* valid expression introducer is expected */
PANIC (awk, XP_AWK_EEXPR);
}
static xp_awk_node_t* __parse_if (xp_awk_t* awk) static xp_awk_node_t* __parse_if (xp_awk_t* awk)
{ {
return XP_NULL; return XP_NULL;
@ -380,7 +509,7 @@ static xp_awk_node_t* __parse_break (xp_awk_t* awk)
node = (xp_awk_node_t*) xp_malloc (xp_sizeof(xp_awk_node_t)); node = (xp_awk_node_t*) xp_malloc (xp_sizeof(xp_awk_node_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_BREAK; node->type = XP_AWK_NODE_BREAK;
node->sbls = XP_NULL; node->next = XP_NULL;
/* TODO: do i have to consume a semicolon here???? */ /* TODO: do i have to consume a semicolon here???? */
return node; return node;
@ -393,7 +522,7 @@ static xp_awk_node_t* __parse_continue (xp_awk_t* awk)
node = (xp_awk_node_t*) xp_malloc (xp_sizeof(xp_awk_node_t)); node = (xp_awk_node_t*) xp_malloc (xp_sizeof(xp_awk_node_t));
if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM);
node->type = XP_AWK_NODE_CONTINUE; node->type = XP_AWK_NODE_CONTINUE;
node->sbls = XP_NULL; node->next = XP_NULL;
/* TODO: do i have to consume a semicolon here???? */ /* TODO: do i have to consume a semicolon here???? */
return node; return node;
@ -497,6 +626,21 @@ static int __get_token (xp_awk_t* awk)
ADD_TOKEN_STR (awk, XP_TEXT("-")); ADD_TOKEN_STR (awk, XP_TEXT("-"));
} }
} }
else if (c == XP_CHAR('*')) {
SET_TOKEN_TYPE (awk, TOKEN_MUL);
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_CHAR('/')) {
SET_TOKEN_TYPE (awk, TOKEN_DIV);
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_CHAR('%')) {
SET_TOKEN_TYPE (awk, TOKEN_MOD);
ADD_TOKEN_CHAR (awk, c);
GET_CHAR_TO (awk, c);
}
else if (c == XP_CHAR('(')) { else if (c == XP_CHAR('(')) {
SET_TOKEN_TYPE (awk, TOKEN_LPAREN); SET_TOKEN_TYPE (awk, TOKEN_LPAREN);
ADD_TOKEN_CHAR (awk, c); ADD_TOKEN_CHAR (awk, c);

View File

@ -1,50 +1,10 @@
/* /*
* $Id: tree.h,v 1.2 2006-01-09 12:51:47 bacon Exp $ * $Id: tree.h,v 1.3 2006-01-10 13:57:54 bacon Exp $
*/ */
#ifndef _XP_AWK_TREE_H_ #ifndef _XP_AWK_TREE_H_
#define _XP_AWK_TREE_H_ #define _XP_AWK_TREE_H_
/*
enum TokenType
{
IF, END, ID, NUM, READ, WRITE, UNTIL, ....
}
enum NodeKind { statement, expression };
enum StatKind { if, repeat, assign, read, write };
enum ExpKind { op, const, id };
enum ExpType { void, integer, boolean };
struct treenode
{
treenode* child[3]; //
treenode* sibling; // <---- next statement...
int lineno;
NodeKind node_kind;
union {
statkind s;
expkind e;
} kind;
union {
TokenType Op;
int val;
char* name;
} attr;
exptype type; <- for type checking...
};
struct node_t
{
int type;
};
*/
enum enum
{ {
XP_AWK_NODE_BLOCK, XP_AWK_NODE_BLOCK,
@ -54,11 +14,15 @@ enum
typedef struct xp_awk_node_t xp_awk_node_t; typedef struct xp_awk_node_t xp_awk_node_t;
typedef struct xp_awk_node_block_t xp_awk_node_block_t; typedef struct xp_awk_node_block_t xp_awk_node_block_t;
typedef struct xp_awk_node_expr_t xp_awk_node_expr_t;
typedef struct xp_awk_node_term_t xp_awk_node_term_t;
typedef struct xp_awk_node_if_t xp_awk_node_if_t; 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_do_t xp_awk_node_do_t;
#define XP_AWK_NODE_HDR \ #define XP_AWK_NODE_HDR \
int type; \ int type; \
xp_awk_node_t* sbls xp_awk_node_t* next
struct xp_awk_node_t struct xp_awk_node_t
{ {
@ -78,12 +42,39 @@ struct xp_awk_node_block_t
xp_awk_node_t* body; xp_awk_node_t* body;
}; };
struct xp_awk_node_expr_t
{
XP_AWK_NODE_HDR;
xp_awk_node_t* left;
xp_awk_node_t* right;
};
struct xp_awk_node_term_t
{
XP_AWK_NODE_HDR;
xp_awk_node_t* value;
};
struct xp_awk_node_if_t struct xp_awk_node_if_t
{ {
XP_AWK_NODE_HDR; XP_AWK_NODE_HDR;
xp_awk_node_t* cond; xp_awk_node_t* test;
xp_awk_node_t* if_part; xp_awk_node_t* then_part;
xp_awk_node_t* else_part; xp_awk_node_t* else_part;
}; };
struct xp_awk_node_while_t
{
XP_AWK_NODE_HDR;
xp_awk_node_t* test;
xp_awk_node_t* body;
};
struct xp_awk_node_do_t
{
XP_AWK_NODE_HDR;
xp_awk_node_t* body;
xp_awk_node_t* test;
};
#endif #endif