语法和语义之间有什么区别?


87

我一直认为引用语言的语法与引用语言的语义相同。但我已获悉,显然并非如此。有什么不同?



6
在语法上,“无色的绿色想法疯狂地睡觉”是可以的,但没有语义上的意义。参见en.wikipedia.org/wiki/Colorless_green_ideas_sleep_furiously
CesarGon 2011年

+1提出这个问题。我想知道同样的事情,太懒了,无法在互联网上搜索它,并且显然从来没有问过。
KK。

或多或少,我会说...语义是实例的类型,它们与其他实例的关系以及它们之间存在的保证。语法是通过字符串声明这些内容的方法。或多或少。
德博普

Answers:


106

语义〜意义

语法〜符号表示

因此,用不同语言编写的两个程序可以完成相同的操作(语义),但是用于编写程序的符号将有所不同(语法)。

编译器将为您检查语法(编译时错误),并从语言规则中导出语义(将语法映射到机器指令上),但是不会找到所有语义错误(运行时错误,例如计算错误的结果,因为代码说加1而不是加2)。


2
错误检查不是区分语法和语义的标准。编译器可以而且必须诊断语法错误(例如缺少分号)和语义错误(例如对于那些操作数x + y没有合适的+运算符的地方)。我称逻辑错误为1而不是2 。
基思·汤普森

3
@Keith-但是逻辑(如“逻辑错误”)是语义。编译器可以完成一些语义检查,尤其是类型检查,因此我同意编译器不仅会发现语法错误,而且克里斯只说“ 不会发现所有语义错误”,这并不意味着“ 无法找到 ”。找到任何 “。
Steve314,2011年

1
@ Steve314:同意。但是,如果您想在编译器必须检测到的错误与它不需要检测到的错误之间进行严格区分,那么我认为“语义”与“逻辑”是表达这种区分的好方法。
基思·汤普森

4
@KeithThompson实际上,从理论上讲,具有足够强大的功能(即,依赖)类型系统的语言的编译器或解释器可以检查代码的任何任意属性(对Halting问题进行模运算,如果适用),从而将语义错误分解为通常,“可检查”和“不可检查”实际上没有任何意义。
帕萨里恩(Ftharien)的火焰2012年

@ Ptharien'sFlame通过突出您声明的“理论上”部分,我将把讨论从云端撤出一秒钟。在实践中,在代码中强制执行语义需要附加语法以使编译器可以了解其功能。额外的语义检查是有代价的(即复杂性/可读性)。说一种语言可以强大到可以检查所有语义错误,就好像说一个法律体系可以足够完善以防止所有犯罪。就个人而言,我宁愿自由而不是安全,但这就是使这成为“宗教”主题的原因。
Evan Plaice

35

