cleanups and such
[mikachu/openbox.git] / obcl / parse.y
1 %{
2 #include "obcl.h"
3
4 int yylex(void);
5 void yyerror(char *msg, ...);
6
7 extern int yylineno;
8 extern char *yytext;
9 GList *config; /* this is what we parse into */
10
11 %}
12
13 %union {
14     double num;
15     gchar *string;
16     CLNode *node;
17     GList *glist;
18 };
19
20 %token <num> TOK_NUM
21 %token <string> TOK_ID TOK_STRING
22 %token TOK_SEP
23
24 %type <glist> config
25 %type <glist> stmts
26 %type <node> stmt
27 %type <glist> list
28 %type <glist> block
29 %type <node> value
30
31 %expect 2 /* for now */
32
33 %%
34
35 config: stmts
36     {
37         config = $$ = $1;
38     }
39     ;
40
41 stmts:
42     { $$ = NULL; }
43     | stmt
44     { $$ = g_list_append(NULL, $1); }
45     | stmts stmt
46     { $$ = g_list_append($1, $2); }
47     ;
48
49 stmt: TOK_ID list ';'
50     {
51         CLNode *s = g_new(CLNode,1);
52         s->type = CL_LIST;
53         s->u.lb.list = $2;
54         s->u.lb.block = NULL;
55         s->u.lb.id = $1;
56         $$ = s;
57     }
58     | TOK_ID list block
59     {
60         CLNode *s = g_new(CLNode,1);
61         s->type = CL_LISTBLOCK;
62         s->u.lb.list = $2;
63         s->u.lb.block = $3;
64         s->u.lb.id = $1;
65         $$ = s;
66     }
67     | TOK_ID block
68     { 
69         CLNode *s = g_new(CLNode,1);
70         s->type = CL_BLOCK;
71         s->u.lb.block = $2;
72         s->u.lb.list = NULL;
73         s->u.lb.id = $1;
74         $$ = s;
75     }
76     ;
77
78 list: value
79     {
80         $$ = g_list_append(NULL, $1);
81     }
82     | list ',' value
83     {
84         $$ = g_list_append($1, $3);
85     }
86     ;
87
88 block: '{' stmts '}'
89     {
90         $$ = $2;
91     }
92     ;
93
94 value: TOK_ID
95     {
96         CLNode *node = g_new(CLNode,1);
97         node->type = CL_ID;
98         node->u.str = $1;
99         $$ = node;
100     }
101     | TOK_STRING
102     { 
103         CLNode *node = g_new(CLNode,1);
104         node->type = CL_STR;
105         node->u.str = $1;
106         $$ = node;
107     }
108     | TOK_NUM
109     {
110         CLNode *node = g_new(CLNode,1);
111         node->type = CL_NUM;
112         node->u.num = $1;
113         $$ = node;
114     }
115     ;
116
117 %%
118
119 int yywrap()
120 {
121     return 1;
122 }
123
124 /* void yyerror(const char *err) */
125 /* { */
126 /*     fprintf(stderr, "Parse error on line %d, near '%s': %s\n", */
127 /*             yylineno, yytext, err); */
128 /* } */
129
130 void yyerror(char *msg, ...)
131 {
132     va_list args;
133     va_start(args,msg);
134
135     fprintf(stderr, "Error on line %d, near '%s': ", yylineno, yytext);
136     vfprintf(stderr, msg, args);
137     fprintf(stderr,"\n");
138
139     va_end(args);
140 }
141
142 GList *cl_parse_fh(FILE *fh)
143 {
144     extern FILE *yyin;
145     yyin = fh;
146     yyparse();
147     return config;
148 }