- 语法,包括生产、非终端、终端和运算符
- 正则表达式
一些程序模块以字节序列或字符序列的形式接收输入或产生输出,当它只是存储在内存中时称为字符串,或者当它流入或流出模块时称为流。在今天的阅读中,我们讨论如何为这样的序列编写规范。具体而言,字节或字符序列可能是:
- 字符串
- 磁盘上的文件,在这种情况下,规范称为文件格式
- 通过网络发送的消息,在这种情况下,规范是有线协议
- 用户在控制台上键入的命令,在这种情况下,规范是命令行界面
对于这些类型的序列,我们引入了语法的概念,它不仅允许我们区分合法和非法序列,还可以将序列解析为程序可以使用的数据结构。从语法生成的数据结构通常是递归数据类型,就像我们在递归数据类型读取中讨论的那样。
我们还讨论了一种称为正则表达式的语法的专门形式。除了用于规范和分析之外,正则表达式还是一种广泛使用的工具,用于许多需要反汇编字符串、从中提取信息或转换字符串的字符串处理任务。
接下来的阅读将讨论解析器生成器,这是一种将语法自动转换为该语法的解析器的工具。
制作可以使用运算符将右侧的终端和非终端组合在一起。生产表达式中最重要的三个运算符是:
重复,表示:*
x ::= y* // x matches zero or more y
串联,不是由符号表示,而只是一个空格:
x ::= y z // x matches y followed by z
联合,也称为交替,表示为:|
x ::= y | z // x matches either y or z
按照惯例,后缀运算符具有最高优先级,这意味着它们首先被应用。接下来应用串联。交替具有最低的优先级,这意味着它最后应用。括号可用于覆盖优先级:*
|
m ::= a (b|c) d // m matches a, followed by either b or c, followed by d
x ::= (y z | a b)* // x matches zero or more yz or ab pairs
让我们使用这些运算符来概括我们的语法以匹配其他一些主机名,例如 和 。url
http://stanford.edu/
http://google.com/
url ::= 'http://' hostname '/'
hostname ::= 'mit.edu' | 'stanford.edu' | 'google.com'
此语法的第一条规则演示串联。非终端匹配以文本字符串开头的字符串,后跟与非终端的匹配,后跟文本字符串。url
http://
hostname
/
该规则演示联合。可以匹配三个文本字符串之一,或者 。hostname
hostname
mit.edu
stanford.edu
google.com
因此,此语法表示三个字符串、 、 和 的集合。http://mit.edu/
http://google.com/
http://stanford.edu/
让我们更进一步,允许任何小写单词代替 、 、 和 :mit
stanford
google
com
edu
url ::= 'http://' hostname '/'
hostname ::= word '.' word
word ::= letter*
letter ::= ('a' | 'b' | 'c' | 'd' | 'e' | 'f' | 'g' | 'h' | 'i'
| 'j' | 'k' | 'l' | 'm' | 'n' | 'o' | 'p' | 'q'
| 'r' | 's' | 't' | 'u' | 'v' | 'w' | 'x' | 'y' | 'z')
新规则匹配零个或多个小写字母的字符串,因此整体语法现在也可以匹配。不幸的是,也可以匹配一个空字符串,所以这个语法也匹配,这不是一个合法的URL。这里有一个详细的方法来解决这个问题,它需要匹配至少一个字母。word
http://alibaba.com/
http://zyxw.edu/
word
url
http://./
word
word ::= letter letter*
我们将在下一节中看到一种更简单的编写方法。