参考gpt
词法分析器作用
读入源程序字符流、组成词素,输出词法单元序列
过滤空白、换行、制表符、注释等
将词素添加到符号表中
基本术语
1.词法单元
源代码字符串集的分类 <identifier, count>, <number,80>
2.模式——字符串集 → 分类为 \overset{\text{分类为}}{\rightarrow} →分类为单词的规则
正则表达式, [ A − Z ] ∗ . ∗ [A-Z]^*.^* [A−Z]∗.∗
3.词素
程序中实际出现的字符串,与模式匹配,分类为单词
词法单元 | 词素实例 |
---|---|
else——字符 e, l, s, e | else |
if——字符 i,f | if |
comparison | <, <=, =, < >, >, >= |
id——字母开头的字母或数字 | pi, count, D2 |
number | 3.1416 |
literal——在2个“之间,除”以外的任何字符 | “core dumped” |
词法单元的类别
1.每个关键字有一个词法单元。一个关键字的模式就是该关键字本身
2. 表示运算符的词法单元。表示单个/一类运算符
3. 表示所有标识符的词法单元
4. 一个或多个表示常量的词法单元,比如数字和字面值字符串
5. 每一个标点符号有一个词法单元
词法单元的属性
词素的更多信息
名字 | 属性 |
---|---|
影响语法分析 | 影响翻译 |
二元组 < 记号,属性值 > 二元组<记号,属性值> 二元组<记号,属性值>;属性一般用符号表的指针表示
p o s i t i o n : = i n i t i a l + r a t e ∗ 60 position := initial + rate * 60 position:=initial+rate∗60
< id,指向符号表中position条目的指针>
< assign _ op >
< id,指向符号表中initial条目的指针>
< add_op>
< id,指向符号表中rate条目的指针>
< mul_ op>
< num,整数值60>
词法错误
较少:词法分析是对源程序极为局部化的视角
f i ( a = = f ( x ) ) . . . fi (a == f(x))... fi(a==f(x))...词法分析无法发现
什么情况下发生——剩余输入的前缀无法与任何一个模式匹配
修复方法:
删除、插入字符
替换、交换字符
最短编辑距离
输入缓冲
加快程序读入速度的方法
若干个字符 → \rightarrow →正确的词素 = 或< 可能是 == 或 <=至少向前看一个字符
单字符I/O+预读和回退 → \rightarrow →效率低下
磁盘 → 块I/O 缓冲区 → 单字符读取 词法分析器 磁盘\overset{\text{块I/O}}{\rightarrow}缓冲区\overset{\text{单字符读取}}{\rightarrow}词法分析器 磁盘→块I/O缓冲区→单字符读取词法分析器
3种实现方式
- 自动生成工具——Lex,生成工具提供读取输入和缓冲的函数
- 高级语言手工编码,利用高级语言提供的I/O函数
- 汇编语言编程,直接访问磁盘
1 → 3 : 性能 ↑ , 实现难度 ↑ 1\rightarrow3:性能 \uparrow,实现难度 \uparrow 1→3:性能↑,实现难度↑
唯一读取文件的阶段,值得优化
方案
- 双缓冲区方案
- 哨兵标记
双缓冲技术
双缓冲通常涉及2个缓冲区:一个存储输入文本,另一个存储当前正在处理的词素(lexeme)Current token
lexemeBegin:当前词素的开始位置
哨兵标记
每个缓冲区末端添加标记——哨兵sentinel: eof → \rightarrow →减少条件判断
词法单元的描述
正则表达式 → \rightarrow →正规式:描述词素模式的表示方法
有限的重复 一个给定结构的无限重复
regular expression r——表示语言L(r)
利用一组规则(运算)构造
高效描述在处理词法单元时要用到的模式类型,基本r如何递归构成复杂r
定义规则
归纳基础
字母表Σ上的正则表达式r的定义规则,以及r所表示的语言 L ( r ) L(r) L(r)定义:
- ε是正则表达式,表示语言{ε}
- 若a∈Σ,则a是正则表达式,表示语言{a}
归纳步骤
r, s为正则表达式,表示语言 L ( r ) , L ( s ) L(r),L(s) L(r),L(s),则
优先级逐渐
↑ \uparrow ↑
( r ) ∣ ( s ) 是正则 → 表示语言 L ( r ) ∪ L ( s ) (r) | (s)是正则\rightarrow表示语言L(r) ∪ L(s) (r)∣(s)是正则→表示语言L(r)∪L(s)
( r ) ( s ) 是正则,表示语言 L ( r ) L ( s ) (r)(s)是正则,表示语言L(r)L(s) (r)(s)是正则,表示语言L(r)L(s)
( r ) ∗ 是正则,表示语言 ( L ( r ) ) ∗ (r)*是正则,表示语言{(L(r))}^* (r)∗是正则,表示语言(L(r))∗
( r ) 是正则,表示语言 L ( r ) (r) 是正则,表示语言L(r) (r)是正则,表示语言L(r)
a ∣ b ∗ c = ( a ) ∣ ( ( b ) ∗ ( c ) ) a | b^* c= (a)|({(b)}^*(c)) a∣b∗c=(a)∣((b)∗(c))
e . g : Σ = a , b e.g:Σ={a, b} e.g:Σ=a,b
a ∣ b → { a , b } a | b\quad\rightarrow\quad\{ a, b\} a∣b→{a,b}
( a ∣ b ) ( a ∣ b ) → { a a , a b , b a , b b } (a | b)(a | b)\quad\rightarrow\quad\{ aa, ab, ba, bb \} (a∣b)(a∣b)→{aa,ab,ba,bb}
a ∗ → { e , a , a a , a a a , … } a^*\quad\rightarrow\quad\{e, a, aa, aaa, …\} a∗→{e,a,aa,aaa,…}
( a ∣ b ) ∗ → { 空串及所有由 a 、 b 组成的符号串 } (a | b)^*\quad\rightarrow\quad\{ 空串及所有由a、b组成的符号串 \} (a∣b)∗→{空串及所有由a、b组成的符号串}
a ∣ a ∗ b → { a , b , 所有以多个 a 开头,后跟一个 b 的符号串 } a | a^*b\quad\rightarrow\quad\{a, b, 所有以多个a开头,后跟一个b的符号串\} a∣a∗b→{a,b,所有以多个a开头,后跟一个b的符号串}
正则集合:正则表达式定义的语言
正则表达式等价: r = s ← → 表示语言相同, L ( r ) = L ( s ) r = s\leftarrow\rightarrow表示语言相同,L(r) = L(s) r=s←→表示语言相同,L(r)=L(s)
正则表达式的代数定律
交换律 : r ∣ s = s ∣ r 交换律:r|s=s|r 交换律:r∣s=s∣r
结合律 : r ∣ ( s ∣ t ) = ( r ∣ s ) ∣ t 结合律:r|(s|t)=(r|s)|t 结合律:r∣(s∣t)=(r∣s)∣t
连接满足结合律 : ( r s ) t = r ( s t ) 连接满足结合律:(r s) t = r (s t) 连接满足结合律:(rs)t=r(st)
连接和 ∣ 满足分配律 : r ( s ∣ t ) = r s ∣ r t , ( s ∣ t ) r = s r ∣ t r 连接和 | 满足分配律:r ( s | t ) = r s | r t,( s | t ) r = s r | t r 连接和∣满足分配律:r(s∣t)=rs∣rt,(s∣t)r=sr∣tr
ε 是连接运算的单位元 : ε r = r , r ε = r ε是连接运算的单位元:εr = r,rε= r ε是连接运算的单位元:εr=r,rε=r
ε 和 ∗ 间的关系 : r ∗ = ( r ∣ ε ) ∗ ε和*间的关系:r^* ={( r | ε)}^* ε和∗间的关系:r∗=(r∣ε)∗
∗ 是幂等的 : r ∗ ∗ = r ∗ * 是幂等的:r^{**} = r^* ∗是幂等的:r∗∗=r∗
正则定义
为正则表达式指定名字
d 1 → r 1 d1 \rightarrow r1 d1→r1
d 2 → r 2 d2\rightarrow r2 d2→r2
… … …
d n → r n dn \rightarrow rn dn→rn
di是不同的名字,并且不在Σ 中
ri是 Σ ∪ d 1 , d 2 , … , d i − 1 基本符号与前面定义的名字 Σ∪{d_{1}, d_{2}, …, d_{i-1}} 基本符号与前面定义的名字 Σ∪d1,d2,…,di−1基本符号与前面定义的名字上的正则
e.g1:C语言标识符
( _ ∣ A ∣ … ∣ Z ∣ a ∣ … ∣ z ) ( _ ∣ A ∣ … ∣ Z ∣ a ∣ … ∣ z ∣ 0 ∣ … ∣ 9 ) ∗ {(\_|A| … | Z | a | … | z)(\_ |A | … | Z | a | … | z | 0 | … | 9)}^* (_∣A∣…∣Z∣a∣…∣z)(_∣A∣…∣Z∣a∣…∣z∣0∣…∣9)∗
l e t t e r _ → A ∣ B ∣ C ∣ … ∣ Z ∣ a ∣ b ∣ … ∣ z ∣ _ letter\_ \rightarrow A | B | C | … | Z | a | b | … | z | \_ letter_→A∣B∣C∣…∣Z∣a∣b∣…∣z∣_
d i g i t → 0 ∣ 1 ∣ 2 ∣ … ∣ 9 digit \rightarrow0 | 1 | 2 | … | 9 digit→0∣1∣2∣…∣9
i d → l e t t e r ( l e t t e r ∣ d i g i t ) ∗ id \rightarrow letter_( letter_ | digit )* id→letter(letter∣digit)∗
简化:
l e t t e r _ → [ A − Z a − z _ ] letter\_ \rightarrow [A-Za-z\_] letter_→[A−Za−z_]
d i g i t → [ 0 − 9 ] digit \rightarrow [0-9] digit→[0−9]
i d → l e t t e r _ ( l e t t e r _ ∣ d i g i t ) ∗ id \rightarrow letter\_ ( letter\_ | digit)* id→letter_(letter_∣digit)∗
e.g2:C语言无符号数 → \rightarrow →上下文无关文法
d i g i t → 0 ∣ 1 ∣ 2 ∣ … ∣ 9 digit \rightarrow 0 | 1 | 2 | … | 9 digit→0∣1∣2∣…∣9
d i g i t s → d i g i t d i g i t ∗ digits \rightarrow digit digit^* digits→digitdigit∗
o p t i o n a l _ f r a c t i o n → . d i g i t s ∣ ε optional\_fraction \rightarrow . digits |ε optional_fraction→.digits∣ε
o p t i o n a l _ e x p o n e n t → ( E ( + ∣ − ∣ ε ) d i g i t s ) ∣ ε optional\_exponent \rightarrow ( E ( + | - | ε) digits ) |ε optional_exponent→(E(+∣−∣ε)digits)∣ε
n u m → d i g i t s o p t i o n a l _ f r a c t i o n o p t i o n a l _ e x p o n e n t num \rightarrow digits optional\_fraction optional\_exponent num→digitsoptional_fractionoptional_exponent
简化:
d i g i t → [ 0 − 9 ] digit \rightarrow [0-9] digit→[0−9]
d i g i t s → d i g i t + digits \rightarrow digit+ digits→digit+
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 \rightarrow digits (.digits)? (E(+|-)? digits)? number→digits(.digits)?(E(+∣−)?digits)?
符号简写
R + 一个或多个字符串从 L ( R ) 中匹配 L ( R ) : R ( R ∗ ) R^+一个或多个字符串从L(R)中匹配L(R): R(R^*) R+一个或多个字符串从L(R)中匹配L(R):R(R∗)
R ? R 是可选的 : ( R ∣ ε ) R?R是可选的: (R|ε) R?R是可选的:(R∣ε)
[abce] 从列表中选择一个字符: (a|b|c|e) → \rightarrow →[a-z] :(a|b|c|d|e|…|y|z)
[^ab] 除了列表中的字符之外的任意字符 → \rightarrow →[^a-z]
0 ∗ 1 0 ∗ 1 0 ∗ 1 0 ∗ : ( ε 1 ∗ ∣ 0 1 ∗ ) ∗ 包含 3 个 1 的 01 串 0^*10^*10^*10^*:{(ε 1^*| 01^*)}^*包含3个1的01串 0∗10∗10∗10∗:(ε1∗∣01∗)∗包含3个1的01串
( ( ε ∣ 0 ) 1 ∗ ) ∗ : ( 1 ∗ ∣ 0 1 ∗ ) ∗ 所有 01 串 → ( 1 ∣ 0 ) ∗ {((ε| 0) 1^*)}^*:{( 1^*| 01^*)}^*所有01串\rightarrow( 1| 0)^* ((ε∣0)1∗)∗:(1∗∣01∗)∗所有01串→(1∣0)∗
被5整除的10进制整数 [ 1 − 9 ] [ 0 − 9 ] ∗ ( 0 ∣ 5 ) ∣ 0 ∣ 5 [1-9][0-9]^*(0 | 5) | 0 | 5 [1−9][0−9]∗(0∣5)∣0∣5
不包含连续的0的01串:
( 1 ∣ 0 ) ∗ : ε , 0 , 1 , 01 , 10 , 11 , 010 , 101 , 110 , 111 , … (1|0)^*:ε,0,1,01,10,11,010,101,110,111,… (1∣0)∗:ε,0,1,01,10,11,010,101,110,111,…
非正则表达式集——正则无法描述的语言
{wcw | w是a、b组成的符号串}
正规式无法描述平衡或嵌套的结构