【问题标题】:Parsing shell commands in c: string cutting with respect to its contents在 c 中解析 shell 命令:关于其内容的字符串切割
【发布时间】:2016-01-04 08:26:47
【问题描述】:

我目前正在创建 Linux shell 以了解有关系统调用的更多信息。

我已经弄清楚了大部分事情。解析器,令牌生成,将适当的东西传递给适当的系统调用 - 工作。

问题是,甚至在我开始制作标记之前,我就将整个命令字符串拆分为单独的单词。它基于分隔符数组,而且效果出奇的好。除了我正在努力为它添加额外的功能,比如转义序列或引号。没有它我真的活不下去,因为即使是使用基本 grep 命令的人也会使用带引号的参数。我需要添加以下功能:

  • ' ' - 忽略这两者之间的所有其他分隔符、运算符或双引号,将其作为一个字符串传递,不要将这些引号包含在结果单词中,
  • " "- 同上,但忽略单引号,
  • \\ - 将其转义为单个反斜杠,
  • \(space) - 将其转义到空格中,不要将生成的空格解析为分隔符
  • \"、\' - 与上述类似。
  • 我还没有弄清楚我需要的许多其他东西

而且它们中的每一个本身似乎都是一个例外。它们中的每一个都必须对命令中可能的位置的多样性进行操作,是否包含在结果中,对其余的解析产生影响。它使我的代码看起来像一个大泥球。

有没有更好的方法来做到这一点?为此目的是否有更通用的算法?

【问题讨论】:

标签: c string parsing


【解决方案1】:

您正在尝试使用用于词法分析器的非传统结构来解决程序分析(词法分析和解析)中的一个经典问题(我将整个命令字符串拆分为单独的单词...)。好的,那么让词法分析器“正确”会遇到非传统的麻烦。

这并不意味着这种方式注定要失败,并且在没有看到问题的具体实例的情况下,(你列出了一组你想要处理的构造,但不要说为什么这些构造很难处理),它很难提供任何具体的建议。这也不意味着这种方式会导致成功。分割线可能会破坏不应该被破坏的标记(通常是因为对转义的内容感到困惑)。

使用标准词法分析器(例如 Flex 或 any of the 1000 variants you can get)的意义在于,它们为复杂的词法分析问题提供了一种经过验证的方法,通常基于人们可以使用正则表达式来描述单个词素的形状。因此,每个词位类型都有一个正则表达式,因此它们是一片汪洋,但每个词都很容易自行指定。

我已经使用强大的词法分析器和解析器(使用该列表中的一种)完成了 ~40 种语言。我向您保证,标准方法在经验上非常有效。意外的类型很容易理解和管理。非标准的方法总是有可能会让你大吃一惊。

最后一句话:Unix 的 shell 语言已经让人们添加疯狂的东西 40 年了。期望这份工作至少是中等难度的,不要期望它会像 Wirth 最初的 Pascal。

【讨论】:

  • 我实际上开始了那个项目,因为我讨厌 bash 古怪的语法。特别是在我尝试 +=1 一个变量之后,它产生了“11”而不是 2,并且让我比以前更秃了一点。我在列表中的每个位置面临的问题是它们的行为会根据它们在字符串中的位置而变化。考虑这样的事情:com\ 1"something" |com2 arg1 arg\ 2 "arg '3' \ "。 "、'、\ 中的每一个都在我的代码中提供了不同的异常情况。这很烦人。
  • 在我看来,“+1 变量产生 11”不是语法问题;它对“+=”的语义应该是什么存在分歧(无论如何都向变量添加一个?如果它是一个字符串,则将一个字符附加到一个变量?)。使用标准工具,您可能不喜欢它的语义,但除非您想自己重写它,否则您几乎必须忍受它们(哦,等等,您正在这样做:)
  • 在您列出的具体问题中,许多问题都可以在经典词法分析器中通过在发现它们的上下文中进行处理来解决;尤其是逃跑。转义通常作为扫描特定词位的一部分被拾取,因此可以在知道它们是这样的情况下进行处理。
  • 我不喜欢生活在让我的生活变得更艰难的事情上。 Bash 在操作符方面的古怪之处和“直觉性”就是其中之一。所以是的,我正在重写:P。
  • 您可能会发现,您可以自己重写它(付出很多努力),但其他懒惰的人仍然会继续使用已经存在的、广泛可用的版本。在你开始真正的工作之前,如果没有用闪亮的版本替换所有东西,你将得不到任何牵引力,生活已经够艰难了。话虽如此,进步是由不讲道理的人取得的;给你更多的力量,你会学到很多东西。享受吧。
猜你喜欢
  • 1970-01-01
  • 2012-04-24
  • 1970-01-01
  • 2011-12-11
  • 2020-03-11
  • 2016-07-30
  • 2012-02-26
  • 1970-01-01
  • 2019-07-07
相关资源
最近更新 更多