# # blogc: A balde compiler. # Copyright (C) 2015 Rafael G. Martins # # This program can be distributed under the terms of the BSD License. # See the file COPYING. # %{ #include #include "utils/utils.h" #include "source-grammar.h" #define YY_INPUT(buf, result, max_size) \ { \ int yyc = (charbuf && *charbuf != '\0') ? *charbuf++ : EOF; \ result = (EOF == yyc) ? 0 : (*buf = yyc, 1); \ } static b_trie_t *config = NULL; static const char *charbuf = NULL; static char *key = NULL; static char *content = NULL; static void blogc_source_config_key(const char *value) { if (key != NULL) { fprintf(stderr, "Syntax error: configuration key already set: %s\n", key); exit(1); } key = b_strdup(value); } static void blogc_source_config_value(const char *value) { if (key == NULL) { fprintf(stderr, "Syntax error: configuration value without a key: %s\n", value); exit(1); } b_trie_insert(config, key, b_str_strip(b_strdup(value))); free(key); key = NULL; } static void blogc_source_content(const char *value) { if (content != NULL) { fprintf(stderr, "Syntax error: content set twice\n"); exit(1); } content = b_strdup(value); } %} page = ( ( - eol )* ( config ( - eol )* )+ '----' '-'* eol content eof ) | anything { fprintf(stderr, "Syntax error near: %s\n", yytext); exit(1); } # Useful rules eol = '\n' | '\r\n' | '\r' eof = !. - = [\t ]* id = [A-Z][A-Z0-9_]* anything = < ( !eol . )* > eol # Configuration config_key = < id > { blogc_source_config_key(yytext); } config_value = < anything > { blogc_source_config_value(yytext); } config = config_key ':' ' '+ config_value # Generic content content = < ( !eof . )+ > { blogc_source_content(yytext); } %% void blogc_source_free(blogc_source_t *source) { if (source == NULL) return; free(source->content); b_trie_free(source->config); free(source); } static void blogc_source_config_free(void *ptr) { free(ptr); } blogc_source_t* blogc_source_parse(const char *tmpl) { charbuf = tmpl; config = b_trie_new(blogc_source_config_free); key = NULL; content = NULL; while(yyparse()); blogc_source_t *rv = malloc(sizeof(blogc_source_t)); rv->content = content; rv->config = config; charbuf = NULL; return rv; }