编译原理入门:CS-Notes词法与语法分析基础
你是否在学习编程时遇到过这些问题:为什么写代码时少个分号会报错?为什么编译器能自动发现语法错误?编译原理中的词法分析(Lexical Analysis)和语法分析(Syntax Analysis)正是解决这些问题的核心技术。本文将结合CS-Notes项目的学习资源,用通俗的语言带你掌握这两个基础概念,读完后你将能理解编译器如何"读懂"你的代码。
编译原理在CS-Notes中的定位
CS-Notes作为计算机科学学习资料的精选项目,涵盖了算法、操作系统、数据库等多个领域的知识。在项目主页的知识体系中,编译原理相关内容虽未单独列为一级章节,但贯穿于多个核心模块:
- 算法模块:Leetcode 题解中字符串处理题目涉及词法分析思想
- 工具模块:正则表达式是词法分析的重要工具
- Java模块:Java 虚拟机的类加载过程包含类似编译的解析步骤
词法分析:代码的"分词"过程
词法分析是编译的第一阶段,它将源代码字符串分割成一个个有意义的词法单元(Token),就像我们阅读文章时会自动将句子分成词语一样。
词法单元的种类
在编程语言中,常见的词法单元包括:
- 关键字:如Java中的
class、public - 标识符:变量名、函数名等用户定义的名称
- 常量:如
42(整数)、3.14(浮点数)、"hello"(字符串) - 运算符:如
+、-、*、/ - 分隔符:如
;、{、}、(、)
正则表达式:词法分析的利器
CS-Notes的正则表达式章节详细介绍了如何用模式匹配来识别不同的词法单元。例如:
- 整数可以用正则表达式
\d+匹配 - 标识符通常用
[a-zA-Z_]\w*匹配(以字母或下划线开头,后跟字母、数字或下划线)
词法分析器工作流程
- 从源代码中读取字符流
- 根据预定义的正则表达式规则识别词法单元
- 过滤掉空格、注释等无关字符
- 将识别出的词法单元传递给语法分析器
语法分析:代码的"语法检查"过程
语法分析是编译的第二阶段,它根据编程语言的语法规则(通常用上下文无关文法表示),将词法分析产生的Token序列组织成抽象语法树(AST)。
上下文无关文法
上下文无关文法由四部分组成:
- 终结符:即词法分析产生的Token
- 非终结符:表示语法结构的符号,如
<表达式>、<语句> - 开始符号:通常是
<程序>或<编译单元> - 产生式:描述如何从非终结符推导终结符序列的规则
例如,一个简单的表达式文法可以定义为:
<表达式> → <项> | <表达式> + <项> | <表达式> - <项>
<项> → <因子> | <项> * <因子> | <项> / <因子>
<因子> → 数字 | ( <表达式> )
抽象语法树(AST)
AST是源代码语法结构的树形表示,它去掉了与语法分析无关的信息(如括号、分号等分隔符),只保留关键的语法结构。例如,表达式1 + 2 * 3的AST可以表示为:
+
/ \
1 *
/ \
2 3
常见语法错误
语法分析器能够检测出源代码中的语法错误,例如:
- 缺少分号:
int a = 5(正确应为int a = 5;) - 括号不匹配:
if (a > b { ... } - 语法结构错误:
int a + b;
从源码到可执行文件:编译的完整流程
词法分析和语法分析是编译过程的前两个阶段,完整的编译流程还包括:
- 语义分析:检查代码的语义正确性,如类型匹配、变量未定义等
- 中间代码生成:将AST转换为一种中间表示形式(如三地址码)
- 代码优化:改进中间代码,提高执行效率
- 目标代码生成:将优化后的中间代码转换为机器语言或字节码
实践:用CS-Notes资源深入学习
推荐学习路径
扩展资源
- Leetcode 字符串处理题目:实践词法分析相关算法
- 设计模式:了解编译器中常用的设计模式
总结
词法分析和语法分析是编译器的基础,它们分别解决了"代码由哪些基本单元组成"和"这些单元如何构成合法的程序"这两个核心问题。通过CS-Notes提供的丰富学习资源,你可以系统地掌握这些知识,并将其应用到实际的编程和问题解决中。
如果你在学习过程中遇到困难,欢迎参考项目的官方文档或参与社区讨论。点赞、收藏本文,关注CS-Notes项目,获取更多计算机科学基础知识!
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考




