Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/shell/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
解析表达式语法是否适合解析shell命令语言?_Shell_Parsing_Rust_Parser Generator_Peg - Fatal编程技术网

解析表达式语法是否适合解析shell命令语言?

解析表达式语法是否适合解析shell命令语言?,shell,parsing,rust,parser-generator,peg,Shell,Parsing,Rust,Parser Generator,Peg,POSIX shell命令语言不容易解析,这主要是因为词法分析和解析之间的紧密耦合 然而,解析表达式语法(PEG)通常是无扫描的。通过结合词法分析和语法分析,我似乎可以避免这些问题。我使用的语言(Rust)有一个维护良好的PEG库。然而,我知道有三个困难可能使使用该库变得不切实际: Shell必须能够逐行解析,而不是读取超过行尾的字符 别名纯粹是词法上的,在某些情况下会导致一个标记被其他标记的任何序列替换 Shell保留字仅在某些情况下才能识别 根据这些要求,PEG是否适合解析shell命令

POSIX shell命令语言不容易解析,这主要是因为词法分析和解析之间的紧密耦合

然而,解析表达式语法(PEG)通常是无扫描的。通过结合词法分析和语法分析,我似乎可以避免这些问题。我使用的语言(Rust)有一个维护良好的PEG库。然而,我知道有三个困难可能使使用该库变得不切实际:

  • Shell必须能够逐行解析,而不是读取超过行尾的字符
  • 别名纯粹是词法上的,在某些情况下会导致一个标记被其他标记的任何序列替换
  • Shell保留字仅在某些情况下才能识别

根据这些要求,PEG是否适合解析shell命令语言,或者手写的递归下降解析器是否更合适?

是的,可以使用PEG,并且您注意到的任何问题都不应该是问题。 特别是:

1) 逐行解析:大多数PEG工具不会有任何内置的空白跳过。包括换行符在内的所有空白都必须由您显式处理,这意味着您可以以任何方式处理换行符

2) 您不应该使用来自PEG的解析树作为AST。相反,您应该降低解析树并构建AST。对于别名,在解析完成并构建AST后,可以检测别名并插入别名的相应扩展


3) 保留字不保留,除非你保留它们。也就是说,如果您的上下文中可能出现保留字或另一个字母数字符号,则必须首先明确检查保留字,然后检查任意字母数字符号,因为一旦PEG确定其具有匹配项,这将不会回溯。任何不允许保留字的地方,只要不检查它,您的通用字母数字符号规则就会成功。

FWIW,bash使用相当简单的bison生成的解析器,并结合极其复杂的手写词法分析器。我不知道PEG会有多好,但如果你尝试一下,让我们知道。三个原因:当我的外壳在MIT/Apache 2下时,它是GPL,当我的外壳生锈时,它是C,我从中什么也学不到。是的。PEG解析器进行扫描。语法语言比正则表达式更强大,而且简洁方便。我已经将几个ANTLR语法翻译成Grako(PEG),词法部分很容易翻译。PEG的效率将低于基于状态机的词法分析器。@Apalala我的意思不仅仅是词法分析器;我的意思是解析。这个问题可能比堆栈溢出更适合程序员进行堆栈交换。作为一个所谓的问题,这似乎过于宽泛,也太像一次民意调查。YMMV.我有点走火入魔了,但我把“别名”这个词读作“无参数宏”。谁说宏扩展必须在您提供的语法中形成短语?如果没有,你不能仅仅是一个“树替换”。(坦白地说,当lexer遇到它们时,只需简单地扩展它们就可以轻松处理这些问题)。@Ira:传统的shell别名基本上是文本替换——调用中的任何后续文本都会作为扩展的一部分进行解析。因此,尽管您所说的可能适用于其他语言或更高级的shell中的别名,但文本替换几乎总是正确的。进一步:正如我已经说过的,AST不是一个解析树。您可以做任何替换来创建正确的别名语义。“几乎总是?”给定字符串“if(pqr abc”,pqr是别名“a>b)”,您如何解析该字符串,然后稍后替换别名?您不能,shell也不能。我的意思是“在大多数情况下,别名是合法的”。你的例子在我使用的任何shell中都是不合法的。我说“大多数”,因为我不确定;OP应该检查一下。在任何情况下,我都不会再争论它了,因为这与所问的问题无关。shell别名不是宏、无参数或其他形式,因此您的论点不适用。仅当命令有效时,才会检测和扩展外壳别名。然而,我可能在建议一个简单的AST替换时走得太远了,所以我概括了我的答案。谢谢你指出可能的误解。