#include "lexer.h" #include "parser.h" #include "node.h" #include #include /** * @param node a tree of node structs representing a C source file. * @return a scheme representation of node. */ SCM node_to_scm(Node *node) { SCM ret = scm_list_1(scm_from_locale_symbol(node_types[node->type])); SCM field_value = SCM_BOOL_F; switch (node->type) { case FUNC: field_value = scm_from_locale_string(node->field.name); break; case EXPR: field_value = scm_from_locale_symbol(node_ops[node->field.op]); break; case CONST: field_value = scm_from_int32(node->field.val); break; default: ; } if (scm_is_true(field_value)) ret = scm_append(scm_list_2(ret, scm_list_1(field_value))); SCM child; for (size_t i = 0; i < node->num_children; ++i) { child = node_to_scm(node->children[i]); ret = scm_append(scm_list_2(ret, scm_list_1(child))); } return ret; } /** \brief Parser driver for ull. * Given F, returns an AST of the program represented as a guile s-exp, or #f on a parse error. * if DO_PARSE is false, only performs lexing, returning #t on a success. * @param f a preprocessed C file to parse. * @param do_parse on false, do not perform the parsing stage. * @return a SCM list representing the parse tree, or #t if do_parse is #f and lexing is successful, or #f otherwise. */ SCM file_to_ast_wrapper(SCM f, SCM do_parse) { char *file = scm_to_locale_string(f); Node *root = NULL; SCM ret = SCM_BOOL_F; yyin = fopen(file, "r"); if (yyin != NULL){ if (scm_is_true(do_parse)) { if (yyparse(&root) == 0) { ret = node_to_scm(root); free_node(root); } } else { ret = SCM_BOOL_T; int token; while ((token = yylex()) != 0) { if (token == YYerror) ret = SCM_BOOL_F; } } } fclose(yyin); free(file); return ret; } void init_parser_driver() { scm_c_define_gsubr("file->ast", 2, 0, 0, file_to_ast_wrapper); scm_c_export("file->ast", NULL); } void scm_init_parser_driver_module() { scm_c_define_module("frontend driver", init_parser_driver, NULL); }