在编译原理中,词法分析、语法分析和语义分析是编译器前端的三个核心阶段,它们逐层递进,逐步将源代码转化为可执行的结构化表示。以下是它们的区别、对应阶段及示例的详细说明:

1. 词法分析(Lexical Analysis)

阶段定位

输入:源代码字符串(如  int a = 42 + b; )。

输出:词法单元(Token)序列(如  [KEYWORD(int), ID(a), OP(=), NUM(42), OP(+), ID(b), OP(;)] )。

核心任务:将字符流拆解为有意义的词法单元,忽略空格、注释等无关内容,并构建符号表的初始条目。

示例

输入代码:

int main() { return 0; }
词法分析结果:

[KEYWORD(int), ID(main), OP(() , OP()), OP({), KEYWORD(return), NUM(0), OP(;), OP(})]

特点

工具:Lex、Flex 等生成词法分析器。

错误类型:非法字符(如  printf("Hello)  缺少右引号)、无效标识符(如  123var )。

2. 语法分析(Syntax Analysis)

阶段定位

输入:词法分析生成的 Token 序列。

输出:抽象语法树(AST),表示代码的层次结构。

核心任务:根据语法规则(如上下文无关文法)验证 Token 序列的结构合法性,构建语法树。

示例

输入 Token 序列:
 [KEYWORD(int), ID(main), OP(() , OP()), OP({), ...] 

语法分析结果:

FunctionDecl
├─ Type: int
├─ Name: main
├─ Parameters: ()
└─ Body: Block
    └─ ReturnStmt
        └─ Num(0)

特点

工具:Yacc、Bison 等生成语法分析器。

错误类型:语法结构错误(如缺少分号、括号不匹配)。

 

3. 语义分析(Semantic Analysis)

阶段定位

输入:AST 和符号表(包含变量类型、作用域等信息)。

输出:注解后的 AST(附加类型、作用域等语义信息)。

核心任务:检查逻辑正确性,如类型匹配、变量作用域、函数参数合法性等。

示例

输入 AST 节点:
 BinaryOp(ADD, INT(10), STRING("hello")) 

语义分析结果:
报错: 类型不匹配,无法将字符串与整数相加 。

特点

关键检查:类型检查、作用域分析、常量折叠。

错误类型:类型不匹配(如  int a = "hello"; )、未声明变量(如  x = 5; )。

三阶段对比

维度词法分析语法分析语义分析
输入源代码字符串Token 序列AST + 符号表
输出Token 序列 + 符号表AST注解后的 AST
核心规则正则表达式、有限自动机上下文无关文法(CFG)属性文法、类型系统
错误类型非法字符、无效标识符结构错误(如缺少分号)逻辑错误(如类型不匹配)
工具Lex、FlexYacc、Bison自定义类型检查器

 

实际代码示例

输入代码
int arr[2], b;
b = arr * 10;

各阶段处理

词法分析:
生成 Token 序列: [KEYWORD(int), ID(arr), OP([), NUM(2), OP(]), OP(,), ID(b), OP(;), ...] 。

语法分析:
验证数组声明和赋值语句的结构合法性,生成 AST。

语义分析:
检测到  arr  是数组类型,不能作为乘法运算符的操作数,报错: 语义错误:数组变量不能参与算术运算 。

 

总结

词法分析是编译的起点,关注字符流的拆分;

语法分析关注结构合法性,构建代码的抽象表示;

语义分析确保代码逻辑正确,补充类型和作用域信息。
三者层层递进,共同为后续的中间代码生成和优化奠定基础。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