【问题标题】:yacc, only applying rule onceyacc,只应用一次规则
【发布时间】:2009-02-23 18:22:11
【问题描述】:

我正在尝试使用 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 重定向的多个副本。

【问题讨论】:

  • 这是作业的要求吗?标准 shell 允许您多次重定向而不会出错,输出只是在最后一个文件中。我不确定您希望这有多现实,但您缺少 >> 和
  • 实际上并没有提到我正在做的任务,我只是认为只能重定向一次更有意义。我同意上面的列表不完整,我稍后会添加其他 I/O 重定向。

标签: shell yacc


【解决方案1】:

有两种方法:

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

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

(2) 修改子句句柄,统计修饰符,多则报错:

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

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

【讨论】:

    【解决方案2】:

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

    ls > x > y
    

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多