我一直认为引用语言的语法与引用语言的语义是相同的。但是,我被告知,显然并非如此。有什么区别?

评论

一点强制性阅读:en.wikipedia.org/wiki/Denotational_semantics en.wikipedia.org/wiki/Operational_semantics en.wikipedia.org/wiki/Abstract_syntax

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

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

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

我要补充一点,赛门铁克与两者都不相同

#1 楼

语义〜含义

语法〜符号表示

因此,用不同语言编写的两个程序可以做相同的事情(语义),但是用于编写程序的符号会有所不同(语法)。

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

评论


错误检查不是区分语法和语义的标准。编译器可以而且必须诊断语法错误(例如缺少分号)和语义错误(例如x + y,这些操作数没有适当的+运算符)。我称逻辑错误为1而不是2。

–基思·汤普森(Keith Thompson)
11-10-13在0:37

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

–Steve314
11-10-13在0:42



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

–基思·汤普森(Keith Thompson)
2011年10月13日,0:46

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

– Ptharien的火焰
2012年12月13日在20:33

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

–伊文·普莱斯
13年3月15日在17:06

#2 楼

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


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


评论


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

– SK-logic
2011年10月12日上午10:39

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

–mouviciel
2011年10月12日上午11:00

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

– SK-logic
11-10-12在11:48

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

– SK-logic
13 Mar 15 '13 at 17:42

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

–伊文·普莱斯
13年3月15日在18:21

#3 楼

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

The glass drank Ben

这是一个语法正确的语句。它具有名词,动词等。

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

#4 楼

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

例如,指针算术的概念是C语义的一部分; +-运算符可用于表示指针操作的方式是其语法的一部分。

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

评论


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

–古尔山
2011年10月12日,下午6:39

@Gulshan,范式是一个比语义等形式化事物更广泛的概念。范式可能包括语义,但它更多是一种方法论,甚至更广泛地是一种哲学。

– SK-logic
2011年10月12日上午9:01

#5 楼

语法是您排列语言标记的方式。语义就是这些标记的含义(通常,标记的特定排列意味着什么)。

#6 楼

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

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

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

举个例子:


XML语法(带有所有括弧的东西)是一种以XML Infoset(抽象树)为语义的语法。
XML Infoset为语法可以将某种XML数据格式表示为记录的语义。一个对RDF图进行编码的RDF / XML文档。
作为语法的RDF图(带有URI引用的东西)会将抽象资源的图编码为语义。
通过语法将抽象资源的图编码为概念性

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

#7 楼

如果可以用BNF(巴克斯-纳尔形式)或类似形式描述它,那是语法。另一方面,语义是关于程序(或其他源代码块)的含义的。

有时两者之间的界线可能是模糊的。

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

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

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

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

#8 楼

语法是(词汇)符号所说的。语义就是它们的含义。

考虑:

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
-相同的语法,不同的语义(对于整数)。

#9 楼

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

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

(英语)'cat hugs boy'和(编程)'* 3.2 * 5 *'在语法上有效。

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

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

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

(英语)“飞机可能是危险的”可以有两种含义,即飞机可以飞

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

来源:MIT 6.00.1

#10 楼


语法是指用于控制语言中有效语句的构造的正式规则。
语义是指提供语句含义的一组规则。
由于语法而导致的错误在程序中发生。当违反或滥用编程语言规则时。
当语句没有意义时,由于语义而产生错误。
单词顺序是语法的基本原理,那些试图理解的人
理解所写内容使用词序的句法线索来帮助给出句子的结构和含义。
语义学是个人根据自己的先验知识对“句子”的含义的解释。 。因此,
似乎没有句法意义的句子在使用
语义提示时可能具有意义。
语法仅关注语言和语法上正确的内容。
语义要求所有这些
句子“婴儿牛奶饮料”没有句法含义,但是通过语义,大多数人会把它理解为“婴儿牛奶饮料”知识告诉我们婴儿正在喝牛奶,因此我们可以从关键词中找到含义。


评论


支持除最后一个之外的所有内容(第5点)

– nawfal
2014年5月22日晚上8:44

#11 楼

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

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

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

评论


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

– JensG
2014年2月8日在11:38



#12 楼

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

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

评论


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

– CesarGon
2011年10月12日在12:17

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

– SK-logic
2011年10月12日12:43



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

– kylben
2011年10月12日13:31

@kylben,我并不矛盾,因为我从未说过语法和语义甚至是相互联系的。而且在解析阶段之后,编译器就不会对语法做任何事情-编译器正在实现语义。显然,您对术语的解释是错误的。请先阅读以下内容:en.wikipedia.org/wiki/Denotational_semantics

– SK-logic
2011-10-12 14:11

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

– SK-logic
2011年10月12日14:15

#13 楼

非常简短的示例,带有“ plain c”:

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

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


在此示例中,“-”标记的语法相同,

在“ x”赋值中,“-”表示“减法”运算,在

评论


不正确两者-运算符是相同的令牌,但是在语法上有所不同,因为它们在不同的上下文中使用。 0-1匹配语法规则加法表达式:additive-expression-乘法表达式,而-1匹配语法规则unary-expression:一元运算符强制转换表达式(参考:C99标准)。

–基思·汤普森(Keith Thompson)
2011年10月13日,0:30

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

–umlcat
2014年2月12日在18:36



我不同意。二者之间的区别是语法上的,而不仅仅是语义上的(尽管它们也有不同的语义)。语法由语言语法定义,并且两个运算符在语法的不同部分中指定。有关一元运算符,请参见N1570草案,第6.5.3节,对于加法运算符,请参见6.5.6。 (顺便说一句,如果您要使用C示例,它应该是正确的; void main()应该是int main(void),并且您缺少#include 和任何标有getch的标头

–基思·汤普森(Keith Thompson)
2014年2月12日19:05

为了阐明这一点,语法不仅与标记的顺序有关,还与这些标记如何构建更大的结构有关。编译器通常具有词法分析器(令牌器)和解析器作为不同的组件。他们两个都处理语法。

–基思·汤普森(Keith Thompson)
2014年2月12日19:34