如何修复解析简单shell命令的顺序?

问题描述 投票:0回答:2

使用下面定义的语法规则,我试图解析一个简单的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", $2);
            free($2);
        }
        ;

cmd_and_args:
             WORD arg_list {
                printf("CMD: %s\n", $1);
                free($1);
             }
            ;

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

args是有序的,但命令最终会到最后。如何以正确的顺序获得它们?

bison context-free-grammar bnf
2个回答
0
投票

Bison生成自下而上的解析器,这意味着如果您将解析视为树,则会在父节点之前处理节点。 (换句话说,这是一个后序遍历。)

所以行动

 cmd_and_args:  WORD arg_list { … }

arg_list的行动之后执行。

我不明白为什么这会是一个问题,但你可以通过使用Midrule Action或使用单位生产来提取命令字来改变它。

Midrule Action

cmd_and_args:  WORD { /* print $1*/ arg_list { /* arg_list is now $3 */ }

Unit production

cmd_and_args: command_word arg_list { … }

command_word: WORD { /* print $1 */ }

注意:语法不代表真正的shell语法,它允许在命令字之前进行赋值(例如.LC_ALL=C sort file.txt)。


0
投票

我想我解决了这个,这里是更新的语法:

%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", $1);
                  }
                  ;

    words: WORD{
            printf("Args: %s\n", $1);
         }
    %%
© www.soinside.com 2019 - 2024. All rights reserved.