我对编译器的构造很陌生,我试图在编译器构建中为语法分析器编写一个CFG(无上下文语法)赋值语句,我想知道这个非法语句是语义错误还是语法错误?
5=a;
谢谢!
发布于 2016-10-29 15:49:35
在我看来,“语法”和“语义”之间的区别在很大程度上是我们目前如何用“弱解析器”构建编译器的意外。
编译器的目的是识别已给出的有效程序,在实际情况下诊断该程序中的错误,并将该代码编译成可执行形式。
如何识别有效的程序通常通过使用一个解析器来完成,解析器了解程序的语法结构(在许多情况下是由语法显式驱动的),然后是一组“语义”检查,以验证所提供的结构没有违反语言参考手册定义的约束。
作为一个实际问题,不能定义一个“解析器”检查所有的“语法”约束:解析技术通常(总是!)太虚弱了。我们满足于解析器,最好检查程序的上下文无关结构属性(例如,“括号平衡”)。我们推进到“语义检查”的其他一切(根据上一段的定义,它是唯一的另一个地方)。
因此,我们可以定义一个非常弱的解析器,它简单地读取字符并接受任何字符流(当然,您的程序源代码是由字符组成的:),并将其他所有内容降为“语义检查”。我们选择的解析器技术可能做的任何额外语法检查都只是(诚然非常方便)。
因此,是的,您可以定义一个接受"5=a;“的解析器,以匹配(某些)语法约束,并在稍后进行语义检查,以确定左侧是否有效。
对于大多数传统的解析器生成器(甚至是手动递归下降解析器),您可以通过一些小小的努力,为您的语言定义一个语法,它将拒绝"5=a;“作为”语法错误“。因为这很容易,所以我们通常假设这样的检查实际上是通过解析来完成的,所以我们通常会说这是一个“语法错误”,不管使用的是什么解析技术,尽管这是草率的。
相反,"String S=3.7;“可能被我们的解析器所接受;类型不一致性可能是通过语义检查来完成的,所以我们会说类型检查是一个语义错误。但是,这种解释之所以出现,是因为大多数编译器都是以这样的方式构建的。
如果您有一个功能足够强大(具有图灵能力的)规范系统(例如,范·温加登文法或元-S),那么您实际上可以在相同的格式中对您认为的所有“语法”和“语义”进行编码,并让这种形式“执行”来验证您的源代码。如果该引擎抱怨,是“语法错误”还是“语义错误”?在这种情况下,我们不再有单独的“解析”和“语义检查”,因此很难说。充其量,您可以说您有一个错误“解析源文本为一个有效的程序”。
https://stackoverflow.com/questions/40320237
复制相似问题