summaryrefslogtreecommitdiffstats
path: root/lexer
diff options
context:
space:
mode:
authorDave Davenport <qball@gmpclient.org>2016-12-12 23:40:43 +0100
committerDave Davenport <qball@gmpclient.org>2016-12-12 23:40:43 +0100
commitfd64bb7a41bf72ad19df772a2cae336ded484b87 (patch)
tree5639f393cdf04df82b87efe123e4fe7f09b1dbe0 /lexer
parentbe0677cf498aa885a6203fcd0c21c315ad1face3 (diff)
Improve lexer by adding support for modes.
Diffstat (limited to 'lexer')
-rw-r--r--lexer/theme-lexer.l40
-rw-r--r--lexer/theme-parser.y34
2 files changed, 45 insertions, 29 deletions
diff --git a/lexer/theme-lexer.l b/lexer/theme-lexer.l
index a540c229..a645138a 100644
--- a/lexer/theme-lexer.l
+++ b/lexer/theme-lexer.l
@@ -22,6 +22,9 @@ WORD [_\-a-zA-Z0-9]+
STRING [ \t_\-a-zA-Z0-9]+
HEX [0-9a-fA-F]
NUMBER [0-9]
+
+%x PROPERTIES
+%x NAMESTR
%%
%{
@@ -64,20 +67,24 @@ YY_LLOC_START
}
"\{" { return BOPEN;}
-"\}" { return BCLOSE;}
-":" { return PSEP; }
-";" { return PCLOSE;}
-"." { return NSEP; }
-"#" { return NAME_PREFIX;}
-(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;}
-{NUMBER}+ { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;}
-{NUMBER}+\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;}
-@{WORD} { yylval->sval = g_strdup(yytext); return CLASS_NAME; }
+"@" { BEGIN(NAMESTR);return CLASS_PREFIX;}
+"#" { BEGIN(NAMESTR);return NAME_PREFIX;}
+"\}" { return BCLOSE;}
+<INITIAL,NAMESTR>"." { return NSEP; }
{WORD} { yylval->sval = g_strdup(yytext); return N_STRING;}
-{WHITESPACE} ; // ignore all whitespace
-\"{STRING}\" { yytext[yyleng-1] = '\0'; yylval->sval = g_strdup(&yytext[1]); return T_STRING;}
+<NAMESTR>{WORD} { yylval->sval = g_strdup(yytext); return NAME_ELEMENT;}
+
+<NAMESTR>{WHITESPACE} { BEGIN(INITIAL);}
+<INITIAL>{WHITESPACE}+ ; // ignore all whitespace
+<PROPERTIES>{WHITESPACE}+ ; // ignore all whitespace
-#{HEX}{8} {
+":" { BEGIN(PROPERTIES); return PSEP; }
+<PROPERTIES>";" { BEGIN(0); return PCLOSE;}
+<PROPERTIES>(true|false) { yylval->bval= g_strcmp0(yytext, "true") == 0; return T_BOOLEAN;}
+<PROPERTIES>{NUMBER}+ { yylval->ival = (int)g_ascii_strtoll(yytext, NULL, 10); return T_INT;}
+<PROPERTIES>{NUMBER}+\.{NUMBER}+ { yylval->fval = g_ascii_strtod(yytext, NULL); return T_DOUBLE;}
+<PROPERTIES>\"{STRING}\" { yytext[yyleng-1] = '\0'; yylval->sval = g_strdup(&yytext[1]); return T_STRING;}
+<PROPERTIES>#{HEX}{8} {
union { unsigned int val; struct { unsigned char b,g,r,a;};} val;
val.val = (unsigned int)strtoull ( &yytext[1], NULL, 16);
yylval->colorval.alpha = val.a/255.0;
@@ -86,7 +93,7 @@ YY_LLOC_START
yylval->colorval.blue = val.b/255.0;
return T_COLOR;
}
-#{HEX}{6} {
+<PROPERTIES>#{HEX}{6} {
union { unsigned int val; struct { unsigned char b,g,r,a;};} val;
val.val = (unsigned int)g_ascii_strtoull ( &yytext[1], NULL, 16);
yylval->colorval.alpha = 1.0;
@@ -95,7 +102,7 @@ YY_LLOC_START
yylval->colorval.blue = val.b/255.0;
return T_COLOR;
}
-rgba\({NUMBER}{1,3},{NUMBER}{1,3},{NUMBER}{1,3},[01](\.{NUMBER}+)?\) {
+<PROPERTIES>rgba\({NUMBER}{1,3},{NUMBER}{1,3},{NUMBER}{1,3},[01](\.{NUMBER}+)?\) {
char *endptr = &yytext[5];
yylval->colorval.red = g_ascii_strtoull ( endptr, &endptr, 10);
yylval->colorval.green= g_ascii_strtoull ( endptr+1, &endptr, 10);
@@ -103,7 +110,7 @@ rgba\({NUMBER}{1,3},{NUMBER}{1,3},{NUMBER}{1,3},[01](\.{NUMBER}+)?\) {
yylval->colorval.alpha= g_ascii_strtod ( endptr+1, NULL);
return T_COLOR;
}
-rgb\({NUMBER}{1,3},{NUMBER}{1,3},{NUMBER}{1,3}\) {
+<PROPERTIES>rgb\({NUMBER}{1,3},{NUMBER}{1,3},{NUMBER}{1,3}\) {
char *endptr = &yytext[4];
yylval->colorval.red = g_ascii_strtoull ( endptr, &endptr, 10);
yylval->colorval.green = g_ascii_strtoull ( endptr+1, &endptr, 10);
@@ -111,7 +118,8 @@ rgb\({NUMBER}{1,3},{NUMBER}{1,3},{NUMBER}{1,3}\) {
yylval->colorval.alpha = 1.0;
return T_COLOR;
}
-(\r\n|\n) {
+
+<*>(\r\n|\n) {
yylloc->last_column = 1;
yylloc->last_line ++;
};
diff --git a/lexer/theme-parser.y b/lexer/theme-parser.y
index aa82cdcf..468691ac 100644
--- a/lexer/theme-parser.y
+++ b/lexer/theme-parser.y
@@ -1,5 +1,5 @@
%define api.pure
-%glr-parser
+%glr-parser
%skeleton "glr.c"
%locations
%debug
@@ -36,9 +36,11 @@ int yylex (YYSTYPE *, YYLTYPE *);
%token <fval> T_DOUBLE
%token <sval> T_STRING
%token <sval> N_STRING
+%token <sval> NAME_ELEMENT
%token <bval> T_BOOLEAN
%token <colorval> T_COLOR
%token <sval> CLASS_NAME
+%token <sval> FIRST_NAME
%token BOPEN "bracket open";
%token BCLOSE "bracket close";
@@ -46,10 +48,12 @@ int yylex (YYSTYPE *, YYLTYPE *);
%token PCLOSE "property close";
%token NSEP "Name separator";
%token CLASS_PREFIX "Class prefix";
-%token NAME_PREFIX "Name prefix";
+%token NAME_PREFIX "Name prefix";
+%token WHITESPACE "White space";
%type <sval> entry
%type <sval> pvalue
+%type <sval> class_name
%type <theme> entries
%type <theme> start
%type <name_path> name_path
@@ -80,23 +84,26 @@ entries:
;
entry:
-CLASS_NAME state_path BOPEN optional_properties BCLOSE
+CLASS_PREFIX class_name state_path BOPEN optional_properties BCLOSE
{
- Widget *widget = rofi_theme_find_or_create_class ( rofi_theme , $1 );
- for ( GList *iter = g_list_first ( $2 ); iter ; iter = g_list_next ( iter ) ) {
+ gchar *classn = g_strconcat ( "@", $2, NULL);
+ Widget *widget = rofi_theme_find_or_create_class ( rofi_theme , classn );
+ g_free(classn);
+ for ( GList *iter = g_list_first ( $3 ); iter ; iter = g_list_next ( iter ) ) {
widget = rofi_theme_find_or_create_class ( widget, iter->data );
}
- g_list_foreach ( $2, (GFunc)g_free , NULL );
- g_list_free ( $2 );
+ g_list_foreach ( $3, (GFunc)g_free , NULL );
+ g_list_free ( $3 );
+ widget->set = TRUE;
if ( widget->properties != NULL ) {
fprintf(stderr, "Properties already set on this widget.\n");
exit ( EXIT_FAILURE );
}
- widget->properties = $4;
+ widget->properties = $5;
}
| NAME_PREFIX name_path state_path BOPEN optional_properties BCLOSE
{
- Widget *widget = rofi_theme;
+ Widget *widget = rofi_theme;
for ( GList *iter = g_list_first ( $2 ); iter ; iter = g_list_next ( iter ) ) {
widget = rofi_theme_find_or_create_class ( widget, iter->data );
}
@@ -107,6 +114,7 @@ CLASS_NAME state_path BOPEN optional_properties BCLOSE
}
g_list_foreach ( $3, (GFunc)g_free , NULL );
g_list_free ( $3 );
+ widget->set = TRUE;
if ( widget->properties != NULL ) {
fprintf(stderr, "Properties already set on this widget.\n");
exit ( EXIT_FAILURE );
@@ -162,16 +170,16 @@ property
;
pvalue: N_STRING { $$ = $1; }
+class_name: NAME_ELEMENT {$$ = $1;}
name_path:
- %empty { $$ = NULL; }
-| N_STRING { $$ = g_list_append ( NULL, $1 );}
-| name_path NSEP N_STRING { $$ = g_list_append ( $1, $3);}
+NAME_ELEMENT { $$ = g_list_append ( NULL, $1 );}
+| name_path NSEP NAME_ELEMENT { $$ = g_list_append ( $1, $3);}
;
state_path:
%empty { $$ = NULL; }
-| N_STRING { $$ = g_list_append ( NULL, $1 );}
+| N_STRING { $$ = g_list_append ( NULL, $1 );}
| state_path NSEP N_STRING { $$ = g_list_append ( $1, $3);}
;