commit 7d3286caede96d7b813eff7dc3691d683d0f9bf9 from: Omar Polo date: Thu Oct 01 09:52:58 2020 UTC reworked the tokenizer -- breaking change The parser was pratically rewritten. Strings now are required to be quoted with single quotes, while keys (still) requires double quotes. In addition, the * is no longer a valid match argument: to match on everything you need to use the special keyword `all'. match all # before was `match *' on "C-a" do "" # unchanged match class 'Firefox' # before was `match class Firefox' # ... commit - e0041ee5139dcd4173fe8f47ff691c0d41951341 commit + 7d3286caede96d7b813eff7dc3691d683d0f9bf9 blob - 943a39c29b407715da6bf55e5a0d43d66ee83837 blob + 92aadc8434cd61b0831ea6b5c8170b9d8713e985 --- lex.l +++ lex.l @@ -1,4 +1,4 @@ -/* -*- mode:fundamental; indent-tabs-mode: t; -*- */ +/* -*- mode:c; indent-tabs-mode: t; -*- */ %{ /* @@ -34,77 +34,78 @@ KeySym key = 0; %x COMMENT %x KEY +%x STRING %% -"#" { BEGIN(COMMENT); } -\n { yylineno++; BEGIN(INITIAL); } -. ; +# BEGIN(COMMENT); +.*\n yylineno++; BEGIN(INITIAL); return '\n'; -[ \t\r\v\f]+ ; +\" BEGIN(KEY); +\" { + BEGIN(INITIAL); + yylval.key = (struct key){ state, key }; + state = 0; + key = 0; + return TKEY; + } -"match" return TMATCH; -"class" return TCLASS; -"on" return TON; -"do" return TDO; -"toggle" return TTOGGLE; -"activate" return TACTIVATE; -"deactivate" return TDEACTIVATE; -"ignore" return TIGNORE; +C- state |= ControlMask; +S- state |= ShiftMask; +M- state |= Mod1Mask; +s- state |= Mod4Mask; -"\n" yylineno++; return '\n'; -"*" return '*'; +<[^>]+> { + char *c; -[-a-zA-Z0-9]+ { - char *ident; - if ((ident = strdup(yytext)) == NULL) - err(1, "strdup"); - yylval.str = ident; - return TSTRING; - } + if ((c = strdup(yytext)) == NULL) + err(1, "strdup"); -"\"" { BEGIN(KEY); } -"\"" { - BEGIN(INITIAL); + c++; /* skip the < */ + c[strlen(c)-1] = '\0'; /* trim the > */ - yylval.key = (struct key){ state, key }; - state = 0; - key = 0; - return TKEY; - } + if ((key = XStringToKeysym(c)) == NoSymbol) + yyerror("invalid keysym %s", c); -C- { state |= ControlMask; } -S- { state |= ShiftMask; } -M- { state |= Mod1Mask; } -s- { state |= Mod4Mask; } + free(--c); + } -<[^>]+> { - char *c; +SPC key = XK_space; +RET key = XK_Return; - if ((c = strdup(yytext)) == NULL) - err(1, "strdup"); +"(" key = XK_parenleft; +")" key = XK_parenright; - c++; /* skip the < */ - c[strlen(c)-1] = '\0'; /* trim the > */ +. { + if ((key = XStringToKeysym(yytext)) == NoSymbol) + yyerror("invalid key %s", yytext); + } - if ((key = XStringToKeysym(c)) == NoSymbol) - yyerror("invalid keysym %s", c); +\' BEGIN(STRING); +[^']*\' { + if ((yylval.str = strdup(yytext)) == NULL) + err(1, "strdup"); + yylval.str[strlen(yylval.str)-1] = '\0'; /* remove the closing quote */ + BEGIN(INITIAL); + return TSTRING; + } - free(--c); - } +match return TMATCH; +class return TCLASS; +on return TON; +do return TDO; +toggle return TTOGGLE; +activate return TACTIVATE; +deactivate return TDEACTIVATE; +ignore return TIGNORE; +exec return TEXEC; +all return TALL; -SPC { key = XK_space; } -RET { key = XK_Return; } +\n yylineno++; return '\n'; +[ \r\t\f]+ -"(" { key = XK_parenleft; } -")" { key = XK_parenright; } +. return TERR; -. { - if ((key = XStringToKeysym(yytext)) == NoSymbol) - yyerror("invalid key %s", yytext); - } - - %% int blob - 32657d48a66e7b0a1bac2addbf2a5e8efdcbe614 blob + 68bb6d1db282d70709de7d07b094a10d72e3aa5a --- parse.y +++ parse.y @@ -41,7 +41,7 @@ struct group *group; } -%token TMATCH TCLASS +%token TMATCH TCLASS TALL %token TON TDO %token TTOGGLE TACTIVATE TDEACTIVATE TIGNORE TEXEC %token TERR @@ -69,7 +69,7 @@ matches : /* empty */ { $$ = NULL; } | matches match '\n' { $2->next = $1; $$ = $2; } ; -match : TMATCH '*' { $$ = new_match(MANY, NULL); } +match : TMATCH TALL { $$ = new_match(MANY, NULL); } | TMATCH TCLASS TSTRING { $$ = new_match(MCLASS, $3); } ;