$HeadURL$
*/
#include "grammar.h"
+#include "exn.h"
tree_t* grammar_toplevel(parser_t* p_parser)
{
- if (parser_accept_str(p_parser, T_VAR, "import"))
- grammar_import(p_parser);
- else if (parser_accept_str(p_parser, T_VAR, "def"))
- grammar_definition(p_parser);
- else if (p_parser->p_lexer->scanner->p_input == stdin)
- grammar_expression(p_parser);
- else
- parser_error(p_parser, "Unrecognized top-level form");
- return parser_get_tree(p_parser);
+ tree_t* p_tree = NULL;
+ try {
+ if (parser_accept_str(p_parser, T_VAR, "import"))
+ grammar_import(p_parser);
+ else if (parser_accept_str(p_parser, T_VAR, "def"))
+ grammar_definition(p_parser);
+ else if (p_parser->p_lexer->scanner->p_input == stdin)
+ grammar_expression(p_parser);
+ else
+ parser_error(p_parser, "Unrecognized top-level form");
+ p_tree = parser_get_tree(p_parser);
+ } catch(ParseException) {
+ fprintf(stderr, "Invalid Syntax\n");
+ }
+ return p_tree;
}
void grammar_import(parser_t* p_parser)
char* text = scanner_read(p_lexer->scanner);
if (NULL != text) {
p_tok = lexer_make_token(text);
- if (NULL != p_tok)
- printf("TOK: '%s' -> %s\n", text, lexer_tok_type_str(p_tok));
+ //if (NULL != p_tok)
+ // printf("TOK: '%s' -> %s\n", text, lexer_tok_type_str(p_tok));
free(text);
}
return p_tok;
}
+void lexer_skipline(lexer_t* p_lexer) {
+ scanner_getline(p_lexer->scanner);
+}
+
static lex_tok_t* lexer_make_token(char* text) {
lex_tok_t* p_tok = NULL;
if ((0 == strcmp(text,"end") || (text[0] == ';'))) {
lex_tok_t* lexer_read(lexer_t* p_lexer);
+void lexer_skipline(lexer_t* p_lexer);
+
char* lexer_tok_type_str(lex_tok_t* p_tok);
#endif /* LEXER_H */
parser_t* p_parser = parser_new(":> ", stdin);
while(!parser_eof(p_parser)) {
tree_t* p_tree = grammar_toplevel(p_parser);
- print_tree(p_tree, 0);
- mem_release(p_tree);
- puts("OK.");
+ if (NULL != p_tree) {
+ print_tree(p_tree, 0);
+ mem_release(p_tree);
+ puts("OK.");
+ } else {
+ parser_resume(p_parser);
+ }
}
mem_release(p_parser);
#include "parser.h"
#include "vec.h"
+DEFINE_EXCEPTION(ParseException, &RuntimeException);
+
lex_tok_t tok_eof = { T_END_FILE, NULL, 0, 0, NULL };
static void parser_free(void* p_obj) {
return (parser_peek(p_parser)->type == T_END_FILE);
}
+void parser_resume(parser_t* p_parser) {
+ if (NULL != p_parser->p_tok)
+ mem_release(p_parser->p_tok);
+ vec_clear(p_parser->p_tok_buf);
+ lexer_skipline(p_parser->p_lexer);
+}
+
void parser_error(parser_t* p_parser, const char* p_text)
{
- (void)p_parser;
- fprintf(stderr,"Error: %s\n",p_text);
- exit(1);
+ throw_msg(ParseException, p_text);
}
bool parser_accept(parser_t* p_parser, lex_tok_type_t type)
}
tree_t* parser_get_tree(parser_t* p_parser) {
- tree_t* p_tree = parser_tree_new(TREE, p_parser->p_tok_buf);
- p_parser->p_tok_buf = vec_new(0);
+ tree_t* p_tree = NULL;
+ if (1 == vec_size(p_parser->p_tok_buf)) {
+ p_tree = mem_retain(vec_at(p_parser->p_tok_buf, 0));
+ vec_clear(p_parser->p_tok_buf);
+ } else {
+ p_tree = parser_tree_new(TREE, p_parser->p_tok_buf);
+ p_parser->p_tok_buf = vec_new(0);
+ }
return p_tree;
}
#include "lexer.h"
#include "vec.h"
+#include "exn.h"
+
+DECLARE_EXCEPTION(ParseException);
typedef enum { ATOM, TREE } tree_tag_t;
bool parser_eof(parser_t* p_parser);
+void parser_resume(parser_t* p_parser);
+
void parser_error(parser_t* p_parser, const char* p_text);
bool parser_accept(parser_t* p_parser, lex_tok_type_t type);
#include "scanner.h"
#include "mem.h"
-static void scanner_getline(scanner_t* p_scanner);
static void scanner_skip_ws(scanner_t* p_scanner);
static char scanner_current(scanner_t* p_scanner);
static bool scanner_oneof(scanner_t* p_scanner, const char* p_set);
return ret;
}
-static void scanner_getline(scanner_t* p_scanner) {
+void scanner_getline(scanner_t* p_scanner) {
int c;
size_t capacity = 8;
size_t index = 0;
bool scanner_eol(scanner_t* p_scanner);
+void scanner_getline(scanner_t* p_scanner);
+
#endif /* SCANNER_H */