%}
-%union ParseToken {
+%union ParseTokenData {
float real;
int integer;
char *string;
char *identifier;
gboolean bool;
char character;
+ GList *list;
}
%{
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_assign(char *name, ParseToken *token);
void parse_set_section(char *section);
%}
%token <character> '\n'
%token INVALID
+%type <list> list
+%type <list> listtokens
+
%%
sections:
- | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n' lines
+ | sections '[' IDENTIFIER ']' { parse_set_section($3); } '\n'
+ { ++yylineno; } lines
;
lines:
- | lines tokens '\n' { t.character = $3; parse_token($3, t); }
+ | lines tokens { t.type='\n'; t.data.character='\n'; parse_token(&t); } '\n'
+ { ++yylineno; }
+ | lines IDENTIFIER '=' listtoken { parse_assign($2, &t); } '\n'
+ { ++yylineno; }
;
tokens:
- tokens token
- | token
+ tokens token { parse_token(&t); }
+ | token { parse_token(&t); }
;
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; }
+ | 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; }
+ ;
+
+list:
+ '(' listtokens ')' { $$ = $2; }
+ ;
+
+listtokens:
+ listtokens listtoken { ParseToken *nt = g_new(ParseToken, 1);
+ nt->type = t.type;
+ nt->data = t.data;
+ $$ = g_list_append($1, nt);
+ }
+ | listtoken { ParseToken *nt = g_new(ParseToken, 1);
+ nt->type = t.type;
+ nt->data = t.data;
+ $$ = g_list_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; }
;
+
%%
void yyerror(char *err) {