我最近有一个编程类,在那里我们用Java实现了一个shell。其中一项要求是确保可以从终端读取参数,而不考虑它们之间的空格和制表符等,除非在引号内,引号内的所有内容都是原样的。
为了解决这个问题,我编写了一个正则表达式,并使用流在数组中获得结果以供进一步处理。
但现在,在准备系统编程课程时,我意识到必须有一种更简单的方法来做到这一点?这是如何在典型的类似shell的bash中实现的?
它只是一个字符接一个字符地读取流,当它遇到引号时跳过,直到找到匹配的引号吗?
对于复杂的语法(bash令牌可能很复杂(,最好使用解析器/生成器工具,而不是从头开始实现逻辑。使用RE可以覆盖一些语法,但不太可能覆盖复杂的规则集。
根据约束条件(编程语言等(,考虑两个选项:
- 使用flex/bison进行令牌解析和语法解析,或者
- 使用脚本引擎(Python、Perl、JavaScript(,它同时具有RE和强大的字符串处理功能
对于bash(可能还有任何其他现代shell(来说,它要复杂得多。请参阅bash的源代码中的此函数,该函数用于解析匹配的一对字符(引号、大括号等(。它非常复杂,因为有许多不同类型的引号、圆括号和大括号('
、{
、(
、"
、'
…(,并且涉及到许多边缘情况。例如,在这种情况下,跳过字符直到看到另一个引号是不起作用的,因为事情可以嵌套:
echo "`echo "hello"`"
我不知道你在类中实现的shell程序的需求,但如果它不包括这样的嵌套结构,那么我相信可以使用你提到的简单方法。