Parsing 语法分析和语义分析的区别是什么?

Parsing 语法分析和语义分析的区别是什么?,parsing,compiler-construction,language-agnostic,Parsing,Compiler Construction,Language Agnostic,据我所知,解析器由词汇、句法和语义分析三个阶段组成 词法:它会将我的输入分割成标记。示例:123+100-0->123+100-0 语法:它将检查标记,并检查它们之间是否有意义 我面临的问题是理解最后阶段的语义分析,以及它如何区别于第二阶段的语法分析。据我所知,最后阶段的语义分析也会验证已通过语法分析验证的标记,然后打印输出。一般来说,语法分析的目标是将词汇分析生成的标记流转换为某种程序含义的结构化表示。例如,在语法分析中,您希望标记a、/和b被转换成表示a和b的商的东西。通常,语法分析的输出是

据我所知,解析器由词汇、句法和语义分析三个阶段组成

词法:它会将我的输入分割成标记。示例:123+100-0->123+100-0

语法:它将检查标记,并检查它们之间是否有意义


我面临的问题是理解最后阶段的语义分析,以及它如何区别于第二阶段的语法分析。据我所知,最后阶段的语义分析也会验证已通过语法分析验证的标记,然后打印输出。

一般来说,语法分析的目标是将词汇分析生成的标记流转换为某种程序含义的结构化表示。例如,在语法分析中,您希望标记a、/和b被转换成表示a和b的商的东西。通常,语法分析的输出是一个抽象语法树,它是一个编码程序结构的树结构

语义分析的工作是确保语法分析步骤生成的表示实际上是有意义的。例如,假设语法分析器已将a、/和b转换为a和b的商。在语法分析器这样做的时候,它可能不知道a和b的类型是什么;更可能的是,语法分析器只是看到这可以被解释为一个数学表达式,并将其保留下来。然而,这完全有可能不是一个定义良好的操作。例如,如果a是字符串,b是布尔值,那么a/b是无意义操作,编译器应该报告错误

对于一个更详细的示例,假设您正在实现一个Java编译器,并且您看到标记public、class、a、extends、B、{、}。您可以在语法分析期间将其解释为类定义,因为它在语法上是有效的类。但是如果文件后面定义的B不是类呢?或者如果B根本没有定义呢?在这种情况下,代码不正确。它在语法上是有效的,因为它可能是合法的代码,但在语义上是不正确的,因为找不到类B。因此,语法分析器将生成一个完全有效的AST,而语义分析器将在发现B不存在后拒绝代码

我们没有必要将这两个步骤分开的根本原因,事实上有些编译器将这两个步骤融合在一起。这样做的主要原因是实用的——我们有一些很棒的工具来构建语法分析器LR解析器、LL解析器等,它们通过解释标记序列而工作,而不需要过多考虑它们的含义。然后,编译器作者可以指定语言的一般语法,然后编写一个语义分析器作为第二遍检查AST并确定它是否有效。这使得解析器生成器可以自动完成的工作与程序员需要为cleaner编写代码的工作分离开来


希望这有帮助

理论上,句法分析确定语言实例的格式是否正确并分析其语法结构,而语义分析则分析其含义和是否有意义

基本上,句法分析可能取决于词的类型,而不是它们的意思。语义分析依赖于语义。我喜欢绿色的西红柿,而且我填充了wiggly thougts,它们具有相同的语法结构,并且都是格式良好的,但是后者在语义上没有意义

这种理论上的区别实际上有点模糊,因为区分一个词的类型和含义需要一些任意的选择

然而,在编译器开发实践中,区别是显而易见的:语法分析由语法驱动的解析器执行,具体取决于标记的类型。语义分析从动作开始,动作用代码编写,附加到语法规则中。基本上,任何需要查找实际标识符或计算文本值的实际值的东西都是语义分析


有些语言要求将语义分析的结果反馈给解析器,以帮助进行语法分析。这破坏了语法分析和语义分析之间的理论区别,但实际上我们只是认为这有点欺骗,并继续将解析代码称为语法代码。

欢迎使用StackOverflow,请阅读《提问指南》:。你在这里有什么要求?请阅读-所以不是一个讨论论坛,而是收集问答作为开发者的资源。您的问题似乎没有提出任何特殊问题。干杯,我已重新编辑了我的问题,以符合指导原则。非常感谢,我现在明白了!