mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-27 09:02:06 +00:00
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>
This commit is contained in:
parent
21c5ecf604
commit
cc66bca775
2 changed files with 24 additions and 15 deletions
|
@ -16,6 +16,8 @@
|
||||||
|
|
||||||
#include "lkc.h"
|
#include "lkc.h"
|
||||||
|
|
||||||
|
#define YY_DECL static int yylex1(void)
|
||||||
|
|
||||||
#define START_STRSIZE 16
|
#define START_STRSIZE 16
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
|
@ -23,6 +25,7 @@ static struct {
|
||||||
int lineno;
|
int lineno;
|
||||||
} current_pos;
|
} current_pos;
|
||||||
|
|
||||||
|
static int prev_token = T_EOL;
|
||||||
static char *text;
|
static char *text;
|
||||||
static int text_size, text_asize;
|
static int text_size, text_asize;
|
||||||
|
|
||||||
|
@ -268,6 +271,24 @@ n [A-Za-z0-9_-]
|
||||||
}
|
}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
/* second stage lexer */
|
||||||
|
int yylex(void)
|
||||||
|
{
|
||||||
|
int token;
|
||||||
|
|
||||||
|
repeat:
|
||||||
|
token = yylex1();
|
||||||
|
|
||||||
|
/* Do not pass unneeded T_EOL to the parser. */
|
||||||
|
if ((prev_token == T_EOL || prev_token == T_HELPTEXT) && token == T_EOL)
|
||||||
|
goto repeat;
|
||||||
|
|
||||||
|
prev_token = token;
|
||||||
|
|
||||||
|
return token;
|
||||||
|
}
|
||||||
|
|
||||||
static char *expand_token(const char *in, size_t n)
|
static char *expand_token(const char *in, size_t n)
|
||||||
{
|
{
|
||||||
char *out;
|
char *out;
|
||||||
|
|
|
@ -31,7 +31,7 @@ struct symbol *symbol_hash[SYMBOL_HASHSIZE];
|
||||||
static struct menu *current_menu, *current_entry;
|
static struct menu *current_menu, *current_entry;
|
||||||
|
|
||||||
%}
|
%}
|
||||||
%expect 29
|
%expect 21
|
||||||
|
|
||||||
%union
|
%union
|
||||||
{
|
{
|
||||||
|
@ -111,9 +111,7 @@ static struct menu *current_menu, *current_entry;
|
||||||
%}
|
%}
|
||||||
|
|
||||||
%%
|
%%
|
||||||
input: nl start | start;
|
input: mainmenu_stmt stmt_list | stmt_list;
|
||||||
|
|
||||||
start: mainmenu_stmt stmt_list | stmt_list;
|
|
||||||
|
|
||||||
/* mainmenu entry */
|
/* mainmenu entry */
|
||||||
|
|
||||||
|
@ -141,8 +139,7 @@ option_name:
|
||||||
;
|
;
|
||||||
|
|
||||||
common_stmt:
|
common_stmt:
|
||||||
T_EOL
|
if_stmt
|
||||||
| if_stmt
|
|
||||||
| comment_stmt
|
| comment_stmt
|
||||||
| config_stmt
|
| config_stmt
|
||||||
| menuconfig_stmt
|
| menuconfig_stmt
|
||||||
|
@ -193,7 +190,6 @@ config_option_list:
|
||||||
| config_option_list depends
|
| config_option_list depends
|
||||||
| config_option_list help
|
| config_option_list help
|
||||||
| config_option_list option_error
|
| config_option_list option_error
|
||||||
| config_option_list T_EOL
|
|
||||||
;
|
;
|
||||||
|
|
||||||
config_option: T_TYPE prompt_stmt_opt 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 choice_option
|
||||||
| choice_option_list depends
|
| choice_option_list depends
|
||||||
| choice_option_list help
|
| choice_option_list help
|
||||||
| choice_option_list T_EOL
|
|
||||||
| choice_option_list option_error
|
| choice_option_list option_error
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -443,7 +438,6 @@ help: help_start T_HELPTEXT
|
||||||
depends_list:
|
depends_list:
|
||||||
/* empty */
|
/* empty */
|
||||||
| depends_list depends
|
| depends_list depends
|
||||||
| depends_list T_EOL
|
|
||||||
| depends_list option_error
|
| depends_list option_error
|
||||||
;
|
;
|
||||||
|
|
||||||
|
@ -458,7 +452,6 @@ depends: T_DEPENDS T_ON expr T_EOL
|
||||||
visibility_list:
|
visibility_list:
|
||||||
/* empty */
|
/* empty */
|
||||||
| visibility_list visible
|
| visibility_list visible
|
||||||
| visibility_list T_EOL
|
|
||||||
;
|
;
|
||||||
|
|
||||||
visible: T_VISIBLE if_expr T_EOL
|
visible: T_VISIBLE if_expr T_EOL
|
||||||
|
@ -484,11 +477,6 @@ end: T_ENDMENU T_EOL { $$ = $1; }
|
||||||
| T_ENDIF T_EOL { $$ = $1; }
|
| T_ENDIF T_EOL { $$ = $1; }
|
||||||
;
|
;
|
||||||
|
|
||||||
nl:
|
|
||||||
T_EOL
|
|
||||||
| nl T_EOL
|
|
||||||
;
|
|
||||||
|
|
||||||
if_expr: /* empty */ { $$ = NULL; }
|
if_expr: /* empty */ { $$ = NULL; }
|
||||||
| T_IF expr { $$ = $2; }
|
| T_IF expr { $$ = $2; }
|
||||||
;
|
;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue