12

是否有现有的 POSIX sh 语法可用,或者我必须直接从规范中找出它?

请注意,我对纯sh不太感兴趣;一个扩展但符合标准的 sh 对于我的目的来说也很好。

4

4 回答 4

8

POSIX 标准定义了POSIX shell 的语法。该定义包括一个带注释的 Yacc 语法。因此,它可以或多或少地机械地转换为 EBNF。

如果你想要一个“真正的”语法,那么你必须更加努力。选择你的“真实外壳”并找到源代码并从中找出语法。

请注意,EBNF 并未广泛使用。它的实用价值有限,尤其是因为基本上没有支持它的工具。因此,您不太可能找到现成的 EBNF 语法(几乎任何东西)。

于 2013-03-24T15:18:26.900 回答
8

我做了更多的挖掘并找到了这些资源:

  1. 位于此处sh教程

  2. 一本包含 Bash 2.0 的 BNF 语法的 Bash 书(从此处消失),相关附录仍在此处

我查看了 , , 的来源,bash但在我需要的抽象级别上没有找到任何远程的东西。pdkshposh

于 2013-03-24T14:48:35.923 回答
3

在过去的一年中,我多次尝试编写自己的成熟 Bash 解释器,并且在某些时候我也达到了标记答案(#2)中所述的同一本书附录参考,但它并不完全正确/更新(例如,它没有使用'coproc'保留关键字定义生产规则,并且使用'<&'进行重定向的重复生产规则定义,可能是更多问题,但这些是我注意到的)。

  1. 我发现的最好的方法是去http://ftp.gnu.org/gnu/bash/
  2. 下载当前 bash 版本的源代码
  3. 打开 parse.y 文件(在本例中是 YACC 文件,它基本上包含 bash 使用的所有解析逻辑),然后将 '%%' 之间的行复制粘贴到您喜欢的文本编辑器中,这些行定义了语法的产生规则
  4. 然后,使用一点正则表达式(顺便说一句,我很糟糕),我们可以删除 '{...}' 之间的额外代码逻辑,以使语法看起来更像 BNF。

我使用的正则表达式是:

(\{(\s+.*?)+\})\s+([;|])

它匹配任何非贪婪的行,包括大括号之间的.*?空格和新行,特别是在or字符之前的最后一个右大括号。然后我只是将匹配的字符串替换为(例如第三个捕获组的结果,要么是;要么|)。\s+;|\3

这是我在发布时设法提取的语法定义https://pastebin.com/qpsK4TF6

于 2019-05-06T01:39:59.150 回答
1

我希望 sh、csh、ash、bash 将包含解析器。这些的 GNU 版本是开源的;你可以去那里检查一下。

于 2013-03-24T13:47:29.590 回答