create a generic tokenizer/sectionizer for the config file. pass off the token to...
[dana/openbox.git] / openbox / parse.yacc
1 %{
2 #include "parse.h"
3 #ifdef HAVE_STDIO_H
4 #  include <stdio.h>
5 #endif
6
7 extern int yylex();
8
9 extern int yylineno;
10 extern FILE *yyin;
11
12 static char *path;
13 static union ParseToken t;
14
15 /* in parse.c */
16 void parse_token(ParseTokenType type, union ParseToken token);
17 void parse_set_section(char *section);
18 %}
19
20 %union ParseToken {
21     float real;
22     int integer;
23     char *string;
24     char *identifier;
25     gboolean bool;
26     char character;
27 }
28
29 %token <real> REAL
30 %token <integer> INTEGER
31 %token <string> STRING
32 %token <identifier> IDENTIFIER
33 %token <bool> BOOL
34 %token <character> '('
35 %token <character> ')'
36 %token <character> '{'
37 %token <character> '}'
38 %token <character> '='
39 %token <character> ','
40 %token <character> '\n'
41 %token INVALID
42
43 %%
44
45 sections:
46   | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n' lines
47   ;
48
49 lines:
50   | lines tokens '\n' { t.character = $3; parse_token(TOKEN_NEWLINE, t); }
51   ;
52
53 tokens:
54     tokens token
55   | token
56   ;
57
58 token:
59     REAL       { t.real = $1; parse_token(TOKEN_REAL, t); }
60   | INTEGER    { t.integer = $1; parse_token(TOKEN_INTEGER, t); }
61   | STRING     { t.string = $1; parse_token(TOKEN_STRING, t); }
62   | IDENTIFIER { t.identifier = $1; parse_token(TOKEN_IDENTIFIER, t); }
63   | BOOL       { t.bool = $1; parse_token(TOKEN_BOOL, t); }
64   | '('        { t.character = $1; parse_token(TOKEN_LBRACKET, t); }
65   | ')'        { t.character = $1; parse_token(TOKEN_RBRACKET, t); }
66   | '{'        { t.character = $1; parse_token(TOKEN_LBRACE, t); }
67   | '}'        { t.character = $1; parse_token(TOKEN_RBRACE, t); }
68   | '='        { t.character = $1; parse_token(TOKEN_EQUALS, t); }
69   | ','        { t.character = $1; parse_token(TOKEN_COMMA, t); }
70   ;
71
72 %%
73
74 void yyerror(char *err) {
75     g_message("%s:%d: %s", path, yylineno, err);
76 }
77
78 void parse_rc()
79 {
80     /* try the user's rc */
81     path = g_build_filename(g_get_home_dir(), ".openbox", "rc3", NULL);
82     if ((yyin = fopen(path, "r")) == NULL) {
83         g_free(path);
84         /* try the system wide rc */
85         path = g_build_filename(RCDIR, "rc3", NULL);
86         if ((yyin = fopen(path, "r")) == NULL) {
87             g_warning("No rc2 file found!");
88             g_free(path);
89             return;
90         }
91     }
92
93     yylineno = 1;
94
95     yyparse();
96
97     g_free(path);
98 }