diff --git a/ase/stx/parser.c b/ase/stx/parser.c index 55e59f6c..9ea233f4 100644 --- a/ase/stx/parser.c +++ b/ase/stx/parser.c @@ -1,11 +1,15 @@ /* - * $Id: parser.c,v 1.13 2005-06-05 16:44:05 bacon Exp $ + * $Id: parser.c,v 1.14 2005-06-06 03:47:34 bacon Exp $ */ #include #include #include +static int __parse_method ( + xp_stx_parser_t* parser, + xp_stx_word_t method_class, void* input); + static int __get_token (xp_stx_parser_t* parser); static int __get_ident (xp_stx_parser_t* parser); static int __get_charlit (xp_stx_parser_t* parser); @@ -14,7 +18,8 @@ static int __skip_spaces (xp_stx_parser_t* parser); static int __skip_comment (xp_stx_parser_t* parser); static int __get_char (xp_stx_parser_t* parser); static int __unget_char (xp_stx_parser_t* parser, xp_cint_t c); -static int __reset_input (xp_stx_parser_t* parser, void* input); +static int __open_input (xp_stx_parser_t* parser, void* input); +static int __close_input (xp_stx_parser_t* parser); xp_stx_parser_t* xp_stx_parser_open (xp_stx_parser_t* parser) { @@ -35,9 +40,8 @@ xp_stx_parser_t* xp_stx_parser_open (xp_stx_parser_t* parser) parser->curc = XP_STX_CHAR_EOF; parser->ungotc_count = 0; - parser->input = XP_NULL; - parser->input_reset = XP_NULL; - parser->input_consume = XP_NULL; + parser->input_owner = XP_NULL; + parser->input_func = XP_NULL; return parser; } @@ -47,8 +51,6 @@ void xp_stx_parser_close (xp_stx_parser_t* parser) if (parser->__malloced) xp_stx_free (parser); } -#define RESET_INPUT(parser,in) \ - do { if (__reset_input(parser,in) == -1) return -1; } while (0) #define GET_CHAR(parser) \ do { if (__get_char(parser) == -1) return -1; } while (0) #define UNGET_CHAR(parser,c) \ @@ -60,15 +62,24 @@ void xp_stx_parser_close (xp_stx_parser_t* parser) int xp_stx_parser_parse_method ( xp_stx_parser_t* parser, xp_stx_word_t method_class, void* input) { - if (parser->input_reset == XP_NULL || - parser->input_consume == XP_NULL) { + int n; + + if (parser->input_func == XP_NULL) { parser->error_code = XP_STX_PARSER_ERROR_INVALID; return -1; } - RESET_INPUT (parser, input); + if (__open_input(parser,input) == -1) return -1; + n = __parse_method (parser, method_class, input); + if (__close_input(parser) == -1) return -1; + + return n; +} + +static int __parse_method ( + xp_stx_parser_t* parser, xp_stx_word_t method_class, void* input) +{ GET_CHAR (parser); - GET_TOKEN (parser); xp_printf (XP_TEXT("%d, [%s]\n"), parser->token.type, parser->token.buffer); @@ -216,7 +227,9 @@ static int __get_char (xp_stx_parser_t* parser) parser->curc = parser->ungotc[parser->ungotc_count--]; } else { - if (parser->input_consume (parser, &c) == -1) { + if (parser->input_func ( + XP_STX_PARSER_INPUT_CONSUME, + parser->input_owner, (void*)&c) == -1) { parser->error_code = XP_STX_PARSER_ERROR_INPUT; return -1; } @@ -232,10 +245,14 @@ static int __unget_char (xp_stx_parser_t* parser, xp_cint_t c) return 0; } -static int __reset_input (xp_stx_parser_t* parser, void* input) +static int __open_input (xp_stx_parser_t* parser, void* input) { - parser->input = input; - if (parser->input_reset(parser) == -1) return -1; + if (parser->input_func( + XP_STX_PARSER_INPUT_OPEN, + (void*)&parser->input_owner, input) == -1) { + parser->error_code = XP_STX_PARSER_ERROR_INPUT; + return -1; + } parser->error_code = XP_STX_PARSER_ERROR_NONE; parser->curc = XP_STX_CHAR_EOF; @@ -243,3 +260,14 @@ static int __reset_input (xp_stx_parser_t* parser, void* input) return 0; } +static int __close_input (xp_stx_parser_t* parser) +{ + if (parser->input_func( + XP_STX_PARSER_INPUT_CLOSE, + parser->input_owner, XP_NULL) == -1) { + parser->error_code = XP_STX_PARSER_ERROR_INPUT; + return -1; + } + + return 0; +} diff --git a/ase/stx/parser.h b/ase/stx/parser.h index babeb57b..50142d3e 100644 --- a/ase/stx/parser.h +++ b/ase/stx/parser.h @@ -1,5 +1,5 @@ /* - * $Id: parser.h,v 1.10 2005-06-05 16:44:05 bacon Exp $ + * $Id: parser.h,v 1.11 2005-06-06 03:47:34 bacon Exp $ */ #ifndef _XP_STX_PARSER_H_ @@ -19,6 +19,15 @@ enum XP_STX_PARSER_ERROR_STRLIT }; +/* input_func cmd */ +enum +{ + XP_STX_PARSER_INPUT_OPEN, + XP_STX_PARSER_INPUT_CLOSE, + XP_STX_PARSER_INPUT_CONSUME, + XP_STX_PARSER_INPUT_REWIND +}; + typedef struct xp_stx_parser_t xp_stx_parser_t; struct xp_stx_parser_t @@ -30,9 +39,8 @@ struct xp_stx_parser_t xp_stx_cint_t ungotc[5]; xp_size_t ungotc_count; - void* input; - int (*input_reset) (xp_stx_parser_t*); - int (*input_consume) (xp_stx_parser_t*, xp_stx_cint_t*); + void* input_owner; + int (*input_func) (int cmd, void* owner, void* arg); xp_bool_t __malloced; }; diff --git a/ase/test/stx/parser.c b/ase/test/stx/parser.c index f5f5064a..2000a34c 100644 --- a/ase/test/stx/parser.c +++ b/ase/test/stx/parser.c @@ -13,27 +13,77 @@ struct ss_t { const xp_stx_char_t* text; - xp_size_t size; xp_size_t index; }; typedef struct ss_t ss_t; -int ss_input (void* owner, int cmd, void* arg) +int ss_func (int cmd, void* owner, void* arg) { - ss_t* ss = (ss_t*)owner; if (cmd == XP_STX_PARSER_INPUT_OPEN) { + ss_t* ss = *(ss_t**)owner; + ss->text = (const xp_stx_char_t*)arg; + ss->index = 0; return 0; } else if (cmd == XP_STX_PARSER_INPUT_CLOSE) { + //ss_t* ss = (ss_t*)owner; return 0; } else if (cmd == XP_STX_PARSER_INPUT_CONSUME) { - if (ss->index < ss->size) *c = ss->text[ss->index++]; - else *c = XP_STX_CHAR_EOF; + ss_t* ss = (ss_t*)owner; + xp_cint_t* c = (xp_cint_t*)arg; + if (ss->text[ss->index] == XP_STX_CHAR('\0')) { + *c = XP_STX_CHAR_EOF; + } + else *c = ss->text[ss->index++]; + return 0; } - return 0; + else if (cmd == XP_STX_PARSER_INPUT_REWIND) { + return 0; + } + return -1; +} + +struct stdio_t +{ + XP_FILE* stdio; +}; + +typedef struct stdio_t stdio_t; + + +int stdio_func (int cmd, void* owner, void* arg) +{ + + if (cmd == XP_STX_PARSER_INPUT_OPEN) { + stdio_t* p = *(stdio_t**)owner; + p->stdio = xp_fopen ((const xp_char_t*)arg, XP_TEXT("r")); + if (p->stdio == XP_NULL) return -1; + return 0; + } + else if (cmd == XP_STX_PARSER_INPUT_CLOSE) { + stdio_t* p = (stdio_t*)owner; + xp_fclose (p->stdio); + return 0; + } + else if (cmd == XP_STX_PARSER_INPUT_CONSUME) { + stdio_t* p = (stdio_t*)owner; + xp_cint_t* c = (xp_cint_t*)arg; + xp_cint_t t = xp_fgetc (p->stdio); + if (t == EOF) { + if (xp_ferror (p->stdio)) return -1; + *c = XP_STX_CHAR_EOF; + } + else *c = t; +xp_printf (XP_TEXT("[%c]\n"), *c); + return 0; + } + else if (cmd == XP_STX_PARSER_INPUT_REWIND) { + return 0; + } + return -1; } int xp_main (int argc, xp_char_t* argv[]) @@ -53,17 +103,21 @@ int xp_main (int argc, xp_char_t* argv[]) return -1; } - parser.input_func = ss_func; - { - /* - ss_t ss = { - XP_STX_TEXT("isNil\n^true"), - 11, - 0 - }; - */ - xp_stx_parser_parse_method (&parser, 0, &ss); + /* + ss_t ss; + parser.input_owner = (void*)&ss; + parser.input_func = ss_func; + xp_stx_parser_parse_method (&parser, 0, + XP_TEXT("isNil\n^true")); + */ + stdio_t stdio; + parser.input_owner = (void*)&stdio; + parser.input_func = stdio_func; + if (xp_stx_parser_parse_method (&parser, 0, + (void*)XP_TEXT("test.st")) == -1) { + xp_printf (XP_TEXT("parser error\n")); + } } xp_stx_parser_close (&parser); diff --git a/ase/test/stx/test.st b/ase/test/stx/test.st new file mode 100644 index 00000000..788b148f --- /dev/null +++ b/ase/test/stx/test.st @@ -0,0 +1,2 @@ +isNil + ^true