语法错误是什么?
语法错误(syntax error)是代码结构上的错误,比如少了冒号、括号或引号,违反了编程语言的语法规则。编译器或解释器会在程序运行任何一行之前就拒绝它。
更新于 2026年9月24日
Python 在运行你的程序的任何一行之前,会先读取整个文件,检查它是否符合这门语言的语法。只要有一行违反了语法,就什么都不会运行。运行下面的程序,留意没有发生的事:第一个 print 根本没有打印。
File "main.py", line 4
if temperature > 30
^
SyntaxError: expected ':'
第 1 行完全合法,可输出里却没有“Checking the temperature”。Python 拒绝了整个文件,因为 if 行必须以冒号结尾。在 30 后面加上 :,再运行一次,两行就都打印出来了。
语法错误是如何被发现的
每种编程语言都有自己的语法:允许使用哪些词,括号在哪里开、在哪里闭,if 后面必须跟什么。负责检查语法的程序叫作解析器,它工作在把源代码转换成机器可执行内容的第一个阶段。
- 分词器把文本拆分成一个个记号(token):
if、temperature、>、30等等。 - 解析器按顺序读取这些记号,把它们套进语法规则里。在
if temperature > 30之后,它期待一个:,却遇到了行尾。 - 它停下来,报告它放弃的位置:文件名、行号,以及位置下方的一个脱字符(
^)。 - 因为解析失败,不会生成任何代码,所以程序一行都不会运行。
在 CPython 中,每次启动脚本时都会运行解析器。在有单独构建步骤的语言里,由编译器做这项检查:只要还有一个语法错误,gcc、clang 和 javac 就拒绝生成程序。这就是为什么语法错误被归入编译时错误,而运行时错误则发生在程序已经运行之后。
Python 中常见的语法错误
初学者遇到的大多数语法错误都来自下面这些写法,表中是 Python 3.12 打印的原始信息。
| 代码 | 信息 | 修复方法 |
|---|---|---|
if x > 3 | SyntaxError: expected ':' | if、for、while、def 和 class 行要以 : 结尾 |
print("Hi" | SyntaxError: '(' was never closed | 打开的每个括号都要闭合 |
name = "Ada | SyntaxError: unterminated string literal (detected at line 1) | 把引号闭合 |
if x = 5: | SyntaxError: invalid syntax. Maybe you meant '==' or ':=' instead of '='? | 用 == 做比较 |
print "Hi" | SyntaxError: Missing parentheses in call to 'print'. Did you mean print(...)? | Python 3 需要写成 print(...) |
if a > 0 && b > 0: | SyntaxError: invalid syntax | Python 使用 and、or 和 not |
if 下面没有缩进的代码行 | IndentationError: expected an indented block after 'if' statement on line 1 | 把代码体缩进四个空格 |
IndentationError 是 SyntaxError 的一种:在 Python 中,缩进本身就是语法的一部分。
并不是每个拼写错误都是语法错误。pritn("hello") 完全符合语法,因为名字后面跟着括号就是一次函数调用。Python 直到执行到这一行,才会发现并不存在叫 pritn 的函数,然后抛出 NameError: name 'pritn' is not defined. Did you mean: 'print'?。这是运行时错误,它上面的代码行都已经运行过了。
为什么报告的行号可能不对
解析器报告的是它无法再继续的位置,而这并不总是错误所在的位置。没有闭合的括号就是典型的例子:解析器要读过本该闭合括号的地方之后,才能知道这个括号没有闭合。
File "main.py", line 1
prices = [4.50, 3.20, 7.80
^
SyntaxError: '[' was never closed
Python 3.10 及以后的版本会指向第 1 行开头的 [。Python 3.9 及更早的版本只会在第 2 行报告 invalid syntax,也就是真正出错那一行的下一行。所以,当报告的那一行看起来没问题时,就去检查上一行的末尾。
其他解析器也是这样。对于把 FROM 拼错了的 SELECT name FORM users;,SQLite 会把 FORM 当作 name 列的别名(第二个名字),直到再往后一个词才报错:
Parse error near line 1: near "users": syntax error
SELECT name FORM users;
^--- error here
C、Java 和 JavaScript 中的语法错误
编译型语言在构建时报告语法错误,而不是在运行时。下面是一个少了分号的声明,用 Clang 编译(在 macOS 上,gcc 命令实际运行的就是这个编译器):
#include <stdio.h>
int main(void) {
int count = 3
printf("%d\n", count);
return 0;
}
main.c:4:18: error: expected ';' at end of declaration
把它粘贴到 C 语言在线编译器里,看看 GCC 对同一个错误是怎么描述的。
在 Java 中,javac 把同样的错误报告为 error: ';' expected,并且不会写出 .class 文件。在 C 语言中,少一个大括号可能会在文件后面引出一连串错误。先修复第一个,再重新编译,因为其他错误往往是由它引起的。
V8 这样的 JavaScript 引擎会在运行之前解析整个脚本,和 Python 一样。Node.js 会在打印“start”之前就拒绝这个文件:
console.log("start");
if (x > 1 {
console.log("big");
}
SyntaxError: Unexpected token '{'
在浏览器中,语法错误只会让出错的那个脚本文件无法运行,页面上的其他脚本照常运行。
如何修复语法错误
- 先读信息的最后一行。它说明了问题所在:少了
:、(没有闭合、出现了意外的记号。 - 找到报告的那一行,看脱字符指向哪里。如果这一行看起来没问题,就检查上一行。
- 检查成对的符号。每个
(、[、{和引号都需要有另一半。大多数编辑器在光标靠近括号时,会高亮显示与之匹配的那个括号。 - 检查语言要求的标点:Python 中的冒号和缩进,C、Java 和 JavaScript 中的分号和大括号。
- 只修复第一个错误,然后重新运行。后面的报错往往是第一个错误引起的。
- 留意语法高亮。少了一个引号之后,文件剩下的部分通常都会变成字符串的颜色,由此就能看出问题从哪里开始。
好消息是,语法错误是最容易修复的一类错误:工具会告诉你哪里出了问题,以及大致的位置。更难对付的错误要等到代码运行时才会出现。
下一步学什么
通过了解析器的程序,在运行时仍然可能崩溃,这就是运行时错误。程序一直运行到结束、却打印出错误答案,说明它有逻辑错误,那一页还用一张表格对比了全部三种错误类型。想了解语法规则本身,可以阅读 Python 语法或 C 语言语法,再到 Python 课程中练习。
常见问题
语法错误有哪些例子?
print("Hello" 少了右括号,就是一个语法错误;在 Python 中,if 行少了冒号也是:if x > 3。在 C 和 Java 中,最常见的是语句末尾少了分号。所有这些情况下,代码都不符合语法,所以无法运行。语法错误和语义错误有什么区别?
int;另一些书则把它当作逻辑错误的另一种叫法。C 语言中的语法错误是什么?
gcc 和 clang 会打印文件名、行号和列号,例如 main.c:4:18: error: expected ';' at end of declaration,并且在所有错误修复之前不会生成可执行文件。为什么 Python 不自动修复语法错误?
Did you mean print(...)?,但决定权留给你。计算器上的 syntax error 是什么意思?
ERR:SYNTAX。