1

我正在尝试使用 yacc 和 lex 编写 shell,但我的 I/O 重定向器遇到了一些问题。目前,我可以按任何顺序很好地使用 < 和 > 运算符,但我的问题是我可以重定向两次而没有错误,例如“ls > log > log2”

我的规则代码如下,谁能给我一些关于如何解决这个问题的提示?谢谢!

 io_mod:
    iomodifier_opt io_mod
    |
    ;

 iomodifier_opt:
    GREAT WORD {
        printf("   Yacc: insert output \"%s\"\n", $2);
        Command::_currentCommand._outFile = $2;
    }
    |
    LESS WORD {
       printf("   Yacc: insert input \"%s\"\n", $2);
       Command::_currentCommand._inputFile = $2;
    }
    | /* can be empty */
    ;

编辑:在与我的 TA 交谈后,我了解到我实际上不需要为我的命令只使用 1 个修饰符,而且我实际上可以拥有相同 I/O 重定向的多个副本。

4

3 回答 3

4

有两种方法:

(1) 修改语法,使每一种修饰语只能有一个:

io_mod_opt:out_mod in_mod | in_mod out_mod | in_mod | out_mod | ;

(2)修改子句处理程序,统计修饰符,多于一个则报错:

大字{
    如果(已经有输出文件()){
        error("输出文件太多:\"%s\"\n", $2)
    } 别的 {
        /* 记录输出文件 */
    }
}

选项 (2) 似乎可能导致更好的错误消息和更简单的语法。

于 2009-02-23T19:04:35.880 回答
1

还有第三种方法——不要担心。Bash(在 Cygwin 下)不会产生以下错误:

ls > x > y

它先创建 x,然后创建 y,最后写入 y。

于 2009-02-27T03:54:51.743 回答
-1

我意识到这可能只是一个学习 lexx 和 yacc 的练习,但除此之外,第一个问题是问为什么要使用 lexx 和 yacc?任何常用的 shell 命令语言都有一个非常简单的语法。您从使用 LALR 生成器中获得了什么?

好吧,我的意思是,除了复杂性、难以生成好的错误消息和代码量之外。

于 2009-02-23T20:20:57.023 回答