笔记 | 编译原理L2:词法分析(lexical analysis)

本文详细阐述了词法分析在编译过程中的作用,介绍了词法单元、词素、终结符和非终结符的概念,以及正则表达式和有限状态自动机在语言定义中的应用。重点讲解了DFA和NFA的区别以及它们在识别语言中的角色。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1 概述

词法分析(lexical analysis),也称scanning, 编译程序的第一阶段,其作用是识别单词(程序意义上)并找出词法错误. 读入源程序的输入字符、将它们拆分成词素,生成并输出一个词法单元序列,每个词法单元对应于一个词素

image.png|500

回顾词法分析在整个编译过程的位置

![[【笔记】编译原理L1#^53d248| 回顾编译原理的各个模块顺序]]

1.1 词法分析的常见做法

  • 由语法分析器调用,需要的时候不断读取、生成词法单元。这样可以避免额外的输入输出。
  • 词法分析可以使用:[[【笔记】编译原理L2:词法分析(lexical analysis)#3.2 正则表达式 | RE]] 和 [[【笔记】编译原理L2:词法分析(lexical analysis)#3.4 正则语言(RL)| RL]]

Note:在识别出词法单元之外,还会完成一些不需要生成词法单元的简单处理,比如删除注释、将多个连续的空白字符压缩成一个字符

1.2 一些经典名词

词素(Lexeme) 词法单元 (Token) <词法单元名、属性值(可选)> 词性划分
源程序中的字符序列,它和某类词法单元的模式匹配,被词法分析器识别为该词法单元的实例。 单元名是表示词法单位种类的抽象符号,语法分析器通过单元名即可确定词法单元序列的结构, 是有意义最小的程序单位。属性值通常用于语义分析之后的阶段image.png 根据作用对程序子串进行分类image.png
  1. 词法分析的输出是单词(token)的序列<词法单元名、属性值(可选)>:
    image.png
  2. Token序列将作为语法分析程序的输入:
  3. 一个具体的示例:
    image.png

2 语言的定义

2.1 什么是语言

  1. 作用:沟通,交流,传递信息
  2. 自然语言:英语,中文,日语

2.2 你如何定义语言?

  1. 无限的集合
  2. 抽象地来看:字符组成了单词; 单词组成了句子; 句子携带了信息
  • 语言是形式化的内容提取——单词、句子、语言:是三种不同的语言
单词(Token) 句子(Sentence) 语言(Language)
满足一定规则的字符(Character)串 满足一定规则的单词序列 满足一定条件的句子集合

示例:程序设计语言:形式化的内容提取

程序设计语言(Programming Language) 程序(Program) 语句(Sentence) 单词(Token)
组成程序的所有语句的集合。 满足语法规则的语句序列 满足语法规则的单词序列。 满足词法规则的字符串
  • 语言是字和组成字的规则
    “doge”(it’s not a word ): reserved words and some rules forwords (词法)
    “Long time no see”(It’s not a correct sentence): rules forsentences(语法)
    检查单词错误是词法负责的范畴,检查句子错误是语法负责的范畴

  • 语言是用有限的规则来描述的无限集

  • 语言的组成部分

符号 (Symbol/Character) 字母表 符号串(字符串)
语言中不可再分的单位 符号的非空有穷集合,Σ,V或其它大写字母, 其中的元素可称为字母、符号、字符。例如:V1 = {a, b, c}, V2 = {+, -, 0, 1, …,9}, Σ= {x|x∈ASCII字符} 某字母表上的符号的有穷序列。a, b, c, abc, bc,…:V1上的符号串; 1250, +2, -1835,…:V2上的符号串。空串(ε):不含任何符号的串
  1. 语句: 字母表上符合某种构成规则的符号串序列。
  2. 语言 L:某字母表上的语句的集合: L(Σ); 注意:定义在同一个字母表上的语言有很多!
    比如:Σ定义了语言中允许出现的全部符号;若Σ = 英文字母,L(Σ)是英文句子, 若Σ = ASCII字符, L(Σ)可以定义成C语言程序,但也可以定义成Java程序或者其他的程序语言,这里就可以构成多种语言。(此现象产生的原因:L(Σ)是字符串集合,但不是包含Σ上任意的字符串,而是满足某种规则的字符串——引出了我们要如何定义规则?

2.3 如何定义规则

文法(G, Grammar): 四元组G = ( V N V_{N} VN , V T V_{T} VT , S S S, P P

实验1 词法分析 一、 实验目的 调试并完成一个词法分析程序,加深对词法分析原理的理解。 二、 实验要求 1、 待分析的简单语言的词法 (1) 关键字: begin if then while do end 所有关键字都是小写。 (2) 运算符和界符: := + – * / < <= <> > >= = ; ( ) # (3) 其他单词是标识符(ID)和整型常数(NUM),通过以下正规式定义: ID=letter(letter| digit)* NUM=digit digit * (4)空格由空白、制表符和换行符组成。空格一般用来分隔ID、NUM,运算符、界符和关键字,词法分析阶段通常被忽略。 2、 各种单词符号对应的种别码 单词符号 种别码 单词符号 种别码 begin 1 : 17 if 2 := 18 then 3 > 20 while 4 <> 21 do 5 <= 22 end 6 < 23 letter(letter| digit)* 10 >= 24 digit digit * 11 = 25 * 13 ; 26 / 14 ( 27 + 15 ) 28 - 16 # 0 3、 词法分析程序的功能 输入:所给文法的源程序字符串。 输出:二元组(syn,token或sum)构成的序列。 其中:syn为单词种别码; token为存放的单词自身字符串; sum为整型常数。 三、结果验证 给定源程序 begin x:=9; if x>0 then x:=2*x+1/3; end# 输出结果。 四、源程序代码如下: #include<stdio.h> #include<string.h> #include<iostream.h> char prog[80],token[8]; char ch; int syn,p,m=0,n,sum=0; //p是缓冲区prog的指针,m是token的指针 char *rwtab[6]={"begin","if","then","while","do","end"}; void scaner() { for(n=0;n<8;n++) token[n]=NULL; ch=prog[p++]; while(ch=='_') 执行语句1; if((判断ch是字母字符的条件)) { m=0; while((ch>='A'&&ch<='Z')||(ch>='a'&&ch<='z')||(ch>='0'&&ch<='9')) { token[m++]=ch; ch=prog[p++];} token[m++]='\0'; p--; syn=10; for(n=0;n<6;n++) if(加入判断条件) {syn=n+1; break; } } else if(判断ch是数字字符的条件)' { sum=0; while(ch>='0'&&ch<='9') { sum=sum*10+ch-'0'; ch=prog[p++]; } p--;执行语句2; } else ………完成剩余程序代码 }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eternal_U

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值