diff options
author | Dave Davenport <qball@gmpclient.org> | 2016-12-12 23:40:43 +0100 |
---|---|---|
committer | Dave Davenport <qball@gmpclient.org> | 2016-12-12 23:40:43 +0100 |
commit | fd64bb7a41bf72ad19df772a2cae336ded484b87 (patch) | |
tree | 5639f393cdf04df82b87efe123e4fe7f09b1dbe0 /lexer | |
parent | be0677cf498aa885a6203fcd0c21c315ad1face3 (diff) |
Improve lexer by adding support for modes.
Diffstat (limited to 'lexer')
-rw-r--r-- | lexer/theme-lexer.l | 40 | ||||
-rw-r--r-- | lexer/theme-parser.y | 34 |
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);} ; |