From 08f64f011d00da966b474d4f93f7f55b78387fb7 Mon Sep 17 00:00:00 2001 From: Michael Stapelberg Date: Sun, 22 May 2011 21:26:50 +0200 Subject: [PATCH] cleanup cmdparse lexer/parser (ignore whitespace, solves conflicts) --- src/cmdparse.l | 34 +++++++----- src/cmdparse.y | 148 ++++++++++++++++++++++--------------------------- 2 files changed, 87 insertions(+), 95 deletions(-) diff --git a/src/cmdparse.l b/src/cmdparse.l index 6e33c950..1c71ed38 100644 --- a/src/cmdparse.l +++ b/src/cmdparse.l @@ -30,14 +30,20 @@ int cmdyycolumn = 1; cmdyycolumn += yyleng; \ } +/* macro to first eat whitespace, then expect a string */ +#define WS_STRING do { \ + yy_push_state(WANT_STRING); \ + yy_push_state(EAT_WHITESPACE); \ +} while (0) + %} EOL (\r?\n) /* handle everything up to \n as a string */ %s WANT_STRING -/* first expect a whitespace, then a string */ -%s WANT_WS_STRING +/* eat a whitespace, then go to the next state on the stack */ +%s EAT_WHITESPACE /* handle a quoted string or everything up to the next whitespace */ %s WANT_QSTRING @@ -65,7 +71,6 @@ EOL (\r?\n) cmdyycolumn = 1; } -[ \t]* { BEGIN(WANT_STRING); return WHITESPACE; } \"[^\"]+\" { BEGIN(INITIAL); /* strip quotes */ @@ -73,21 +78,24 @@ EOL (\r?\n) copy[strlen(copy)-1] = '\0'; cmdyylval.string = copy; return STR; - } -\"[^\"]+\" { + } +\"[^\"]+\" { BEGIN(INITIAL); /* strip quotes */ char *copy = sstrdup(yytext+1); copy[strlen(copy)-1] = '\0'; cmdyylval.string = copy; return STR; - } + } -[^;\n]+ { BEGIN(INITIAL); cmdyylval.string = sstrdup(yytext); return STR; } +[^;\n]+ { BEGIN(INITIAL); cmdyylval.string = sstrdup(yytext); return STR; } -[ \t]* { return WHITESPACE; } +[;\n] { BEGIN(INITIAL); return ';'; } +[ \t]* { yy_pop_state(); } + +[ \t]* { /* ignore whitespace */ ; } attach { return TOK_ATTACH; } -exec { BEGIN(WANT_WS_STRING); return TOK_EXEC; } +exec { WS_STRING; return TOK_EXEC; } exit { return TOK_EXIT; } reload { return TOK_RELOAD; } restart { return TOK_RESTART; } @@ -109,7 +117,7 @@ mode { return TOK_MODE; } tiling { return TOK_TILING; } floating { return TOK_FLOATING; } toggle { return TOK_TOGGLE; } -workspace { BEGIN(WANT_WS_STRING); return TOK_WORKSPACE; } +workspace { WS_STRING; return TOK_WORKSPACE; } focus { return TOK_FOCUS; } move { return TOK_MOVE; } open { return TOK_OPEN; } @@ -129,9 +137,9 @@ grow { return TOK_GROW; } px { return TOK_PX; } or { return TOK_OR; } ppt { return TOK_PPT; } -nop { BEGIN(WANT_WS_STRING); return TOK_NOP; } -restore { BEGIN(WANT_WS_STRING); return TOK_RESTORE; } -mark { BEGIN(WANT_WS_STRING); return TOK_MARK; } +nop { WS_STRING; return TOK_NOP; } +restore { WS_STRING; return TOK_RESTORE; } +mark { WS_STRING; return TOK_MARK; } class { BEGIN(WANT_QSTRING); return TOK_CLASS; } id { BEGIN(WANT_QSTRING); return TOK_ID; } diff --git a/src/cmdparse.y b/src/cmdparse.y index bc4858f2..b247d59b 100644 --- a/src/cmdparse.y +++ b/src/cmdparse.y @@ -106,7 +106,6 @@ char *parse_cmd(const char *new) { %} -%expect 5 %error-verbose %lex-param { struct context *context } @@ -116,7 +115,6 @@ char *parse_cmd(const char *new) { int number; } -%token TOK_ATTACH "attach" %token TOK_EXEC "exec" %token TOK_EXIT "exit" %token TOK_RELOAD "reload" @@ -166,7 +164,6 @@ char *parse_cmd(const char *new) { %token TOK_ID "id" %token TOK_CON_ID "con_id" -%token WHITESPACE "" %token STR "" %token NUMBER "" @@ -183,7 +180,7 @@ char *parse_cmd(const char *new) { %% commands: - commands optwhitespace ';' optwhitespace command + commands ';' command | command { owindow *current; @@ -198,16 +195,12 @@ commands: } ; -optwhitespace: - | WHITESPACE - ; - command: - match optwhitespace operations + match operations ; match: - | matchstart optwhitespace criteria optwhitespace matchend + | matchstart criteria matchend { printf("match parsed\n"); } @@ -322,8 +315,8 @@ criteria: ; operations: - operation optwhitespace - | operations ',' optwhitespace operation + operation + | operations ',' operation ; operation: @@ -336,7 +329,6 @@ operation: | restore | move | workspace - | attach | focus | kill | open @@ -352,11 +344,11 @@ operation: ; exec: - TOK_EXEC WHITESPACE STR + TOK_EXEC STR { - printf("should execute %s\n", $3); - start_application($3); - free($3); + printf("should execute %s\n", $2); + start_application($2); + free($2); } ; @@ -387,13 +379,6 @@ restart: } ; -attach: - TOK_ATTACH - { - printf("should attach\n"); - } - ; - focus: TOK_FOCUS { @@ -436,17 +421,16 @@ kill: optional_kill_mode: /* empty */ { $$ = KILL_WINDOW; } - | WHITESPACE { $$ = KILL_WINDOW; } - | WHITESPACE TOK_WINDOW { $$ = KILL_WINDOW; } - | WHITESPACE TOK_CLIENT { $$ = KILL_CLIENT; } + | TOK_WINDOW { $$ = KILL_WINDOW; } + | TOK_CLIENT { $$ = KILL_CLIENT; } ; workspace: - TOK_WORKSPACE WHITESPACE STR + TOK_WORKSPACE STR { - printf("should switch to workspace %s\n", $3); - workspace_show($3); - free($3); + printf("should switch to workspace %s\n", $2); + workspace_show($2); + free($2); } ; @@ -477,29 +461,29 @@ fullscreen: ; next: - TOK_NEXT WHITESPACE direction + TOK_NEXT direction { /* TODO: use matches */ - printf("should select next window in direction %c\n", $3); - tree_next('n', ($3 == 'v' ? VERT : HORIZ)); + printf("should select next window in direction %c\n", $2); + tree_next('n', ($2 == 'v' ? VERT : HORIZ)); } ; prev: - TOK_PREV WHITESPACE direction + TOK_PREV direction { /* TODO: use matches */ - printf("should select prev window in direction %c\n", $3); - tree_next('p', ($3 == 'v' ? VERT : HORIZ)); + printf("should select prev window in direction %c\n", $2); + tree_next('p', ($2 == 'v' ? VERT : HORIZ)); } ; split: - TOK_SPLIT WHITESPACE direction + TOK_SPLIT direction { /* TODO: use matches */ - printf("splitting in direction %c\n", $3); - tree_split(focused, ($3 == 'v' ? VERT : HORIZ)); + printf("splitting in direction %c\n", $2); + tree_split(focused, ($2 == 'v' ? VERT : HORIZ)); } ; @@ -511,19 +495,19 @@ direction: ; mode: - TOK_MODE WHITESPACE window_mode + TOK_MODE window_mode { HANDLE_EMPTY_MATCH; owindow *current; TAILQ_FOREACH(current, &owindows, owindows) { printf("matching: %p / %s\n", current->con, current->con->name); - if ($3 == TOK_TOGGLE) { + if ($2 == TOK_TOGGLE) { printf("should toggle mode\n"); toggle_floating_mode(current->con, false); } else { - printf("should switch mode to %s\n", ($3 == TOK_FLOATING ? "floating" : "tiling")); - if ($3 == TOK_FLOATING) { + printf("should switch mode to %s\n", ($2 == TOK_FLOATING ? "floating" : "tiling")); + if ($2 == TOK_FLOATING) { floating_enable(current->con, false); } else { floating_disable(current->con, false); @@ -540,16 +524,16 @@ window_mode: ; border: - TOK_BORDER WHITESPACE border_style + TOK_BORDER border_style { - printf("border style should be changed to %d\n", $3); + printf("border style should be changed to %d\n", $2); owindow *current; HANDLE_EMPTY_MATCH; TAILQ_FOREACH(current, &owindows, owindows) { printf("matching: %p / %s\n", current->con, current->con->name); - current->con->border_style = $3; + current->con->border_style = $2; } } ; @@ -562,10 +546,10 @@ border_style: level: - TOK_LEVEL WHITESPACE level_direction + TOK_LEVEL level_direction { - printf("level %c\n", $3); - if ($3 == 'u') + printf("level %c\n", $2); + if ($2 == 'u') level_up(); else level_down(); } @@ -577,19 +561,19 @@ level_direction: ; move: - TOK_MOVE WHITESPACE direction + TOK_MOVE direction { - printf("moving in direction %d\n", $3); - tree_move($3); + printf("moving in direction %d\n", $2); + tree_move($2); } - | TOK_MOVE WHITESPACE TOK_WORKSPACE WHITESPACE STR + | TOK_MOVE TOK_WORKSPACE STR { owindow *current; - printf("should move window to workspace %s\n", $5); + printf("should move window to workspace %s\n", $3); /* get the workspace */ - Con *ws = workspace_get($5, NULL); - free($5); + Con *ws = workspace_get($3, NULL); + free($3); HANDLE_EMPTY_MATCH; @@ -601,27 +585,27 @@ move: ; restore: - TOK_RESTORE WHITESPACE STR + TOK_RESTORE STR { - printf("restoring \"%s\"\n", $3); - tree_append_json($3); - free($3); + printf("restoring \"%s\"\n", $2); + tree_append_json($2); + free($2); } ; layout: - TOK_LAYOUT WHITESPACE layout_mode + TOK_LAYOUT layout_mode { - printf("changing layout to %d\n", $3); + printf("changing layout to %d\n", $2); owindow *current; /* check if the match is empty, not if the result is empty */ if (match_is_empty(¤t_match)) - con_set_layout(focused->parent, $3); + con_set_layout(focused->parent, $2); else { TAILQ_FOREACH(current, &owindows, owindows) { printf("matching: %p / %s\n", current->con, current->con->name); - con_set_layout(current->con, $3); + con_set_layout(current->con, $2); } } } @@ -634,41 +618,41 @@ layout_mode: ; mark: - TOK_MARK WHITESPACE STR + TOK_MARK STR { - printf("marking window with str %s\n", $3); + printf("marking window with str %s\n", $2); owindow *current; HANDLE_EMPTY_MATCH; TAILQ_FOREACH(current, &owindows, owindows) { printf("matching: %p / %s\n", current->con, current->con->name); - current->con->mark = sstrdup($3); + current->con->mark = sstrdup($2); } - free($3); + free($2); } ; nop: - TOK_NOP WHITESPACE STR + TOK_NOP STR { printf("-------------------------------------------------\n"); - printf(" NOP: %s\n", $3); + printf(" NOP: %s\n", $2); printf("-------------------------------------------------\n"); - free($3); + free($2); } ; resize: - TOK_RESIZE WHITESPACE resize_way WHITESPACE direction resize_px resize_tiling + TOK_RESIZE resize_way direction resize_px resize_tiling { /* resize [ px] [or ppt] */ - printf("resizing in way %d, direction %d, px %d or ppt %d\n", $3, $5, $6, $7); - int direction = $5; - int px = $6; - int ppt = $7; - if ($3 == TOK_SHRINK) { + printf("resizing in way %d, direction %d, px %d or ppt %d\n", $2, $3, $4, $5); + int direction = $3; + int px = $4; + int ppt = $5; + if ($2 == TOK_SHRINK) { px *= -1; ppt *= -1; } @@ -723,9 +707,9 @@ resize_px: { $$ = 10; } - | WHITESPACE NUMBER WHITESPACE TOK_PX + | NUMBER TOK_PX { - $$ = $2; + $$ = $1; } ; @@ -734,9 +718,9 @@ resize_tiling: { $$ = 10; } - | WHITESPACE TOK_OR WHITESPACE NUMBER WHITESPACE TOK_PPT + | TOK_OR NUMBER TOK_PPT { - $$ = $4; + $$ = $2; } ;