正则语言是一门最简单的语言
用途:描述目标语言的词法单元及其构成法则
本质:描述字符串的集合
仅有三个概念:
- 字符
- 并运算
- 连接运算:集合的笛卡尔乘积运算,也叫点积运算
用正则语言描述字符串的集合:
满足某一构成法则的字符串的集合称其为一个正则表达式。
构成法则的线性迭加则通过正则表达式的正则运算来表达。
最小的正则表达式为一个字符,它满足正则表达式的定义,因为一个字符也可构成一个字符串,一个集合中可以只有一个元素。
例:字符
i
i
i是一个正则表达式,字符
f
f
f是另一个正则表达式
这两个正则表达式做连接运算,其结果还是一个正则表达式, 其集合中只含一个元素,这个元素为字符串
i
f
if
if
连接运算表达式:{’i’}∙{’f’} = {’if’}
另一种写法:
’
i
’
∙
’
f
’
=
’
i
f
’
{’i’}∙{’f’} = {’if’}
’i’∙’f’=’if’ (当集合中只含一 个元素时)
运算的衍生
对于正则表达式L:
- Kneene闭包:
- 正闭包:
- 扩展形式:
模式表达中的相关概念
- 字符(character):字符集
例如,ASCII字符集:字母集, 数字集,标点符号集; - 串(string): 某个字符集下的字符串。
注意:串不是集合。 串s的长度记为|s|。空串用ε表示。 - 语言(language):字符串的集合。
例如:C语言, Java语言,英语,汉语。,{a}是语言。
串s:
- 前缀(prefix)
- 后缀(suffix)
- 子串(substring)
- 子序列(subsequence): 去掉了一些其中的字符
语言的运算
特定的串的集合叫做语言
有三种运算:
- 并运算
- 联接
- 闭包
语言运算的结果仍是语言
三种运算的优先级:*(+) > 联接 > ∪或 |
用正则表达式表达词法单元的模式
- 变量的正则定义:
使用letter_ 来表示任一字母或下划线,用digit_ 来表示数位。
上式的|表示并运算,括号用于把字表达式组合在一起,星号表示“零个或多个”括号中表达式的连接,将letter_和表达式的其余部分并列表示连接运算。 - 数值常量的正则定义:
optionFraction要么是空串要么是小数点后再跟一个或多个数位;optionalExponent如果不是空串,就是字母E后跟随一个可选的+号或-号,再跟上一个或多个数位;小数点后至少要给一个数位。
正则表达式的扩展
- 一个或多个实例:单目后缀运算符 + 来表示一个正则表达式及其语言的正闭包
- 零个或多个实例
- 零个或一个实例
- 字符类:连续的字符中的任选其一
简洁的正则表达式例子
正则表达式的状态转换图
将字符流切分成词素流,表达了一个词素的获取过程
有三种状态:
- 起始状态
- 中间状态
- 匹配状态(包含、不包含)
状态转换图包含的状态表示看到该关键字的各个后续字母后的情况,最后一个是“非字母或数字”的测试,也就是检查后面是否为某个不可能成为标识符一部分的字符。有必要检查该标识符是否结束,设定词法单元之间的优先级,使得当一个词素同时匹配id的模式和关键字的模式时,优先识别保留字词法单元,而不是id词法单元。
n
u
m
b
e
r
→
d
i
g
i
t
s
(
.
d
i
g
i
t
s
)
?
(
E
[
+
−
]
?
d
i
g
i
t
s
)
?
number → digits (. digits )?( E [+ - ]? digits)?
number→digits(.digits)?(E[+−]?digits)?
分析:
- 如果看到一个数位,转入状态13;在该状态下,可以读入任意数量的其他位数,或消暑,或E。
- 如果都不是这些,进入other(状态20),得到了一个整数形式的数字。这种情形在进入状态20时进行处理,在该状态返回词法单元number以及一个指向常量表条目的指针,刚刚找到的词素便放在这个常量表条目中。
用于识别空白符:
在该图中,寻找一个或多个空白字符,在图中用delim表示。典型的空白字符有空格、制表符、换行符,有可能包括那些根据语言设计不可能出现在任何词法单元中的字符。
分析:
- 在状态24中找到了一个连续的空白字符组成的块,且后面还跟随一个非空白字符。
- 将输入回退到这个非空白符的开头,但并不向语法分析器返回任何词法单元。
- 我们必须在这个空白符之后再次启动词法分析过程。