实际上,没有两个级别,而是三个:

  • 词汇水平:如何组合字符以产生语言元素(if产生if
  • 语法级别:如何语言元素被组合以产生语言表达(if(42==answer)产生一个条件语句)
  • 语义级别:如何将语言表达式转换为CPU指令以形成含义(条件语句允许执行一个分支或另一个分支,具体取决于布尔表达式的结果)

10
在词法分析阶段与解析阶段之间的分离完全是人为的,无非是一种优化。在某些语言中,没有定义词素的有限平面集-但仍然有明确定义的语法。因此,我宁愿将词素定义为语法的一部分,不是一个单独的实体。
SK-logic

@ SK-logic:在许多语言中,指定了构成变量名称的授权或禁止的词素的列表。因此,分离是有意义的。
mouviciel 2011年

5
@mouviciel,仅作为优化才有意义-否则,您将只有一个ValidIdentifier终端,可以将其定义为类似的东西![AnyKeyword] [Identifier](我在这里使用的是类似PEG的表示法)。对于这种语言,您不需要单独的词法传递。例如,请参阅基于GLR的C ++解析器。
SK-logic

2
@EvanPlaice,您在说什么?我的观点是,词汇分析不是必需的(实际上限制了您的语言),不是解析
SK-logic

1
@ SK-logic我想我读了您的评论意味着与您想要的相反。我以为您是在谈论仅需要词法分析器的情况-例如纯“常规”或“无上下文”语言。在高级语言中,词法分析程序可能不是必需的,但它提供了一种运行单遍语法验证的快速方法。我完全同意,在许多情况下,关闭或完全消除词法分析器阶段将是有益的。
Evan Plaice

18

我将用一个简单的语言示例向您解释ENGLISH

The glass drank Ben

是句法正确的陈述。它具有名词,动词等。

但是从语义上讲这是错误的,因为该陈述没有可想像或正确的含义。


15

语义描述编程语言的逻辑实体及其交互。语法定义了这些字符如何表达。

例如,指针算术的概念是C语义的一部分。的方式+-运营商可以用来表达指针操作是其语法的一部分。

有时,两种语言共享其部分语义,但是语法却大相径庭(例如C#和VB.NET-都使用值类型和引用类型,但是键入定义它们的字符是不同的)。在其他情况下,两种语言在语法上是相似的,但是语义却不匹配(考虑Java与JavaScript,在相似之处通常会使初学者感到困惑)。


那么,“范式”与语义相关吗?我的意思是范式是一组相互关联的语义?
Gulshan

1
@Gulshan,范式是一个比这种形式化的东西作为语义更为广泛的概念。范式可能包括语义,但它更多是一种方法论,甚至更广泛的是一种哲学。
SK-logic


5

您没有指定是仅引用编程语言还是编程中使用的通用语言,因此我的答案是关于数据语言(例如XML,RDF,数据类型系统等)的:

布赖恩·米克(Brian L. Meek)在他的七个独立于语言的标准的黄金法则(1995年)中写道:“一种语言的语法可以是另一种语言的语义”。他指的是数据描述中使用的“语法”和“语义”一词:因此,如果您在某种数据格式的规范中偶然发现这些词,则最好用“ Potrzebie”替换这两个词,以明确表示您必须解决对自己的意义。

至少在精确指定的数据中,语法和语义之间的关系可以用术语“编码”更好地描述。语义以语法编码。由于录音可以嵌套,因此一种语言的语法就是另一种语言的语义。如果超出了数据领域,则这种嵌套实际上是无限的,正如Umberto Eco所说的那样,它是“无限符号学”。

举个例子:

  • XML语法(带有所有这些括号的东西)是将XML Infoset(抽象树)作为语义的语法。
  • XML Infoset作为语法可以将某种XML数据格式的记录表示为语义,例如,对RDF图进行编码的RDF / XML文档。
  • RDF图(带有URI引用的东西)作为语法将抽象资源图编码为语义。
  • 作为语法的抽象资源图将概念模型编码为语义。

人们通常会在某种程度上停下来并把它当作语义,但最终除非存在某些人在脑海中解释数据的情况,否则就没有最终的语义。一旦人们试图以数据形式表达语义,它就会成为语法。


4

如果可以用BNF(巴克斯-纳尔形式)或类似形式描述它,那是语法。如果不能,那不是。

另一方面,语义与程序(或其他源代码块)的含义有关。

有时两者之间的界限可能会模糊。

一种理解区别的方法是查看程序语法或语义不正确时遇到的各种错误。

语法错误是指源代码无法匹配语言语法,例如,在需要使用分号的地方没有分号。

语义错误是无法满足其他语言要求(例如C称为“约束”);一个例子可能是写x + y在那里x,并y是不兼容的类型。语言语法告诉您,加法看起来像something + something,但是它的功能不足以表达对左右操作数类型的要求。

(逻辑错误,例如使用1表示2是正确的错误,通常不会被编译器检测到-尽管在某些情况下,编译器会警告可疑代码。)


0

语法是(词汇)符号所说的。语义就是他们的意思。

考虑:

C#:condition ? true_value : false_value
VB.NET:If(condition, true_value, false_value)
-不同的语法,相同的语义。

C#:left_value / right_value
VB.NET:left_value / right_value
-相同的语法,不同的语义(对于整数)。


0

语法是句子中单词的语法安排,即单词顺序。

(英语)“ cat dog boy ”和(编程)“ hi.5 ”在语法上正确。

(英语)“ 猫抱着男孩 ”,(编程)“ * 3.2 * 5 *”在语法上有效。

静态语义是语法上有效的语句是否具有任何含义。

(英语)' 我很大 '(编程)(python)' 3 +'hi' '在语法上是正确的,但具有静态语义错误。

语义是与语法正确的符号字符串相关联的含义,没有静态的语义错误,即句子在语法和语义上都是正确的,但其含义可能不是所要的。

(英语)“ 飞行中的飞机可能是危险的 ”可以有两种含义,即飞行中的飞机可能有危险或正在飞行中的飞机有危险。

(编程)“计算机不会生成任何错误消息,但不会执行您告诉计算机的操作;它将做其他事情。

来源:MIT 6.00.1


-2
  1. 语法是指规范某种语言中有效语句的构造的正式规则。语义是指给出陈述含义的一组规则。

  2. 当违反或滥用编程语言规则时,在程序中会发生由于语法引起的错误。当语句没有意义时,由于语义而导致的错误会在程序中发生。

  3. 词序是语法的基本原理,试图理解所写内容的人使用词序的句法线索来帮助给出句子的结构和含义。语义是个人根据其先验知识对“句子”的含义的自己的解释。因此,在使用语义提示时,看似没有语法意义的句子可以具有意义。

  4. 语法仅与语言和语法上正确的内容有关。语义学要求所有人都具备先验知识,而这远远超出了任何特定于语言的知识。

  5. “婴儿牛奶饮料”一词没有句法含义,但是由于我们的先验知识告诉我们婴儿喝牛奶,因此大多数人会通过语义将其解释为“婴儿喝牛奶”的含义,因此我们可以从中找到含义。关键词。


1
给予好评除外最后一个所有(5点)
nawfal

-2

语法和语义就像策略和战术左右

它们并不是真正独立的通用概念,而是一对相关的单词,当您处于特定的上下文中时,它们指示相反的方向。但是,在某种程度上,策略是另一种策略。

因此,如果您使用某种语言编写代码,那么语法就是您使用的语言,而所需的行为就是语义。但是,如果您正在实现或讨论该语言的编译器,那么语法就是语法(可能是类型系统)以及基于此语言构建的语义。等等。


4
那是什么深奥的BS?喜欢左右?喜欢策略和战术吗?也许甚至像阴与阳,上帝与魔鬼,哈利与伏地魔一样?
JensG 2014年

-3

语法是计算机可以理解的,语义是人类可以理解的。

编译器/解释器不在乎您的设计,在任何编译到机器级别的代码中,您都很难推断出设计。开发人员关心设计,因为好的设计是通过抽象复杂的行为和交互来降低复杂性,并且不同类型的问题使它们具有不同的语义。语言的选择主要取决于您要使用的语义在语法中如何轻松有效地表达。


“语法是计算机可以理解的,语义是人类可以理解的”,这是一个极大的简化。人类也确实了解语法,而计算机也了解某些语义。
CesarGon

4
显然是错误的。有一些语言具有相同的语法和完全不同的语义(例如,同一语言的急切版本和惰性版本),有一些语言实际上没有语法,并且具有非常丰富和可变的语义(例如,Forth和Lisp)。语义是编译器解释您的语言的方式。人类可能对此一无所知,但仍然能够使用一种语言。
SK-logic

@ SK-logic,您在矛盾自己。如果可以使用相同的语法表达不同的语义,那么显然语义不包含在语法中,而是包含在用法中。然而,编译器仅具有可使用的语法。它不解释语义,而是解释语法。它不会根据开发人员的意图(而仅根据他的键入)来不同地编译相同的语法。语义由开发人员提供,仅对他有意义。
kylben 2011年

3
@kylben,我并不矛盾,因为我从未说过语法和语义甚至是相互联系的。而且,在解析阶段之后,编译器并没有对语法做任何事情-编译器正在实现语义。显然,您对术语的解释是错误的。请先
SK-logic

3
您所谈论的是程序的含义,它是语言学家所定义的“语义”。但是在计算机科学中,语义是语言的意思,而不是特定的程序。
SK-logic

-3

非常简单的“ plain c”示例:

void main()
{
  int a = 10;
  int x = a - 1;
  int y = - 1;

  printf("x = %i", x);
  printf("y = %i", y);
    getch();
}

在此示例中,“-”标记的语法相同,但是根据其使用位置,其含义不同(“语义”)。

在“ x”分配中,“-”表示“减”运算,在“ y”分配中,“-”表示“负号”运算。


3
不正确 这两个-运算符是相同的token,但是它们在语法上有所不同,因为它们在不同的上下文中使用。 0 - 1匹配语法规则additive-expression: additive-expression - multiplicative-expression,同时- 1匹配语法规则unary-expression: unary-operator cast-expression(参考:C99标准)。
基思·汤普森

@基思·汤普森:你错过了重点。是语义或语法问题,不是C标准问题。该标准是正确的,但是,我的回答是要解释一个概念,而不是按照字面意思解释一个标准。这就像一个“柯克船长”与“斯波克博士”的问题。干杯;-)
umlcat 2014年

我不同意。两个-操作者之间的区别是语法上的,而不仅仅是语义上的(尽管它们也具有不同的语义)。语法由语言语法定义,并且两个运算符在语法的不同部分中指定。有关一元运算符,请参见N1570草案第6.5.3节,加法运算符请参见6.5.6节。(顺便说一句,如果您要使用C示例,它应该是正确的;void main()应该是int main(void),并且您丢失了#include <stdio.h>,无论标头声明是什么getch
Keith Thompson

为了阐明这一点,语法不仅与标记的顺序有关,还与这些标记如何构建更大的结构有关。编译器通常具有词法分析器(令牌器)和解析器作为不同的组件。两个人对付语法。
基思·汤普森
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.