summaryrefslogtreecommitdiffstats
path: root/scripts/kconfig/zconf.y
diff options
context:
space:
mode:
authorMasahiro Yamada <yamada.masahiro@socionext.com>2018-12-11 12:00:49 +0100
committerMasahiro Yamada <yamada.masahiro@socionext.com>2018-12-12 16:18:54 +0100
commitcc66bca775eeb81ef24456338bcd97e2e780c236 (patch)
tree00309c147f287d6706e31a08b211ad4697997533 /scripts/kconfig/zconf.y
parentkconfig: refactor pattern matching in STRING state (diff)
downloadlinux-cc66bca775eeb81ef24456338bcd97e2e780c236.tar.xz
linux-cc66bca775eeb81ef24456338bcd97e2e780c236.zip
kconfig: fix ambiguous grammar in terms of new lines
This commit decreases 8 shift/reduce conflicts. A certain amount of grammatical ambiguity comes from how to reduce excessive T_EOL tokens. Let's take a look at the example code below: 1 config A 2 bool "a" 3 4 depends on B 5 6 config B 7 def_bool y The line 3 is melt into "config_option_list", but the line 5 can be either a part of "config_option_list" or "common_stmt" by itself. Currently, the lexer converts '\n' to T_EOL verbatim. In Kconfig, a new line works as a statement terminator, but new lines in empty lines are not critical since empty lines (or lines that contain only whitespaces/comments) are just no-op. If the lexer simply discards no-op lines, the parser will not be bothered by excessive T_EOL tokens. Of course, this means we are shifting the complexity from the parser to the lexer, but it is much easier than tackling on shift/reduce conflicts. I introduced the second stage lexer to tweak the behavior. Discard T_EOL if the previous token is T_EOL or T_HELPTEXT. Two T_EOL tokens in a row is meaningless. T_HELPTEXT is a special token that is reduced without T_EOL. Signed-off-by: Masahiro Yamada <yamada.masahiro@socionext.com>
Diffstat (limited to '')
-rw-r--r--scripts/kconfig/zconf.y18
1 files changed, 3 insertions, 15 deletions
diff --git a/scripts/kconfig/zconf.y b/scripts/kconfig/zconf.y
index c28f1a8f721d..02bfc62ba92c 100644
--- a/scripts/kconfig/zconf.y
+++ b/scripts/kconfig/zconf.y
@@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE];
static struct menu *current_menu, *current_entry;
%}
-%expect 29
+%expect 21
%union
{
@@ -111,9 +111,7 @@ static struct menu *current_menu, *current_entry;
%}
%%
-input: nl start | start;
-
-start: mainmenu_stmt stmt_list | stmt_list;
+input: mainmenu_stmt stmt_list | stmt_list;
/* mainmenu entry */
@@ -141,8 +139,7 @@ option_name:
;
common_stmt:
- T_EOL
- | if_stmt
+ if_stmt
| comment_stmt
| config_stmt
| menuconfig_stmt
@@ -193,7 +190,6 @@ config_option_list:
| config_option_list depends
| config_option_list help
| config_option_list option_error
- | config_option_list T_EOL
;
config_option: T_TYPE prompt_stmt_opt T_EOL
@@ -293,7 +289,6 @@ choice_option_list:
| choice_option_list choice_option
| choice_option_list depends
| choice_option_list help
- | choice_option_list T_EOL
| choice_option_list option_error
;
@@ -443,7 +438,6 @@ help: help_start T_HELPTEXT
depends_list:
/* empty */
| depends_list depends
- | depends_list T_EOL
| depends_list option_error
;
@@ -458,7 +452,6 @@ depends: T_DEPENDS T_ON expr T_EOL
visibility_list:
/* empty */
| visibility_list visible
- | visibility_list T_EOL
;
visible: T_VISIBLE if_expr T_EOL
@@ -484,11 +477,6 @@ end: T_ENDMENU T_EOL { $$ = $1; }
| T_ENDIF T_EOL { $$ = $1; }
;
-nl:
- T_EOL
- | nl T_EOL
-;
-
if_expr: /* empty */ { $$ = NULL; }
| T_IF expr { $$ = $2; }
;