最近我不得不给出 C 中的词法和语义错误的例子。我提供了以下例子。
我认为以下是词汇错误,
int a#;
对于语义错误,我给出了以下示例,
int a[10];
a=100;
但是现在我有点困惑是否两者实际上都是语法错误。请给我一些关于这些错误的想法?
最近我不得不给出 C 中的词法和语义错误的例子。我提供了以下例子。
我认为以下是词汇错误,
int a#;
对于语义错误,我给出了以下示例,
int a[10];
a=100;
但是现在我有点困惑是否两者实际上都是语法错误。请给我一些关于这些错误的想法?
首先,错误的分类(如词汇、句法、语义、语用)在细节上是任意的。
如果您将词法错误定义为词法分析器检测到的错误,那么格式错误的数字可能是 1,例如12q4z5
。或带有禁止字符的名称,例如$
您可以将语法错误定义为在解析时检测到的错误。然而,C 并不是严格意义上的上下文无关语言,它的解析器保留上下文信息(例如在符号表中)。
由于所有a
#
和;
都是有效的词位,因此您a#;
不是词法错误。
实际上#
主要是在预处理时有用,解析的实际上是预处理的形式,而不是用户给定的源代码!
许多语义错误与未定义行为的概念有关,例如printf("%d")
缺少整数参数。或超出范围的访问,在您的情况下printf("%d\n", a[1234]);
一些(但不是全部)语义或语用错误可以通过静态分析工具找到。您甚至可以说现代编译器(启用所有警告时)会做一些事情。您的示例a=100;
是键入错误(可以任意称为语法,因为C编译器在解析时发现它,并且作为语义,因为与不是上下文无关属性的类型相关)。而且您拥有更专业的静态分析工具,例如Frama-C,您可以扩展或自定义GCC 编译器(例如,使用MELT,一种特定于域的语言)来添加您的编译器(例如,在TALPO中)。
一个务实的错误可能是声明一个巨大的局部变量,就像这里。可能,当 1Tbyte RAM 内存很普遍时,堆栈会有很多 GB,所以这个例子可以运行,但不是今天。