rofi/lexer/theme-parser.y

152 lines
3.3 KiB
Plaintext
Raw Normal View History

%glr-parser
%skeleton "glr.c"
2016-12-09 18:49:49 +00:00
%locations
%debug
%error-verbose
%code requires {
#include "theme.h"
}
%{
#include <stdio.h>
#include <stdlib.h>
void yyerror(const char* s);
int yylex (void );
#include "theme.h"
Widget *rofi_theme = NULL;
%}
%union {
int ival;
double fval;
char *sval;
int bval;
2016-12-10 18:48:44 +00:00
ThemeColor colorval;
2016-12-09 18:49:49 +00:00
Widget *theme;
GList *name_path;
Property *property;
GHashTable *property_list;
}
%token <ival> T_INT
2016-12-09 21:16:31 +00:00
%token <fval> T_DOUBLE
2016-12-09 18:49:49 +00:00
%token <sval> T_STRING
%token <sval> N_STRING
%token <bval> T_BOOLEAN
%token <colorval> T_COLOR
%token BOPEN "bracket open";
%token BCLOSE "bracket close";
%token PSEP "property separator";
%token PCLOSE "property close";
%token NSEP "Name separator";
2016-12-09 21:16:31 +00:00
%type <sval> entry
2016-12-09 18:49:49 +00:00
%type <sval> pvalue
2016-12-09 21:16:31 +00:00
%type <theme> entries
%type <theme> start
2016-12-09 18:49:49 +00:00
%type <name_path> name_path
%type <property> property
%type <property_list> property_list
%type <property_list> optional_properties
2016-12-09 21:16:31 +00:00
%start start
2016-12-09 18:49:49 +00:00
%%
start:
optional_properties
2016-12-09 21:16:31 +00:00
entries {
2016-12-09 18:49:49 +00:00
$$ = $2;
if ( $1 != NULL ) {
$$->properties = $1;
}
}
;
entries:
2016-12-09 21:16:31 +00:00
%empty {
2016-12-09 18:49:49 +00:00
// There is always a base widget.
$$ = rofi_theme = (Widget*)g_malloc0 (sizeof(Widget));
rofi_theme->name = g_strdup ( "Window" );
}
| entries entry { $$ = $1; }
;
entry:
name_path BOPEN optional_properties BCLOSE
2016-12-09 18:49:49 +00:00
{
Widget *widget = rofi_theme;//rofi_theme_find_or_create_class ( rofi_theme , $1 );
for ( GList *iter = g_list_first ( $1 ); iter ; iter = g_list_next ( iter ) ) {
2016-12-09 21:16:31 +00:00
widget = rofi_theme_find_or_create_class ( widget, iter->data );
2016-12-09 18:49:49 +00:00
}
g_list_foreach ( $1, (GFunc)g_free , NULL );
g_list_free ( $1 );
2016-12-09 18:49:49 +00:00
if ( widget->properties != NULL ) {
fprintf(stderr, "Properties already set on this widget.\n");
exit ( EXIT_FAILURE );
}
widget->properties = $3;
};
/**
* properties
*/
optional_properties
: %empty { $$ = NULL; }
| property_list { $$ = $1; }
2016-12-09 21:16:31 +00:00
;
2016-12-09 18:49:49 +00:00
2016-12-09 21:16:31 +00:00
property_list:
2016-12-09 18:49:49 +00:00
property {
2016-12-09 21:16:31 +00:00
$$ = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)rofi_theme_property_free );
2016-12-09 18:49:49 +00:00
g_hash_table_replace ( $$, $1->name, $1 );
}
| property_list property {
// Old will be free'ed, and key/value will be replaced.
g_hash_table_replace ( $$, $2->name, $2 );
}
;
property
: pvalue PSEP T_INT PCLOSE {
$$ = rofi_theme_property_create ( P_INTEGER );
$$->name = $1;
2016-12-09 21:16:31 +00:00
$$->value.i = $3;
2016-12-09 18:49:49 +00:00
}
2016-12-09 21:16:31 +00:00
| pvalue PSEP T_DOUBLE PCLOSE {
$$ = rofi_theme_property_create ( P_DOUBLE );
2016-12-09 18:49:49 +00:00
$$->name = $1;
2016-12-09 21:16:31 +00:00
$$->value.f = $3;
2016-12-09 18:49:49 +00:00
}
2016-12-09 21:16:31 +00:00
| pvalue PSEP T_COLOR PCLOSE {
2016-12-09 18:49:49 +00:00
$$ = rofi_theme_property_create ( P_COLOR );
$$->name = $1;
2016-12-09 21:16:31 +00:00
$$->value.color = $3;
2016-12-09 18:49:49 +00:00
}
2016-12-09 21:16:31 +00:00
| pvalue PSEP T_STRING PCLOSE {
2016-12-09 18:49:49 +00:00
$$ = rofi_theme_property_create ( P_STRING );
$$->name = $1;
2016-12-09 21:16:31 +00:00
$$->value.s = $3;
2016-12-09 18:49:49 +00:00
}
| pvalue PSEP T_BOOLEAN PCLOSE {
$$ = rofi_theme_property_create ( P_BOOLEAN );
$$->name = $1;
2016-12-09 21:16:31 +00:00
$$->value.b = $3;
2016-12-09 18:49:49 +00:00
}
;
pvalue: N_STRING { $$ = $1; }
name_path:
%empty { $$ = NULL; }
| N_STRING { $$ = g_list_append ( NULL, $1 );}
2016-12-09 21:16:31 +00:00
| name_path NSEP N_STRING { $$ = g_list_append ( $1, $3);}
2016-12-09 18:49:49 +00:00
;
%%