# Define the compiler environment
base_env = BuildEnv.new(echo: :command) do |env|
env.build_dir('source','build/obj/source')
- env.set_toolset(:gcc)
+ env.set_toolset(:clang)
env["CFLAGS"] += ['-DLEAK_DETECT_LEVEL=1', '--std=c99', '-Wall', '-Wextra'] #, '-Werror']
env["CPPPATH"] += ['modules/libopts/source'] + Dir['modules/libcds/source/**/']
end
void grammar_import(parser_t* p_parser)
{
+ size_t mark = parser_mark(p_parser);
parser_expect(p_parser, T_VAR);
parser_expect(p_parser, T_END);
+ parser_reduce(p_parser, mark);
}
void grammar_definition(parser_t* p_parser)
{
+ size_t mark = parser_mark(p_parser);
parser_expect(p_parser,T_VAR);
if (parser_peek(p_parser)->type == T_LPAR) {
grammar_fn_stmnt(p_parser);
grammar_expression(p_parser);
parser_expect(p_parser,T_END);
}
+ parser_reduce(p_parser, mark);
}
void grammar_expression(parser_t* p_parser)
void grammar_arglist(parser_t* p_parser)
{
+ size_t mark = parser_mark(p_parser);
parser_expect(p_parser, T_LPAR);
while(parser_peek(p_parser)->type != T_RPAR) {
grammar_expression(p_parser);
parser_expect(p_parser, T_COMMA);
}
parser_expect(p_parser, T_RPAR);
+ parser_reduce(p_parser, mark);
}
void grammar_if_stmnt(parser_t* p_parser)
{
+ size_t mark = parser_mark(p_parser);
grammar_expression(p_parser);
grammar_expression(p_parser);
parser_expect_str(p_parser,T_VAR,"else");
grammar_expression(p_parser);
parser_expect(p_parser,T_END);
+ parser_reduce(p_parser, mark);
}
void grammar_fn_stmnt(parser_t* p_parser)
{
+ size_t mark1 = parser_mark(p_parser);
parser_expect(p_parser, T_LPAR);
+ size_t mark2 = parser_mark(p_parser);
while(parser_peek(p_parser)->type != T_RPAR) {
parser_expect(p_parser, T_VAR);
if(parser_peek(p_parser)->type != T_RPAR)
parser_expect(p_parser, T_COMMA);
}
parser_expect(p_parser, T_RPAR);
+ parser_reduce(p_parser, mark2);
while(parser_peek(p_parser)->type != T_END) {
grammar_expression(p_parser);
}
parser_expect(p_parser, T_END);
+ parser_reduce(p_parser, mark1);
}
/* SCLPL Parser
*****************************************************************************/
+
+void print_subtree(tree_t* p_tree, int depth);
+
+void print_tree(vec_t* p_vec, int depth);
+
+void print_subtree(tree_t* p_tree, int depth) {
+ for(int i = 0; i < (4 * depth); i++) printf("%c", ' ');
+ if (p_tree->tag == ATOM) {
+ puts("ATOM");
+ } else {
+ puts("TREE");
+ print_tree(p_tree->ptr.vec, depth+1);
+ }
+}
+
+void print_tree(vec_t* p_vec, int depth) {
+ for(size_t idx = 0; idx < vec_size(p_vec); idx++) {
+ tree_t* p_tree = vec_at(p_vec, idx);
+ print_subtree(p_tree, depth);
+ }
+}
+
/* TODO:
* Formalize grammar for parser
parser_t* p_parser = parser_new(":> ", stdin);
while(!parser_eof(p_parser)) {
grammar_toplevel(p_parser);
+ print_tree(p_parser->p_tok_buf, 0);
+ vec_clear(p_parser->p_tok_buf);
puts("OK.");
}
mem_release(p_parser);
return p_parser;
}
+static void parser_tree_free(void* p_obj) {
+ mem_release(((tree_t*)p_obj)->ptr.tok);
+}
+
+static tree_t* parser_tree_new(tree_tag_t tag, void* p_obj) {
+ tree_t* p_tree = (tree_t*)mem_allocate(sizeof(tree_t), &parser_tree_free);
+ p_tree->tag = tag;
+ p_tree->ptr.tok = (lex_tok_t*)p_obj;
+ return p_tree;
+}
+
void parser_fetch(parser_t* p_parser)
{
p_parser->p_tok = lexer_read(p_parser->p_lexer);
{
bool ret = false;
if (parser_peek(p_parser)->type == type) {
- vec_push_back(p_parser->p_tok_buf, p_parser->p_tok);
+ vec_push_back(p_parser->p_tok_buf, parser_tree_new(ATOM, p_parser->p_tok));
p_parser->p_tok = NULL;
ret = true;
}
{
bool ret = false;
if ((parser_peek(p_parser)->type == type) && (0 == strcmp((char*)(p_parser->p_tok->value), p_text))) {
- vec_push_back(p_parser->p_tok_buf, p_parser->p_tok);
+ vec_push_back(p_parser->p_tok_buf, parser_tree_new(ATOM, p_parser->p_tok));
p_parser->p_tok = NULL;
ret = true;
}
}
return ret;
}
+
+size_t parser_mark(parser_t* p_parser)
+{
+ return (vec_size(p_parser->p_tok_buf) - 1);
+}
+
+void parser_reduce(parser_t* p_parser, size_t mark)
+{
+ vec_t* p_buf = p_parser->p_tok_buf;
+ vec_t* p_form = vec_new(0);
+ for(size_t idx = mark; idx < vec_size(p_buf); idx++) {
+ tree_tag_t tag = ((tree_t*)vec_at(p_buf, idx))->tag;
+ tree_t* p_tree = parser_tree_new(tag, mem_retain(vec_at(p_buf, idx)));
+ vec_push_back(p_form, p_tree);
+ }
+ vec_erase(p_parser->p_tok_buf, mark, vec_size(p_parser->p_tok_buf)-1);
+ vec_push_back(p_parser->p_tok_buf, parser_tree_new(TREE, p_form));
+}
+
#include "lexer.h"
#include "vec.h"
+typedef enum { ATOM, TREE } tree_tag_t;
+
+typedef struct {
+ tree_tag_t tag;
+ union {
+ lex_tok_t* tok;
+ vec_t* vec;
+ } ptr;
+} tree_t;
+
typedef struct {
lexer_t* p_lexer;
lex_tok_t* p_tok;
bool parser_expect_str(parser_t* p_parser, lex_tok_type_t type, const char* p_text);
+size_t parser_mark(parser_t* p_parser);
+
+void parser_reduce(parser_t* p_parser, size_t mark);
+
#endif /* PARSER_H */