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