]> Dogcows Code - chaz/openbox/commitdiff
beginning of obcl. the parser works with semicolons after statements
authorMarius Nita <marius@cs.pdx.edu>
Mon, 14 Apr 2003 06:04:49 +0000 (06:04 +0000)
committerMarius Nita <marius@cs.pdx.edu>
Mon, 14 Apr 2003 06:04:49 +0000 (06:04 +0000)
for now, there is much left to change and do.

obcl/Makefile [new file with mode: 0644]
obcl/foo.conf [new file with mode: 0644]
obcl/lex.l [new file with mode: 0644]
obcl/main.c [new file with mode: 0644]
obcl/obcl.c
obcl/obcl.h [new file with mode: 0644]
obcl/parse.y [new file with mode: 0644]

diff --git a/obcl/Makefile b/obcl/Makefile
new file mode 100644 (file)
index 0000000..03c3a5d
--- /dev/null
@@ -0,0 +1,23 @@
+CFLAGS=-ansi -pedantic -Wall `pkg-config --cflags glib-2.0`
+LIBS=`pkg-config --libs glib-2.0` -ll
+
+targets = cltest
+
+sources = obcl.c main.c parse.c lex.c
+headers = obcl.h
+
+.PHONY: all clean
+
+all: $(targets)
+
+$(targets): $(sources:.c=.o)
+       $(CC) -o $@ $^ $(LIBS)
+
+parse.c: parse.y
+       $(YACC) -d -o$@ $^
+
+lex.c: lex.l
+       $(LEX) -o$@ $^
+
+clean:
+       $(RM) $(targets) *.o core *~ lex.c parse.c parse.h
diff --git a/obcl/foo.conf b/obcl/foo.conf
new file mode 100644 (file)
index 0000000..648bb01
--- /dev/null
@@ -0,0 +1,21 @@
+include "meh.conf";
+include "bummy.conf";
+
+section mouse {
+    mbind titlebar, frame {
+        event click;
+        button middle;
+        action lower;
+    }
+
+    mbind frame {
+        event click;
+        button right;
+        action launch_nukes;
+    }
+}
+
+section theme {
+    theme "merry";
+    font "tahoma-12 bold";
+}
diff --git a/obcl/lex.l b/obcl/lex.l
new file mode 100644 (file)
index 0000000..33a3c61
--- /dev/null
@@ -0,0 +1,86 @@
+%{
+#include "obcl.h"
+#include "parse.h"
+%}
+
+%option yylineno
+
+DGT   [0-9]
+ID    [a-zA-Z_][a-zA-Z_\.\-0-9]*
+
+
+ /* string bummy */
+%x str
+%%
+
+       char str_buf[1024];
+       char *str_buf_ptr;
+       int str_char;
+
+ /* begin a string */
+[\"\'] {
+           str_buf_ptr = str_buf;
+           str_char = yytext[0];
+           BEGIN(str);
+       }
+
+ /* end a string */
+<str>[\"\'] {
+           if (yytext[0] == str_char) {
+               BEGIN(INITIAL);
+               *str_buf_ptr = '\0';
+               yylval.string = g_strdup(str_buf);
+               return TOK_STRING;
+           } else {
+               *str_buf_ptr++ = yytext[0];
+           }
+       }
+
+ /* can't have newlines in strings */
+<str>\n {
+           printf("Error: Unterminated string constant.\n");
+           BEGIN(INITIAL);
+       }
+
+ /* handle \" and \' */
+<str>"\\"[\"\'] {
+           if (yytext[1] == str_char)
+               *str_buf_ptr++ = yytext[1];
+           else {
+               *str_buf_ptr++ = yytext[0];
+               *str_buf_ptr++ = yytext[1];
+           }
+       }
+
+ /* eat valid string contents */
+<str>[^\\\n\'\"]+ {
+           char *yptr = yytext;
+           while (*yptr) {
+               *str_buf_ptr++ = *yptr++;
+           }
+       }
+
+ /* numberz */
+{DGT}+ {
+           yylval.num = atof(yytext);
+           return TOK_NUM;
+       }
+
+ /* real numbers */
+{DGT}+"."{DGT}* {
+           yylval.num = atof(yytext);
+           return TOK_NUM;
+       }
+
+ /* identifiers -- names without spaces and other crap in them */
+{ID}   {
+           yylval.string = g_strdup(yytext);
+           return TOK_ID;
+       }
+
+ /* skip comments */
+"#".*\n     ;
+ /* skip other whitespace */
+[ \n\t]+      ;
+.           { return yytext[0]; }
+%%
diff --git a/obcl/main.c b/obcl/main.c
new file mode 100644 (file)
index 0000000..5fb8396
--- /dev/null
@@ -0,0 +1,8 @@
+#include "obcl.h"
+
+int main()
+{
+    GList *lst = cl_parse("foo.conf");
+    cl_print_tree(lst,0);
+    return 0;
+}
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..b4d9aeee157bbbe2f3c84633aecb2cbdbb5998a2 100644 (file)
@@ -0,0 +1,57 @@
+#include "obcl.h"
+
+void free_cl_tree(GList *tree)
+{
+
+}
+
+GList *cl_parse(gchar *file)
+{
+    FILE *fh = fopen(file, "r");
+    if (fh)
+        return cl_parse_fh(fh);
+    else {
+        printf("can't open file %s\n", file);
+        return 0;
+    }
+}
+
+void cl_print_tree(GList *tree, int depth)
+{
+    CLNode *tmp;
+    int tmpd = depth;
+
+    for (; tree; tree = tree->next) {
+        tmp = (CLNode*)tree->data;
+
+        while (tmpd-- > 0)
+            printf(" ");
+        tmpd = depth;
+
+        switch(tmp->type) {
+        case CL_ID:
+            printf("--ID-- %s\n", tmp->u.str);
+            break;
+        case CL_STR:
+            printf("--STR-- %s\n", tmp->u.str);
+            break;
+        case CL_NUM:
+            printf("--NUM-- %.2f\n", tmp->u.num);
+            break;
+        case CL_LIST:
+            printf("--LIST-- %s\n", tmp->u.lb.id);
+            cl_print_tree(tmp->u.lb.list, depth+2);
+            break;
+        case CL_BLOCK:
+            printf("--BLOCK-- %s\n", tmp->u.lb.id);
+            cl_print_tree(tmp->u.lb.block, depth+2);
+            break;
+        case CL_LISTBLOCK:
+            printf("--LISTBLOCK-- %s\n", tmp->u.lb.id);
+            cl_print_tree(tmp->u.lb.list, depth+2);
+            printf("\n");
+            cl_print_tree(tmp->u.lb.block, depth+2);
+            break;
+        }
+    }
+}
diff --git a/obcl/obcl.h b/obcl/obcl.h
new file mode 100644 (file)
index 0000000..a940e89
--- /dev/null
@@ -0,0 +1,38 @@
+#ifndef __obcl_h
+#define __obcl_h
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <glib.h>
+
+typedef enum CLNodeType {
+    CL_ID,
+    CL_NUM,
+    CL_STR,
+    CL_LIST,
+    CL_BLOCK,
+    CL_LISTBLOCK
+} CLNodeType;
+
+typedef struct CLNode {
+    CLNodeType type;
+    union {
+        struct {
+            gchar *id;
+            GList *list;
+            GList *block;
+        } lb;
+        double num;
+        gchar *str;
+    } u;
+
+} CLNode;
+
+void free_cl_tree(GList *tree);
+GList *cl_parse(gchar *file);
+GList *cl_parse_fh(FILE *file);
+void cl_print_tree(GList *tree, int depth);
+
+GList *parse_file(FILE *fh);
+
+#endif /* __obcl_h */
diff --git a/obcl/parse.y b/obcl/parse.y
new file mode 100644 (file)
index 0000000..40a0718
--- /dev/null
@@ -0,0 +1,146 @@
+%{
+#include "obcl.h"
+
+int yylex(void);
+void yyerror(char *msg, ...);
+
+extern int yylineno;
+extern char *yytext;
+GList *config; /* this is what we parse into */
+
+%}
+
+%union {
+    double num;
+    gchar *string;
+    CLNode *node;
+    GList *glist;
+};
+
+%token <num> TOK_NUM
+%token <string> TOK_ID TOK_STRING
+%token TOK_SEP
+
+%type <glist> config
+%type <glist> stmts
+%type <node> stmt
+%type <glist> list
+%type <glist> block
+%type <node> value
+
+%expect 2 /* for now */
+
+%%
+
+config: stmts
+    {
+        config = $$ = $1;
+    }
+    ;
+
+stmts:
+    { $$ = NULL; }
+    | stmt
+    { $$ = g_list_append(NULL, $1); }
+    | stmts stmt
+    { $$ = g_list_append($1, $2); }
+    ;
+
+stmt: TOK_ID list ';'
+    {
+        CLNode *s = g_new(CLNode,1);
+        s->type = CL_LIST;
+        s->u.lb.list = $2;
+        s->u.lb.id = $1;
+        $$ = s;
+    }
+    | TOK_ID list block
+    {
+        CLNode *s = g_new(CLNode,1);
+        s->type = CL_LISTBLOCK;
+        s->u.lb.list = $2;
+        s->u.lb.block = $3;
+        s->u.lb.id = $1;
+        $$ = s;
+    }
+    | TOK_ID block
+    { 
+        CLNode *s = g_new(CLNode,1);
+        s->type = CL_BLOCK;
+        s->u.lb.block = $2;
+        s->u.lb.id = $1;
+        $$ = s;
+    }
+    ;
+
+list: value
+    {
+        $$ = g_list_append(NULL, $1);
+    }
+    | list ',' value
+    {
+        $$ = g_list_append($1, $3);
+    }
+    ;
+
+block: '{' stmts '}'
+    {
+        $$ = $2;
+    }
+    ;
+
+value: TOK_ID
+    {
+        CLNode *node = g_new(CLNode,1);
+        node->type = CL_ID;
+        node->u.str = $1;
+        $$ = node;
+    }
+    | TOK_STRING
+    { 
+        CLNode *node = g_new(CLNode,1);
+        node->type = CL_STR;
+        node->u.str = $1;
+        $$ = node;
+    }
+    | TOK_NUM
+    {
+        CLNode *node = g_new(CLNode,1);
+        node->type = CL_NUM;
+        node->u.num = $1;
+        $$ = node;
+    }
+    ;
+
+%%
+
+int yywrap()
+{
+    return 1;
+}
+
+/* void yyerror(const char *err) */
+/* { */
+/*     fprintf(stderr, "Parse error on line %d, near '%s': %s\n", */
+/*             yylineno, yytext, err); */
+/* } */
+
+void yyerror(char *msg, ...)
+{
+    va_list args;
+    va_start(args,msg);
+
+    fprintf(stderr, "Error on line %d, near '%s': ", yylineno, yytext);
+    vfprintf(stderr, msg, args);
+    fprintf(stderr,"\n");
+
+    va_end(args);
+}
+
+GList *cl_parse_fh(FILE *fh)
+{
+    extern FILE *yyin;
+    yyin = fh;
+    yyparse();
+    return config;
+}
This page took 0.031168 seconds and 4 git commands to generate.