【梳理】编译原理与实践 第二章 扫描(docx)

编译原理

知 识 梳 理

(第一版)

建议先修课程:离散数学、C / C++、数据结构、汇编语言、计算机组成原理。
配套教材:
Kenneth C. Louden Compiler Construction: Principles and Practice


链接:https://pan.baidu.com/s/1sBfYGtpjNzh8YbnLGCiYnw
提取码:0000


二 扫描
2.1 扫描过程
标记是通常用枚举类型定义的逻辑实体。例如:
typedef enum { IF, THEN, ELSE, PLUS, MINUS, NUM, ID, … } TokenType;
标记被分为几类。包括保留字(reserved word),又称关键字(keyword),例如IF和THEN,代表字符串“if”和“then”。第二类是特殊符号,例如算术运算符PLUS和MINUS,代表“+”和“-”。最后一类是可以代表多个字符串的标记,例如NUM和ID,分别代表数字和标识符。
如果编程语言不支持枚举,则需要按照比较老的方式直接定义标记了。例如:
#define IF 256
#define THEN 257
#define ELSE 258

(数值从256开始,以免与ASCII字符的值冲突)

标记是本身必须与它们代表的字符串区分开来的逻辑实体。在上例中,保留字标记IF必须与它代表的“if”区别。标记代表的字符串也被叫做字符串值(string value)或词义(lexeme)。每个保留字只有1个词义。标识符虽然都用单一的标记ID表示,但具有许多字符串值代表它们各自的名称。这些名称必须由编译器使用符号表追踪。因此,扫描器也必须至少构造部分标记的字符串值。与标记关联的值叫做属性(attributes)。标记-属性属于key-value结构,这种结构在计算机科学与工程中是极其常见的。字符串值就是一种属性。标记也可以具有其它属性。例如,NUM标记可以同时具有一个字符串值“32767”,也可以具有一个从字符串计算得来的数值32767。特殊符号标记PLUS也同时与字符串“+”和算术运算符+关联。实际上,可以把标记符号自己看成一个属性,而全体标记看作属性的集合。记号主要在词法分析和语法分析中使用,而属性主要在语义分析中使用。

扫描器至少需要计算后续步骤需要的每个标记的属性数量。举例:NUM的字符串值需要先行得到,但字符串值代表的数值倒不用马上计算。另一方面,如果数值计算出来了,字符串值就可以丢弃。扫描器可以为编译的后续阶段执行必要的运算,也可以直接把属性传递给后续阶段。比如,可以将标识符的字符串值输入符号表,或干脆丢给编译器的其它部件。

由于扫描器可能需要计算标记的数个属性值,因此将属性值都用单一的结构类型表示是很有用的。这样的结构可以称为标记记录(token record)。例如:
typedef struct { TokenType TokenVal; char* StringVal; int NumVal; } TokenRecord;
typedef struct { TokenType tokenval; union { char* stringval; int numval; } attribute; } TokenRecord;
后一种形式假定标识符只需要字符串值,而数字只需要数值。一个更常用的方法是:扫描器仅返回标记值,其它属性都放在编译器的其它部分可以访问的变量中。

扫描器的任务是转换整个源程序为标记序列,但是扫描器几乎不会只扫描一次。相反,扫描器在语法分析器的控制下进行词法分析,通过类似这样的函数按需返回单个标记:
TokenType GetToken();
此函数被调用是,从输入返回下一个标记,并计算额外的属性,比如标记的字符串值。输入的字符串一般不作为函数的参数,而是被保留在缓冲区,或由系统输入设备提供。
在读取并返回标记时,需要跳过空白字符。在完整读取完一个标记后,停止读取。
2.2 正则表达式
正则表达式(regular expression,regex,RE)代表字符串的模式。一个正则表达式r完全是由它匹配的字符串集定义的。这个字符串集合称为正则表达式生成的语言(language generated by the regular expression),记为L®。“语言”一词在这里仅仅是用于描述“一组字符串”,与编程语言没有关系。这个语言首先依赖于可用的字符集。一般地,可用字符集是ASCII字符集或其子集,也可以是ASCII字符集的超集,这时字符集的元素也称符号(symbols)。这一组合法符号称为字母表(alphabet),常记作Σ。
正则表达式r也会包含字母表中的字符,但这些字符的意义不同:在正则表达式中,所有符号都代表模式(pattern)。此外,正则表达式r中的一部分字符可以具有特殊意义,称为元字符(metacharacter)或元符号(metasymbol)。这些通常不是字母表中的合法字符,但有时也会存在于字母表。为了将元字符与字母表的字符区别,一般在它们之前添加转义字符(escape character)。转义字符通常是反斜杠“\”或引号“’”。转义字符也是元字符。

设字母表Σ中有字符a。正则表达式a匹配字符a:
L(“a” )={a}
我们用符号ε代表空串,元符号"ε" 的定义为
L(“ε” )={ε}
如果一个正则表达式无法匹配任何字符串,则该式生成的语言是空集:
L(“ϕ” )={}
注意{}和{ε}是不同的:后者包含一个空串。

正则表达式有三种基本运算:
【1】从替代项中选择。用元字符“|”表示。
设有正则表达式r,s。则r|s匹配任何匹配r或s的字符串。即
L(r│s)=L®∪L(s)
此外,我们有
L(“a” │"ε" )={a,ε}
【2】连接(concatenation)。连接运算不使用任何元字符,直接并列列写。
设有正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值