%define api.pure %glr-parser %skeleton "glr.c" %locations %debug %error-verbose %code requires { #include "theme.h" } %{ #include #include #include #include "theme.h" #include "lexer/theme-parser.h" ThemeWidget *rofi_theme = NULL; void yyerror(YYLTYPE *yylloc, const char* s); int yylex (YYSTYPE *, YYLTYPE *); %} %union { int ival; double fval; char *sval; int bval; ThemeColor colorval; ThemeWidget *theme; GList *name_path; Property *property; GHashTable *property_list; Distance distance; } %token T_INT %token T_DOUBLE %token T_STRING %token N_STRING %token T_POSITION; %token NAME_ELEMENT %token T_BOOLEAN %token T_COLOR %token T_PIXEL %token T_LINK %token FIRST_NAME %token BOPEN "bracket open"; %token BCLOSE "bracket close"; %token PSEP "property separator"; %token PCLOSE "property close"; %token NSEP "Name separator"; %token NAME_PREFIX "Name prefix"; %token WHITESPACE "White space"; %type entry %type pvalue %type entries %type start %type name_path %type state_path %type property %type property_list %type optional_properties %start start %% start: entries optional_properties { $$ = $1; rofi_theme_widget_add_properties ( $$, $2 ); } ; entries: %empty { // There is always a base widget. $$ = rofi_theme = (ThemeWidget*)g_malloc0 (sizeof(ThemeWidget)); rofi_theme->name = g_strdup ( "Root" ); } | entries optional_properties entry { $$ = $1; rofi_theme_widget_add_properties ( $$, $2); } ; entry: NAME_PREFIX name_path BOPEN optional_properties BCLOSE { ThemeWidget *widget = rofi_theme; for ( GList *iter = g_list_first ( $2 ); iter ; iter = g_list_next ( iter ) ) { widget = rofi_theme_find_or_create_name ( widget, iter->data ); } g_list_foreach ( $2, (GFunc)g_free , NULL ); g_list_free ( $2 ); widget->set = TRUE; rofi_theme_widget_add_properties ( widget, $4); }; /** * properties */ optional_properties : %empty { $$ = NULL; } | property_list { $$ = $1; } ; property_list: property { $$ = g_hash_table_new_full ( g_str_hash, g_str_equal, NULL, (GDestroyNotify)rofi_theme_property_free ); 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; $$->value.i = $3; } | pvalue PSEP T_DOUBLE PCLOSE { $$ = rofi_theme_property_create ( P_DOUBLE ); $$->name = $1; $$->value.f = $3; } | pvalue PSEP T_COLOR PCLOSE { $$ = rofi_theme_property_create ( P_COLOR ); $$->name = $1; $$->value.color = $3; } | pvalue PSEP T_STRING PCLOSE { $$ = rofi_theme_property_create ( P_STRING ); $$->name = $1; $$->value.s = $3; } | pvalue PSEP T_LINK PCLOSE { $$ = rofi_theme_property_create ( P_LINK ); $$->name = $1; $$->value.link.name = $3; } | pvalue PSEP T_BOOLEAN PCLOSE { $$ = rofi_theme_property_create ( P_BOOLEAN ); $$->name = $1; $$->value.b = $3; } | pvalue PSEP T_PIXEL PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $3, $3, $3 }; } | pvalue PSEP T_PIXEL T_PIXEL PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $3, $4 }; } | pvalue PSEP T_PIXEL T_PIXEL T_PIXEL PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $5, $4 }; } | pvalue PSEP T_PIXEL T_PIXEL T_PIXEL T_PIXEL PCLOSE { $$ = rofi_theme_property_create ( P_PADDING ); $$->name = $1; $$->value.padding = (Padding){ $3, $4, $5, $6 }; } | pvalue PSEP T_POSITION PCLOSE{ $$ = rofi_theme_property_create ( P_POSITION ); $$->name = $1; $$->value.i = $3; } ; pvalue: N_STRING { $$ = $1; } name_path: NAME_ELEMENT { $$ = g_list_append ( NULL, $1 );} | name_path NSEP NAME_ELEMENT { $$ = g_list_append ( $1, $3);} | name_path NSEP { $$ = $1; } ; %%