]> Pileus Git - ~andy/ct/commitdiff
Add C/Bison/Lex ct parser
authorAndy Spencer <andy753421@gmail.com>
Sun, 22 Nov 2009 05:35:45 +0000 (05:35 +0000)
committerAndy Spencer <andy753421@gmail.com>
Sun, 22 Nov 2009 05:35:45 +0000 (05:35 +0000)
.gitignore
ct.awk [moved from tmpl.awk with 100% similarity]
ct.c [new file with mode: 0644]
example/html.ct
gallery/html.ct
mkcommon
mkfile [new file with mode: 0644]
parse.y [new file with mode: 0644]
scan.l [new file with mode: 0644]

index b3f23b60c8f2c3b2a9c802ab838d1f9431b5b871..1a422674868cb9187664464ed8f79b7561328c4b 100644 (file)
@@ -1,4 +1,5 @@
 *.o
 *~
-lib.c
-test
+ct
+parse.[ch]
+scan.c
diff --git a/tmpl.awk b/ct.awk
similarity index 100%
rename from tmpl.awk
rename to ct.awk
diff --git a/ct.c b/ct.c
new file mode 100644 (file)
index 0000000..3506b8c
--- /dev/null
+++ b/ct.c
@@ -0,0 +1,40 @@
+#include <stdio.h>
+#include <glib.h>
+
+#include "parse.h"
+
+gpointer parse(FILE *input, GList **data, GList **code);
+
+int main(int argc, char **argv)
+{
+        /* Parse arguments */
+        int option_log_level = 7;
+        GOptionEntry entries[] = {
+                {"debug", 'd', 0, G_OPTION_ARG_INT,  &option_log_level,
+                        "Change default log level", "[1-7]"},
+                {NULL}
+        };
+        GOptionContext *context = g_option_context_new("infile");
+        g_option_context_add_main_entries(context, entries, NULL);
+        g_option_context_parse(context, &argc, &argv, NULL);
+
+        FILE *input = stdin;
+        for (int i = 1; i < argc; i++)
+                if (g_str_has_suffix(argv[i], ".ct"))
+                        input = fopen(argv[i], "r");
+
+        /* Start compiling */
+       GList *data = NULL;
+       GList *code = NULL;
+        parse(input, &data, &code);
+       data = g_list_reverse(data);
+       code = g_list_reverse(code);
+
+        g_print("#include <stdio.h>\n");
+       g_print("\n");
+       for (GList *cur = data; cur; cur = cur->next)
+               g_print("%s", cur->data);
+        g_print("\n");
+       for (GList *cur = code; cur; cur = cur->next)
+               g_print("%s", cur->data);
+}
index e38344fe152a3c75c437f730d8a0bbe58977e072..d08df11c5cb526ab27c5093be231cd82465b2565 100644 (file)
@@ -1,16 +1,16 @@
-[void header() {]
+<% void header() { %>
 Content-Type: application/xhtml+xml; charset=UTF-8
-[}]
+<% } %>
 
-[void body() {]
-       [for (int i = 0; i < 3; i++)]
+<% void body() { %>
+       <% for (int i = 0; i < 3; i++) %>
                <p>hello, world</p>
-[}]
+<% } %>
 
