diff --git a/ase/awk/awk.h b/ase/awk/awk.h index 132731c4..4cb3720c 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -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_ @@ -23,7 +23,8 @@ enum XP_AWK_EENDSRC, /* unexpected end of source */ XP_AWK_ELBRACE, /* left brace expected */ - XP_AWK_ESEMICOLON /* semicolon expected */ + XP_AWK_ESEMICOLON, /* semicolon expected */ + XP_AWK_EEXPR /* expression expected */ }; /* diff --git a/ase/awk/parse.c b/ase/awk/parse.c index d5f7a1d2..46711148 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -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 @@ -23,6 +23,9 @@ enum TOKEN_MINUS, TOKEN_MINUS_MINUS, TOKEN_MINUS_ASSIGN, + TOKEN_MUL, + TOKEN_DIV, + TOKEN_MOD, TOKEN_LPAREN, 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_patnact (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_while (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); 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) { xp_awk_node_block_t* blk; - xp_awk_node_t* x, * y; + xp_awk_node_t* node, * prev; int saved_token; xp_printf (XP_TEXT("__parse_block....\n")); blk = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t)); if (blk == XP_NULL) { - /* TODO: do some clean-up */ +/* TODO: do some clean-up */ PANIC (awk, XP_AWK_ENOMEM); } blk->type = XP_AWK_NODE_BLOCK; - blk->sbls = XP_NULL; - blk->body = XP_NULL; - - x = XP_NULL; + blk->next = XP_NULL; + blk->body = prev = XP_NULL; while (1) { saved_token = awk->token.type; if (MATCH(awk,TOKEN_EOF)) { +/* TODO: do come clean-up */ PANIC (awk, XP_AWK_EENDSRC); } if (MATCH(awk,TOKEN_RBRACE)) { - /* TODO: should finalize a block */ +/* TODO: should finalize a block */ CONSUME (awk); break; } + + if (MATCH(awk, TOKEN_SEMICOLON)) { + /* null statement */ + CONSUME (awk); + continue; + } + if (MATCH(awk,TOKEN_LBRACE)) { /* nested block */ CONSUME (awk); - y = __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: */ + node = __parse_block(awk); } + else node = __parse_stat (awk); - if (y == XP_NULL) return XP_NULL; - if (blk->body == XP_NULL) { - blk->body = y; - x = y; - } - else { - x->sbls = y; - x = y; - } + if (node == XP_NULL) return XP_NULL; + + if (prev == XP_NULL) blk->body = node; + else prev->next = node; + prev = node; 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); } } @@ -353,6 +324,164 @@ xp_printf (XP_TEXT("__parse_block....\n")); 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) { 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)); if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); node->type = XP_AWK_NODE_BREAK; - node->sbls = XP_NULL; + node->next = XP_NULL; /* TODO: do i have to consume a semicolon here???? */ 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)); if (node == XP_NULL) PANIC (awk, XP_AWK_ENOMEM); node->type = XP_AWK_NODE_CONTINUE; - node->sbls = XP_NULL; + node->next = XP_NULL; /* TODO: do i have to consume a semicolon here???? */ return node; @@ -497,6 +626,21 @@ static int __get_token (xp_awk_t* awk) 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('(')) { SET_TOKEN_TYPE (awk, TOKEN_LPAREN); ADD_TOKEN_CHAR (awk, c); diff --git a/ase/awk/tree.h b/ase/awk/tree.h index a33f93ea..538a8900 100644 --- a/ase/awk/tree.h +++ b/ase/awk/tree.h @@ -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_ #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 { XP_AWK_NODE_BLOCK, @@ -54,11 +14,15 @@ enum 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_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_while_t xp_awk_node_while_t; +typedef struct xp_awk_node_do_t xp_awk_node_do_t; #define XP_AWK_NODE_HDR \ int type; \ - xp_awk_node_t* sbls + xp_awk_node_t* next struct xp_awk_node_t { @@ -78,12 +42,39 @@ struct xp_awk_node_block_t 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 { XP_AWK_NODE_HDR; - xp_awk_node_t* cond; - xp_awk_node_t* if_part; + xp_awk_node_t* test; + xp_awk_node_t* then_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