编程语言的语法和语义之间有什么区别?


Answers:


201

语法与语言的结构或语法有关。它回答了以下问题:如何构造有效的句子?所有语言,甚至英语和其他人类(也称为“自然”)语言都具有语法,即定义句子是否正确构建的规则。

以下是一些C语言语法规则:

  • 用分号分隔的语句
  • 将IF语句的条件表达式括在括号内
  • 通过将花括号括起来将多个语句组合为一个语句
  • 数据类型和变量必须在第一个可执行语句之前声明(此功能已在C99中删除。C99和后者允许混合类型声明。)

语义与句子的含义有关。它回答了以下问题:这句话是否有效?如果是这样,那句话是什么意思?例如:

x++;                  // increment
foo(xyz, --b, &qrs);  // call foo

是语法上有效的C语句。但是它们是什么意思呢?尝试将这些语句转换为可执行的指令序列甚至有效吗?这些问题是语义学的核心。

在第一条语句中考虑++运算符。首先,尝试这样做是否有效?

  • 如果x是float数据类型,则此语句没有任何意义(根据C语言规则),因此即使该语句在语法上正确,也将是错误的。
  • 如果x是指向某种数据类型的指针,则该语句的意思是“将sizeof(某种数据类型)添加到地址x的值并将结果存储到地址x的位置”。
  • 如果x是标量,则该语句的含义是“在地址x的值上加一个并将结果存储到地址x的位置”。

最后,请注意,某些语义无法在编译时确定,因此必须在运行时进行评估。在++运算符示例中,如果x已经是其数据类型的最大值,那么当您尝试向其添加1时会发生什么?另一个例子:如果您的程序尝试取消引用值为NULL的指针会发生什么?

总而言之,语法是仅针对句子本身是否对该语言的语法有效的概念。语义是关于句子是否具有有效含义。


好。如果x将的数据1设为最大值并添加到数据中,则会导致输出奇怪的输出(0),这不是语义错误吗?
c

考虑一下车辆中的里程表-它具有一系列相互关联的车轮,每个车轮上都印有数字0到9。最右边的车轮旋转最快;当它从9绕回零时,车轮向左立即前进1。当此轮从9前进到0时,其左轮前进,依此类推。
Jeff N

数据类型就像里程表的轮子一样:它只能保持一定的值。当达到最大值时,下一个超前会使车轮返回零。这是否是语义错误取决于语言规则。在这种情况下,您需要参考C语言标准。我不完全知道C语言标准在说什么,但是这里有一些选择。溢出是:-不是错误;结果为零。-一个错误; 编译器必须产生一个溢出异常。-未定义;编译器可以自由执行任何所需的操作。
杰夫N

2
如果有人在乎特定示例,则将无符号溢出定义为模块化算术(so UINT_MAX + 1 == 0)。签名溢出未定义。现代编译器通常都有INT_MAX + 1 == INT_MIN,但有你不能指望这样的情况如(for (i = 0; i <= N; ++i) { ... }这里NINT_MAX不是无限取决于优化;见blog.llvm.org/2011/05/what-every-c-programmer-should-know。 html)。
Daniel H

“请注意,某些语义无法在编译时确定,因此必须在运行时进行评估” –我喜欢这种语义与自然语言的相似之处。没有上下文,您无法知道某些短语的含义。例如,在短语“他喜欢香蕉”中,“他”的含义取决于上下文。
ymln

21

语法是指一种语言的结构,其词源可追溯到事物的组合方式。
例如,您可能需要通过声明一个类型,一个名称,然后一个分号来将代码组合在一起,以使语法正确。

Type token;

另一方面,语义是关于意义的。编译器或解释器可能会抱怨语法错误。您的同事会抱怨语义。


@Talespin_Kit的含义而不是结构:逻辑更像是一个抽象,例如P => Q,等等或!! P = P,但是当添加语义时,内容可能会很微妙,如果P为“ happy”,则!! P为“ I “不是不开心”!=“我很开心”
doctorlove

5
+1表示“编译器或解释器可能会抱怨语法错误。您的同事将抱怨语义。”
GeekyJ

11

维基百科有答案。阅读语法(编程语言)语义(计算机科学)维基页面。

或考虑任何编译器解释的工作。第一步是词法分析 ,其中通过将字符串划分为词素然后解析来生成标记,该标记构建了一些抽象语法树(表示语法)。下一步涉及转换或评估这些AST(语义)。

另外,请注意,如果您定义了C的变体,其中每个关键字都被转换为它的法文等效项(因此if成为sido成为faireelse成为sinon等),您肯定会更改语言的语法,但不会做太多改变语义:用French-C编程不会更容易!


8

语义就是您的代码的含义-可能用伪代码描述的内容。语法是实际的结构-从变量名到分号的所有内容。


这是不同人之间的对话吗?还是仅仅是一个帖子?我不明白 例如:“不知道以下含义是什么。这再错不过了”。
doubleOrt

4

语法是表达式,语句和程序单元的结构或形式,而语义是这些表达式,语句和程序单元的含义。语义学直接源自语法语法指的是特定编程语言指定的代码结构/形式,但是语义处理分配给符号,字符和单词的含义。


4
  • 您需要正确的语法进行编译。
  • 您需要正确的语义才能使其正常工作。

1

编程语言的语法是其表达,语句和程序单元的形式。它的语义是那些表达式,语句和程序单元的含义。例如,Java while语句的语法是

while (boolean_expr) statement

此语句形式的语义是,当布尔表达式的当前值为true时,将执行嵌入式语句。然后,控件隐式返回布尔表达式以重复该过程。如果布尔表达式为false,则控制转移到while构造之后的语句。


1

语法:它指的是语言的语法结构。您必须非常小心地使用数据类型,标记[它可以是文字或符号,例如“ printf()”。它具有3个令牌,“ printf,(,)”]。同样,您必须非常小心如何使用函数,函数语法,函数声明,定义,初始化和调用它。

在语义上,它与句子或陈述的逻辑或概念有关。如果您出于概念或逻辑说或写某事,那么您在语义上是错误的。


1

了解编译器如何看待代码

通常,代码的语法和语义分析是在编译器的“前端”部分完成的。

  • 语法:编译器为每个关键字和符号生成令牌:令牌包含关键字的信息类型及其在代码中的位置。使用这些标记,可以创建并分析AST(抽象语法树的缩写)。编译器实际上在这里检查的是代码是否在词法上有意义,即“关键字序列”是否符合语言规则?如先前答案中所建议,您可以将其视为语言的语法(而不是代码的含义/含义)。旁注:此阶段报告语法错误。(将具有错误类型的令牌返回给系统)

  • 语义:现在,编译器将检查您的代码操作是否“有意义”。例如,如果语言支持类型推断,则在尝试将字符串分配给浮点数时将报告语义错误。或两次声明同一变量。这些是“语法上” /语法上正确的错误,但在操作过程中没有任何意义。旁注:为了检查同一变量是否被声明两次,编译器管理符号表

因此,这两个前端阶段的输出是带注释的AST(具有数据类型)和符号表。

以不太技术的方式了解它

考虑到我们使用的普通语言;在这里,英语:

他去学校了。-错误的语法/语法,尽管他想传达正确的意义/语义。

他去感冒了。-感冒是一个形容词。用英语,我们可能会说这不符合语法,但实际上它是我想到的最接近具有正确语法的不正确语义的示例。


编译器 该链接可能对学习更多有所帮助
Vedant Panchal
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.