diff --git a/ase/awk/awk.c b/ase/awk/awk.c index 0b39b807..fe05860b 100644 --- a/ase/awk/awk.c +++ b/ase/awk/awk.c @@ -1,5 +1,5 @@ /* - * $Id: awk.c,v 1.6 2006-01-09 12:51:46 bacon Exp $ + * $Id: awk.c,v 1.7 2006-01-09 16:03:55 bacon Exp $ */ #include @@ -37,11 +37,17 @@ xp_awk_t* xp_awk_open (xp_awk_t* awk) return awk; } -int xp_awk_close (xp_awk_t* awk) +static void __collapse_tree (xp_awk_t* awk) { /* TODO: collapse the tree */ + /* TODO */ + awk->tree = XP_NULL; +} - if (awk->tree != XP_NULL) __collapse_tree (awk->tree); +int xp_awk_close (xp_awk_t* awk) +{ + + if (awk->tree != XP_NULL) __collapse_tree (awk); if (xp_awk_detsrc(awk) == -1) return -1; xp_str_close (&awk->token.name); @@ -55,7 +61,7 @@ int xp_awk_attsrc (xp_awk_t* awk, xp_awk_io_t src, void* arg) xp_assert (awk->src_func == XP_NULL); - if (source(XP_AWK_IO_OPEN, arg, XP_NULL, 0) == -1) { + if (src(XP_AWK_IO_OPEN, arg, XP_NULL, 0) == -1) { awk->errnum = XP_AWK_ESRCOP; return -1; } diff --git a/ase/awk/awk.h b/ase/awk/awk.h index d778f1ac..132731c4 100644 --- a/ase/awk/awk.h +++ b/ase/awk/awk.h @@ -1,5 +1,5 @@ /* - * $Id: awk.h,v 1.7 2006-01-09 12:51:47 bacon Exp $ + * $Id: awk.h,v 1.8 2006-01-09 16:03:55 bacon Exp $ */ #ifndef _XP_AWK_AWK_H_ @@ -21,7 +21,9 @@ enum XP_AWK_ELXCHR, /* lexer came accross an wrong character */ XP_AWK_ELXUNG, /* lexer failed to unget a character */ - XP_AWK_ELBRACE /* left brace expected */ + XP_AWK_EENDSRC, /* unexpected end of source */ + XP_AWK_ELBRACE, /* left brace expected */ + XP_AWK_ESEMICOLON /* semicolon expected */ }; /* @@ -104,6 +106,8 @@ int xp_awk_detinp (xp_awk_t* awk); int xp_awk_attoutp (xp_awk_t* awk, xp_awk_io_t outp, void* arg); int xp_awk_detoutp (xp_awk_t* awk); +int xp_awk_parse (xp_awk_t* awk); + #ifdef __cplusplus } #endif diff --git a/ase/awk/parse.c b/ase/awk/parse.c index 253729e0..d5f7a1d2 100644 --- a/ase/awk/parse.c +++ b/ase/awk/parse.c @@ -1,5 +1,5 @@ /* - * $Id: parse.c,v 1.10 2006-01-09 12:51:47 bacon Exp $ + * $Id: parse.c,v 1.11 2006-01-09 16:03:55 bacon Exp $ */ #include @@ -31,6 +31,8 @@ enum TOKEN_LBRACKET, TOKEN_RBRACKET, + TOKEN_SEMICOLON, + TOKEN_STRING, TOKEN_REGEX, @@ -51,9 +53,9 @@ enum TOKEN_NEXTFILE }; -static int __parse (xp_awk_t* awk); - 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_if (xp_awk_t* awk); static xp_awk_node_t* __parse_while (xp_awk_t* awk); @@ -125,6 +127,44 @@ static struct __kwent __kwtab[] = #define PANIC(awk,code) do { (awk)->errnum = (code); return XP_NULL; } while (0); +void __print_tabs (int depth) +{ + int i; + for (i = 0; i < depth; i++) xp_printf (XP_TEXT("\t")); +} + +void __print_parse_tree (xp_awk_node_t* tree, int depth) +{ + xp_awk_node_t* p; + + p = tree; + while (p != XP_NULL) { + if (p->type == XP_AWK_NODE_BLOCK) { + __print_tabs (depth); + xp_printf (XP_TEXT("{\n")); + + __print_parse_tree (((xp_awk_node_block_t*)p)->body, depth + 1); + + __print_tabs (depth); + xp_printf (XP_TEXT("}\n")); + } + else if (p->type == XP_AWK_NODE_BREAK) { + __print_tabs (depth); + xp_printf (XP_TEXT("break;\n")); + } + else if (p->type == XP_AWK_NODE_CONTINUE) { + __print_tabs (depth); + xp_printf (XP_TEXT("continue;\n")); + } + p = p->sbls; + } +} + +void print_parse_tree (xp_awk_node_t* tree) +{ + __print_parse_tree (tree, 0); +} + int xp_awk_parse (xp_awk_t* awk) { xp_awk_node_t* node; @@ -133,8 +173,12 @@ int xp_awk_parse (xp_awk_t* awk) GET_TOKEN (awk); node = __parse_program(awk); - if (node == XP_NULL) return -1; + if (node == XP_NULL) { +xp_printf (XP_TEXT("error - %d\n"), awk->errnum); + return -1; + } +xp_printf (XP_TEXT("end - %d\n"), awk->errnum); awk->tree = node; return 0; } @@ -145,30 +189,32 @@ static xp_awk_node_t* __parse_program (xp_awk_t* awk) pattern { action } function name (parameter-list) { statement } */ - xp_awk_node_t* node; - /* while (1) { - if (awk->token.type == TOKEN_FUNCTION) { - if (__parse_function_declaration(awk) == -1) return -1; +xp_printf (XP_TEXT(">>>>> starting ... for testing ...\n")); + if (MATCH(awk,TOKEN_FUNCTION)) { + node = __parse_funcdcl(awk); } else { - if (__parse_pattern_action(awk) == -1) return -1; + node = __parse_patnact(awk); } + + if (node == XP_NULL) return XP_NULL; +xp_printf (XP_TEXT(">>>>> breaking ... for testing ...\n")); +break; } - */ return node; } -static xp_awk_node_t* __parse_function_declaration (xp_awk_t* awk) +static xp_awk_node_t* __parse_funcdcl (xp_awk_t* awk) { return XP_NULL; } -static xp_awk_node_t* __parse_pattern_action (xp_awk_t* awk) +static xp_awk_node_t* __parse_patnact (xp_awk_t* awk) { /* BEGIN @@ -208,19 +254,30 @@ static xp_awk_node_t* __parse_pattern_action (xp_awk_t* 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) { - xp_awk_node_block_t* node; + xp_awk_node_block_t* blk; + xp_awk_node_t* x, * y; + int saved_token; - node = (xp_awk_node_block_t*) xp_malloc (xp_sizeof(xp_awk_node_block_t)); - if (node == XP_NULL) { +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 */ PANIC (awk, XP_AWK_ENOMEM); } - node->type = XP_AWK_NODE_BLOCK; - node->sbls = XP_NULL; - node->body = XP_NULL; + blk->type = XP_AWK_NODE_BLOCK; + blk->sbls = XP_NULL; + blk->body = XP_NULL; + + x = XP_NULL; while (1) { + saved_token = awk->token.type; + + if (MATCH(awk,TOKEN_EOF)) { + PANIC (awk, XP_AWK_EENDSRC); + } + if (MATCH(awk,TOKEN_RBRACE)) { /* TODO: should finalize a block */ CONSUME (awk); @@ -230,55 +287,70 @@ static xp_awk_node_t* __parse_block (xp_awk_t* awk) if (MATCH(awk,TOKEN_LBRACE)) { /* nested block */ CONSUME (awk); - if (__parse_block(awk) == XP_NULL) return XP_NULL; + y = __parse_block(awk); } else if (MATCH(awk,TOKEN_IF)) { CONSUME (awk); - if (__parse_if(awk) == XP_NULL) return XP_NULL; + y = __parse_if(awk); } else if (MATCH(awk,TOKEN_WHILE)) { CONSUME (awk); - if (__parse_while(awk) == XP_NULL) return XP_NULL; + y = __parse_while(awk); } else if (MATCH(awk,TOKEN_FOR)) { CONSUME (awk); - if (__parse_for(awk) == XP_NULL) return XP_NULL; + y = __parse_for(awk); } else if (MATCH(awk,TOKEN_DO)) { CONSUME (awk); - if (__parse_do(awk) == XP_NULL) return XP_NULL; + y = __parse_do(awk); } else if (MATCH(awk,TOKEN_BREAK)) { CONSUME (awk); - node->body = __parse_break(awk); + y = __parse_break(awk); } else if (MATCH(awk,TOKEN_CONTINUE)) { CONSUME (awk); - node->body = __parse_continue(awk); + y = __parse_continue(awk); } else if (MATCH(awk,TOKEN_RETURN)) { CONSUME (awk); /* TOOD: */ } - else if (MATCH(awk, TOKEN_EXIT)) { + else if (MATCH(awk,TOKEN_EXIT)) { CONSUME (awk); /* TOOD: */ } - else if (MATCH(awk, TOKEN_DELETE)) { + else if (MATCH(awk,TOKEN_DELETE)) { CONSUME (awk); /* TOOD: */ } - else if (MATCH(awk, TOKEN_NEXT)) { + else if (MATCH(awk,TOKEN_NEXT)) { CONSUME (awk); /* TOOD: */ } - else if (MATCH(awk, TOKEN_NEXTFILE)) { + else if (MATCH(awk,TOKEN_NEXTFILE)) { CONSUME (awk); /* TOOD: */ } + + if (y == XP_NULL) return XP_NULL; + if (blk->body == XP_NULL) { + blk->body = y; + x = y; + } + else { + x->sbls = y; + x = y; + } + + if (saved_token != TOKEN_LBRACE) { + if (!MATCH(awk,TOKEN_SEMICOLON)) PANIC (awk, XP_AWK_ESEMICOLON); + CONSUME (awk); + } } - return 0; + return (xp_awk_node_t*)blk; } static xp_awk_node_t* __parse_if (xp_awk_t* awk) @@ -308,6 +380,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; /* TODO: do i have to consume a semicolon here???? */ return node; @@ -320,6 +393,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; /* TODO: do i have to consume a semicolon here???? */ return node; @@ -426,26 +500,37 @@ static int __get_token (xp_awk_t* awk) else if (c == XP_CHAR('(')) { SET_TOKEN_TYPE (awk, TOKEN_LPAREN); ADD_TOKEN_CHAR (awk, c); + GET_CHAR_TO (awk, c); } else if (c == XP_CHAR(')')) { SET_TOKEN_TYPE (awk, TOKEN_RPAREN); ADD_TOKEN_CHAR (awk, c); + GET_CHAR_TO (awk, c); } else if (c == XP_CHAR('{')) { SET_TOKEN_TYPE (awk, TOKEN_LBRACE); ADD_TOKEN_CHAR (awk, c); + GET_CHAR_TO (awk, c); } else if (c == XP_CHAR('}')) { SET_TOKEN_TYPE (awk, TOKEN_RBRACE); ADD_TOKEN_CHAR (awk, c); + GET_CHAR_TO (awk, c); } else if (c == XP_CHAR('[')) { SET_TOKEN_TYPE (awk, TOKEN_LBRACKET); ADD_TOKEN_CHAR (awk, c); + GET_CHAR_TO (awk, c); } else if (c == XP_CHAR(']')) { SET_TOKEN_TYPE (awk, TOKEN_RBRACKET); ADD_TOKEN_CHAR (awk, c); + GET_CHAR_TO (awk, c); + } + else if (c == XP_CHAR(';')) { + SET_TOKEN_TYPE (awk, TOKEN_SEMICOLON); + ADD_TOKEN_CHAR (awk, c); + GET_CHAR_TO (awk, c); } else { awk->errnum = XP_AWK_ELXCHR; @@ -457,17 +542,20 @@ static int __get_token (xp_awk_t* awk) static int __get_char (xp_awk_t* awk) { + xp_ssize_t n; + if (awk->lex.ungotc_count > 0) { awk->lex.curc = awk->lex.ungotc[--awk->lex.ungotc_count]; return 0; } - if (awk->src_func(XP_AWK_IO_DATA, - awk->src_arg, &awk->lex.curc, 1) == -1) { + n = awk->src_func(XP_AWK_IO_DATA, awk->src_arg, &awk->lex.curc, 1); + if (n == -1) { awk->errnum = XP_AWK_ESRCDT; return -1; } - + if (n == 0) awk->lex.curc = XP_CHAR_EOF; + return 0; } @@ -527,6 +615,7 @@ static int __classfy_ident (const xp_char_t* ident) while (p->name != XP_NULL) { if (xp_strcmp(p->name, ident) == 0) return p->type; + p++; } return TOKEN_IDENT; diff --git a/ase/test/awk/awk.c b/ase/test/awk/awk.c index 27f673dd..4d989053 100644 --- a/ase/test/awk/awk.c +++ b/ase/test/awk/awk.c @@ -38,7 +38,7 @@ int xp_main (int argc, xp_char_t* argv[]) return -1; } - if (xp_awk_attach_source(&awk, process_source, XP_NULL) == -1) { + if (xp_awk_attsrc(&awk, process_source, XP_NULL) == -1) { xp_awk_close (&awk); xp_fprintf (xp_stderr, XP_TEXT("error: cannot attach source\n")); return -1; @@ -50,6 +50,9 @@ int xp_main (int argc, xp_char_t* argv[]) return -1; } +xp_printf (XP_TEXT("-----------------------------------------------\n")); +print_parse_tree (awk.tree); + xp_awk_close (&awk); return 0; }