如何修复简单 shell 命令的解析顺序?
How to fix the order in which a simple shell command is parsed?
使用下面定义的语法规则,我试图解析一个简单的 shell 命令,比如说 cd testFolder
.
这些是我在 parser.y 中定义的规则:
%union{
char *str;
}
%type <str> WORD
%%
command_list:/*empty*/
|command_list command_line{
printf("myShell > ");
}
;
arg_list:/*empty*/
| arg_list WORD{
printf("Args: %s\n", );
free();
}
;
cmd_and_args:
WORD arg_list {
printf("CMD: %s\n", );
free();
}
;
command_line:
cmd_and_args NEWLINE {printf("NULL\n");
}
| NEWLINE {
printf("NULL\n");
}
%%
所以我想要的输出是:
CMD: cd
Args: testFolder
NULL
但我得到的是:
Args: testFolder
CMD: cd
NULL
对于像 vim -O test.c test1.c
这样的命令,我得到:
Args: -O
Args: test.c
Args: test1.c
CMD: vim
NULL
参数是按顺序排列的,但命令最终排在最后。如何以正确的顺序获取它们?
我想我解决了这个问题,这是更新后的语法:
%union{
char *str;
}
%type <str> WORD
%%
command_list:/*empty*/
|com
mand_list command_line{
printf("myShell > ");
}
;
command_line: simple_command NEWLINE{
printf("NULL\n");
}
| NEWLINE{
printf("NULL\n");
}
;
simple_command: simple_command words
| WORD{
printf("CMD: %s\n", );
}
;
words: WORD{
printf("Args: %s\n", );
}
%%
Bison 生成自下而上 解析器,这意味着如果您将解析视为一棵树,节点将在其父节点之前被处理。 (换句话说,这是一个 post 阶遍历。)
因此
的行动
cmd_and_args: WORD arg_list { … }
在 arg_list
的操作之后执行。
我不明白为什么这会成为问题,但您可以通过使用 Midrule Action 或使用单位生产来提取命令词来更改它。
中期行动
cmd_and_args: WORD { /* print */ arg_list { /* arg_list is now */ }
单位产量
cmd_and_args: command_word arg_list { … }
command_word: WORD { /* print */ }
注意:文法并不代表真正的 shell 文法,它允许赋值在命令词之前(例如 LC_ALL=C sort file.txt
)。
使用下面定义的语法规则,我试图解析一个简单的 shell 命令,比如说 cd testFolder
.
这些是我在 parser.y 中定义的规则:
%union{
char *str;
}
%type <str> WORD
%%
command_list:/*empty*/
|command_list command_line{
printf("myShell > ");
}
;
arg_list:/*empty*/
| arg_list WORD{
printf("Args: %s\n", );
free();
}
;
cmd_and_args:
WORD arg_list {
printf("CMD: %s\n", );
free();
}
;
command_line:
cmd_and_args NEWLINE {printf("NULL\n");
}
| NEWLINE {
printf("NULL\n");
}
%%
所以我想要的输出是:
CMD: cd
Args: testFolder
NULL
但我得到的是:
Args: testFolder
CMD: cd
NULL
对于像 vim -O test.c test1.c
这样的命令,我得到:
Args: -O
Args: test.c
Args: test1.c
CMD: vim
NULL
参数是按顺序排列的,但命令最终排在最后。如何以正确的顺序获取它们?
我想我解决了这个问题,这是更新后的语法:
%union{
char *str;
}
%type <str> WORD
%%
command_list:/*empty*/
|com
mand_list command_line{
printf("myShell > ");
}
;
command_line: simple_command NEWLINE{
printf("NULL\n");
}
| NEWLINE{
printf("NULL\n");
}
;
simple_command: simple_command words
| WORD{
printf("CMD: %s\n", );
}
;
words: WORD{
printf("Args: %s\n", );
}
%%
Bison 生成自下而上 解析器,这意味着如果您将解析视为一棵树,节点将在其父节点之前被处理。 (换句话说,这是一个 post 阶遍历。)
因此
的行动 cmd_and_args: WORD arg_list { … }
在 arg_list
的操作之后执行。
我不明白为什么这会成为问题,但您可以通过使用 Midrule Action 或使用单位生产来提取命令词来更改它。
中期行动
cmd_and_args: WORD { /* print */ arg_list { /* arg_list is now */ }
单位产量
cmd_and_args: command_word arg_list { … }
command_word: WORD { /* print */ }
注意:文法并不代表真正的 shell 文法,它允许赋值在命令词之前(例如 LC_ALL=C sort file.txt
)。