summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openbox/parse.c16
-rw-r--r--openbox/parse.h12
-rw-r--r--openbox/parse.y66
3 files changed, 67 insertions, 27 deletions
diff --git a/openbox/parse.c b/openbox/parse.c
index f8f0cd94..421dc48f 100644
--- a/openbox/parse.c
+++ b/openbox/parse.c
@@ -65,7 +65,7 @@ void parse_token(ParseTokenType type, union ParseToken token)
func(type, token);
}
-static void parse_rc_token(ParseTokenType type, union ParseToken token)
+static void parse_rc_token(ParseToken *token)
{
static int got_eq = FALSE;
static ParseTokenType got_val = 0;
@@ -74,35 +74,35 @@ static void parse_rc_token(ParseTokenType type, union ParseToken token)
static gboolean b;
if (id == NULL) {
- if (type == TOKEN_IDENTIFIER) {
+ if (token->type == TOKEN_IDENTIFIER) {
id = token.identifier;
return;
} else {
yyerror("syntax error");
}
} else if (!got_eq) {
- if (type == TOKEN_EQUALS) {
+ if (token->type == TOKEN_EQUALS) {
got_eq = TRUE;
return;
} else {
yyerror("syntax error");
}
} else if (!got_val) {
- if (type == TOKEN_STRING) {
+ if (token->type == TOKEN_STRING) {
s = token.string;
got_val = type;
return;
- } else if (type == TOKEN_BOOL) {
+ } else if (token->type == TOKEN_BOOL) {
b = token.bool;
got_val = type;
return;
- } else if (type == TOKEN_INTEGER) {
+ } else if (token->type == TOKEN_INTEGER) {
i = token.integer;
got_val = type;
return;
} else
yyerror("syntax error");
- } else if (type != TOKEN_NEWLINE) {
+ } else if (token->type != TOKEN_NEWLINE) {
yyerror("syntax error");
} else {
ConfigValue v;
@@ -133,5 +133,5 @@ static void parse_rc_token(ParseTokenType type, union ParseToken token)
id = s = NULL;
got_eq = FALSE;
got_val = 0;
- parse_free_token(type, token);
+ parse_free_token(token->type, token);
}
diff --git a/openbox/parse.h b/openbox/parse.h
index f2d22f81..bd6c03f8 100644
--- a/openbox/parse.h
+++ b/openbox/parse.h
@@ -10,8 +10,7 @@ typedef enum {
TOKEN_STRING = STRING,
TOKEN_IDENTIFIER = IDENTIFIER,
TOKEN_BOOL = BOOL,
- TOKEN_LBRACKET = '(',
- TOKEN_RBRACKET = ')',
+ TOKEN_LIST,
TOKEN_LBRACE = '{',
TOKEN_RBRACE = '}',
TOKEN_EQUALS = '=',
@@ -19,7 +18,12 @@ typedef enum {
TOKEN_NEWLINE = '\n'
} ParseTokenType;
-typedef void (*ParseFunc)(ParseTokenType type, union ParseToken token);
+typedef struct {
+ ParseTokenType type;
+ union ParseTokenData data;
+} ParseToken;
+
+typedef void (*ParseFunc)(ParseToken *token);
void parse_startup();
void parse_shutdown();
@@ -33,7 +37,7 @@ void parse_reg_section(char *section, ParseFunc func);
/* Free a parsed token's allocated memory */
-void parse_free_token(ParseTokenType type, union ParseToken token);
+void parse_free_token(ParseToken *token);
/* Display an error message while parsing.
found in parse.yacc */
diff --git a/openbox/parse.y b/openbox/parse.y
index 71cc5ba9..37bd3dc3 100644
--- a/openbox/parse.y
+++ b/openbox/parse.y
@@ -6,13 +6,14 @@
%}
-%union ParseToken {
+%union ParseTokenData {
float real;
int integer;
char *string;
char *identifier;
gboolean bool;
char character;
+ GSList *list;
}
%{
@@ -26,10 +27,10 @@ extern int yylineno;
extern FILE *yyin;
static char *path;
-static union ParseToken t;
+static ParseToken t;
/* in parse.c */
-void parse_token(ParseTokenType type, union ParseToken token);
+void parse_token(ParseToken *token);
void parse_set_section(char *section);
%}
@@ -47,6 +48,9 @@ void parse_set_section(char *section);
%token <character> '\n'
%token INVALID
+%type <list> list
+%type <list> listtokens
+
%%
sections:
@@ -54,7 +58,7 @@ sections:
;
lines:
- | lines tokens '\n' { t.character = $3; parse_token($3, t); }
+ | lines tokens '\n' { t.type = $3; t.data.character = $3; parse_token(&t); }
;
tokens:
@@ -63,19 +67,51 @@ tokens:
;
token:
- REAL { t.real = $1; parse_token(REAL, t); }
- | INTEGER { t.integer = $1; parse_token(INTEGER, t); }
- | STRING { t.string = $1; parse_token(STRING, t); }
- | IDENTIFIER { t.identifier = $1; parse_token(IDENTIFIER, t); }
- | BOOL { t.bool = $1; parse_token(BOOL, t); }
- | '(' { t.character = $1; parse_token($1, t); }
- | ')' { t.character = $1; parse_token($1, t); }
- | '{' { t.character = $1; parse_token($1, t); }
- | '}' { t.character = $1; parse_token($1, t); }
- | '=' { t.character = $1; parse_token($1, t); }
- | ',' { t.character = $1; parse_token($1, t); }
+ REAL { t.type = TOKEN_REAL; t.data.real = $1; parse_token(&t); }
+ | INTEGER { t.type = TOKEN_INTEGER; t.data.integer = $1;
+ parse_token(&t); }
+ | STRING { t.type = TOKEN_STRING; t.data.string = $1; parse_token(&t); }
+ | IDENTIFIER { t.type = TOKEN_IDENTIFIER; t.data.identifier = $1;
+ parse_token(&t);}
+ | BOOL { t.type = TOKEN_BOOL; t.data.bool = $1; parse_token(&t); }
+ | list { t.type = TOKEN_LIST; t.data.list = $1; parse_token(&t); }
+ | '{' { t.type = $1; t.data.character = $1; parse_token(&t); }
+ | '}' { t.type = $1; t.data.character = $1; parse_token(&t); }
+ | '=' { t.type = $1; t.data.character = $1; parse_token(&t); }
+ | ',' { t.type = $1; t.data.character = $1; parse_token(&t); }
+ ;
+
+list:
+ '(' listtokens ')' { $$ = $2; }
+ ;
+
+listtokens:
+ listtokens listtoken { ParseToken *nt = g_new(ParseToken, 1);
+ nt->type = t.type;
+ nt->data = t.data;
+ $$ = g_slist_append($1, nt);
+ }
+ | token { ParseToken *nt = g_new(ParseToken, 1);
+ nt->type = t.type;
+ nt->data = t.data;
+ $$ = g_slist_append(NULL, nt);
+ }
+ ;
+
+listtoken:
+ REAL { t.type = TOKEN_REAL; t.data.real = $1; }
+ | INTEGER { t.type = TOKEN_INTEGER; t.data.integer = $1; }
+ | STRING { t.type = TOKEN_STRING; t.data.string = $1; }
+ | IDENTIFIER { t.type = TOKEN_IDENTIFIER; t.data.identifier = $1; }
+ | BOOL { t.type = TOKEN_BOOL; t.data.bool = $1; }
+ | list { t.type = TOKEN_LIST; t.data.list = $1; }
+ | '{' { t.type = $1; t.data.character = $1; }
+ | '}' { t.type = $1; t.data.character = $1; }
+ | '=' { t.type = $1; t.data.character = $1; }
+ | ',' { t.type = $1; t.data.character = $1; }
;
+
%%
void yyerror(char *err) {