-[void html() {]
+<% void html() { %>
 <html>
        <body>
-               [body();]
+               <% body(); %>
        </body>
 </html>
-[}]
+<% } %>
index 4080fa30f9c1c005142f3917fcf95a77f78c69ea..e62621aa1920d97f3f84e3d08de1a850a34babe6 100644 (file)
@@ -1,11 +1,12 @@
-[#include <glib.h>]
+<% #include <glib.h> %>
 
-[void header() {]
+
+<% void header() { %>
 Content-Type: text/html; charset=UTF-8
-[}]
+<% } %>
 
 
-[void frame_index(){]
+<% void frame_index(){ %>
 <html>
        <frameset rows="20, *">
                <frame name="head" src="?head">
@@ -15,10 +16,10 @@ Content-Type: text/html; charset=UTF-8
                </frameset>
        </frameset>
 </html>
-[}]
+<% } %>
 
 
-[void frame_head(){]
+<% void frame_head(){ %>
 <html>
        <head>
                <style>
@@ -34,10 +35,10 @@ Content-Type: text/html; charset=UTF-8
                </center>
        </body>
 </html>
-[}]
+<% } %>
 
 
-[void frame_nav(int square, GList *images) {]
+<% void frame_nav(int square, GList *images) { %>
 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
 <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
@@ -53,7 +54,7 @@ Content-Type: text/html; charset=UTF-8
                                text-align:center;
                                text-decoration:none;
                                width:214px;
-                               [if (square)]
+                               <% if (square) %>
                                height:214px;
                        }
                        .box {
@@ -74,21 +75,19 @@ Content-Type: text/html; charset=UTF-8
                </style>
        </head>
        <body>
-               [for (GList *cur = images; cur; cur = cur->next) {]
+               <% for (GList *cur = images; cur; cur = cur->next) { %>
+                       <% gchar *img = (gchar *)cur->data; %>
                        <div class="align">
-                               <a class="box" target="content"
-                                       [g_print("href=\"images/%s\"", (gchar*)cur->data);]
-                               ><img
-                                       [g_print("src=\"thumbs/%s\"", (gchar*)cur->data);]
-                               ></a>
+                               <a class="box" target="content" href="images/<%= "%s", img %>">
+                               <img src="thumbs/<%= "%s", img %>"></a>
                        </div>
-               [}]
+               <% } %>
        </body>
 </html>
-[}]
+<% } %>
 
 
-[void frame_content(){]
+<% void frame_content(){ %>
 <html>
 </html>
-[}]
+<% } %>
index 4e2afaf35da7c89a7df120d910d7d9af6b9ce897..7ef68beacf55a2a186134f63e390569f50462408 100644 (file)
--- a/mkcommon
+++ b/mkcommon
@@ -1,5 +1,6 @@
 %.c: %.ct
-       ../tmpl.awk <$prereq >$target
+       (cd .. && mk)
+       ../ct <$prereq >$target
        ex +'norm gg=G' +'wq' $target
 
 <$HOME/lib/mkcommon
diff --git a/mkfile b/mkfile
new file mode 100644 (file)
index 0000000..8f43ffd
--- /dev/null
+++ b/mkfile
@@ -0,0 +1,11 @@
+PROGS=ct
+PKGS=glib-2.0
+ct-test:V: ct
+       ./ct < example/html.ct
+ct: ct.o scan.o parse.o parse.h
+%.c: %.l
+       flex -o $target $prereq
+%.h %.c: %.y
+       bison -d -o $stem.c $stem.y
+CLEAN=parse.h parse.c scan.c
+<$HOME/lib/mkcommon
diff --git a/parse.y b/parse.y
new file mode 100644 (file)
index 0000000..11eb57c
--- /dev/null
+++ b/parse.y
@@ -0,0 +1,49 @@
+%{
+#define YYSTYPE char *
+#include <stdio.h>
+#include <glib.h>
+extern FILE *yyin;
+int yylex(void);
+void yyerror(gpointer node, char const *s);
+static GList *code = NULL;
+static GList *data = NULL;
+%}
+%error-verbose
+%parse-param {gpointer root};
+%token START END DATA OUT
+%%
+
+input : all | all input ;
+
+all   : data | code | print ;
+
+data  : DATA {
+       static int i = 0;
+       data = g_list_prepend(data, g_strdup_printf(
+               "static char data%d[] = \"%s\\n\";\n",
+               i, g_strescape($1, "")));
+       code = g_list_prepend(code, g_strdup_printf(
+               "fwrite(data%d, sizeof(data%d)-1, 1, stdout);\n",
+               i, i));
+       i++;
+};
+
+code  : START DATA END {
+       code = g_list_prepend(code, g_strdup_printf("%s\n", $2));
+};
+
+print : START OUT DATA END {
+       code = g_list_prepend(code, g_strdup_printf("printf(%s);\n", $3));
+};
+
+%%
+gpointer parse(FILE *input, GList **_data, GList **_code) {
+       yyin = input;
+       yyparse(NULL);
+       *_data = data;
+       *_code = code;
+       return NULL;
+}
+void yyerror(gpointer root, char const *s) {
+       g_error("[%s]\n", s);
+}
diff --git a/scan.l b/scan.l
new file mode 100644 (file)
index 0000000..19f6777
--- /dev/null
+++ b/scan.l
@@ -0,0 +1,23 @@
+%{
+#define YYSTYPE char *
+#include <glib.h>
+#include "parse.h"
+#define debug(arg) // g_message("scan: " arg, yytext);
+%}
+%option noyywrap
+%option nounput
+%option noinput
+/* %option nodebug */
+START [ \t]*<%
+END   [ \t]*%>[ \t]*
+DATA  ([^<\n]|<[^%])*
+CODE  [ \t\n]([^%\n]|%[^>])*
+%s IN FMT
+%%
+<INITIAL>{START} { debug("START [%s]"); yylval = g_strdup(yytext); BEGIN(IN);      return START; }
+<INITIAL>{DATA}  { debug("DATA  [%s]"); yylval = g_strdup(yytext);                 return DATA;  }
+<IN>{END}        { debug("END   [%s]"); yylval = g_strdup(yytext); BEGIN(INITIAL); return END;   }
+<IN>=            { debug("OUT   [%s]"); yylval = g_strdup(yytext);                 return OUT;   }
+<IN>{CODE}       { debug("CODE  [%s]"); yylval = g_strdup(yytext);                 return DATA;  }
+[\n]             { debug("NL    [%s]"); }
+%%