node processing code/macros, and other fixes
[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->lineno = yylineno;
57         $$ = s;
58     }
59     | TOK_ID list block
60     {
61         CLNode *s = g_new(CLNode,1);
62         s->type = CL_LISTBLOCK;
63         s->u.lb.list = $2;
64         s->u.lb.block = $3;
65         s->u.lb.id = $1;
66         s->lineno = yylineno;
67         $$ = s;
68     }
69     | TOK_ID block
70     { 
71         CLNode *s = g_new(CLNode,1);
72         s->type = CL_BLOCK;
73         s->u.lb.block = $2;
74         s->u.lb.list = NULL;
75         s->u.lb.id = $1;
76         s->lineno = yylineno;
77         $$ = s;
78     }
79     ;
80
81 list: value
82     {
83         $$ = g_list_append(NULL, $1);
84     }
85     | list ',' value
86     {
87         $$ = g_list_append($1, $3);
88     }
89     ;
90
91 block: '{' stmts '}'
92     {
93         $$ = $2;
94     }
95     ;
96
97 value: TOK_ID
98     {
99         CLNode *node = g_new(CLNode,1);
100         node->type = CL_ID;
101         node->u.str = $1;
102         node->lineno = yylineno;
103         $$ = node;
104     }
105     | TOK_STRING
106     { 
107         CLNode *node = g_new(CLNode,1);
108         node->type = CL_STR;
109         node->u.str = $1;
110         node->lineno = yylineno;
111         $$ = node;
112     }
113     | TOK_NUM
114     {
115         CLNode *node = g_new(CLNode,1);
116         node->type = CL_NUM;
117         node->u.num = $1;
118         node->lineno = yylineno;
119         $$ = node;
120     }
121     ;
122
123 %%
124
125 int yywrap()
126 {
127     return 1;
128 }
129
130 /* void yyerror(const char *err) */
131 /* { */
132 /*     fprintf(stderr, "Parse error on line %d, near '%s': %s\n", */
133 /*             yylineno, yytext, err); */
134 /* } */
135
136 void yyerror(char *msg, ...)
137 {
138     va_list args;
139     va_start(args,msg);
140
141     fprintf(stderr, "Error on line %d, near '%s': ", yylineno, yytext);
142     vfprintf(stderr, msg, args);
143     fprintf(stderr,"\n");
144
145     va_end(args);
146 }
147
148 GList *cl_parse_fh(FILE *fh)
149 {
150     extern FILE *yyin;
151     yyin = fh;
152     yyparse();
153     return config;
154 }