我是编译器构造的新手,我试图在编译器构造中的语法分析器编程中编写一个CFG(Context Free Grammar)的Assignment Statement,我想知道这个非法语句是语义错误还是语法错误?
5 =一个;
谢谢!
答案 0 :(得分:4)
我们在"语法"之间使用的区别和#34;语义"在我看来,在很大程度上意外的是我们目前如何使用"弱解析器构建编译器"。
编译器的目的是识别已经给出了一个有效的程序,在可行的情况下诊断该程序中的错误,并将该代码编译成可执行的形式。
如何识别有效程序通常是通过使用解析器来完成的,该解析器了解程序的语法结构(在很多情况下由语法显式驱动),后跟一组"语义"检查以确认所提供的结构不会违反语言参考手册中定义的约束。
作为一个实际问题,我们无法定义一个"解析器"检查所有"语法"约束:解析技术经常(总是!)太弱。我们解决了最多检查程序的无上下文结构属性的解析器(例如,"括号余额")。我们推进的其他所有内容"语义检查" (由于是前一段定义中唯一的其他地方)。
因此,可以定义一个真正的弱解析器,只需读取字符并接受字符流的任何内容(当然,您的程序源由字符组成:),并将其他所有内容降级为&# 34;语义检查"。我们选择的解析器技术可能做的任何其他语法检查只是(当然非常方便)肉汁。
所以,是的,你可以定义一个接受" 5 = a;"作为匹配(某些)语法约束,并在稍后进行语义检查,左侧是有效的。
对于大多数传统的解析器生成器(甚至是手动递归下降解析器),您可以通过一些适度的努力,通常为您的语言定义语法,该语法将拒绝" 5 = a;"作为"语法错误"。因为这很容易,我们经常假设这样的检查实际上是通过解析来完成的,所以我们通常会说这是一个"语法错误"无论使用何种解析技术,即使这很邋。。
相比之下,"字符串S = 3.7;"可能是我们的解析器接受了;类型不一致可能是通过语义检查完成的,所以我们会说类型检查是一个语义错误。但是这种解释是因为大多数编译器都是以这种方式构建的。
如果你有一个足够强大的(图灵能力)规范系统(例如,Van Wingaarden Grammars或Meta-S),你实际上可以编码你所认为的所有"语法& #34;和#34;语义"在同样的形式主义,并有形式主义"执行"验证您的源代码。如果该引擎抱怨,这是一个"语法错误"或者语义错误"?在这种情况下,我们不再需要单独解析"和#34;语义检查"所以很难说。充其量,你可以说你有一个错误"将源文本解析为有效的程序"。