【问题标题】:Lexical and Semantic Errors in CC 中的词法和语义错误
【发布时间】:2013-03-22 12:38:37
【问题描述】:

最近我不得不举例说明 C 中的词法和语义错误。我提供了以下示例。

我认为以下是词法错误,

int a#;

对于语义错误,我给出了以下示例,

int a[10];
a=100;

但现在我有点困惑是否两者实际上都是语法错误。请给我一些关于这些错误的想法?

【问题讨论】:

标签: c compiler-construction


【解决方案1】:

首先,错误的分类(如词汇、句法、语义、语用)在细节上是任意的。

如果您将词法错误定义为lexer 检测到的错误,则格式错误的数字可能为1,例如12q4z5。或带有禁止字符的名称,例如$

您可以将语法错误定义为在parsing 时间检测到的错误。然而,C 不是严格意义上的context-free language,它的解析器保留上下文信息(例如在符号表中)。

由于所有 a #; 都是有效的词位,因此您的 a#; 不是词法错误。

其实#主要是在预处理的时候有用,解析出来的其实是预处理后的形式,而不是用户给的源码!

许多语义错误与undefined behavior 的概念有关,例如缺少整数参数的printf("%d")。或者越界访问,在你的情况下printf("%d\n", a[1234]);

可以通过static analysis tools 找到一些(但不是全部)语义或语用错误。您甚至可以说现代编译器(启用所有警告时)会做一些事情。 您的 a=100; 示例是 typing 错误(可以任意称为语法,因为 C 编译器在解析时发现它,并且作为语义,因为与不是上下文无关属性)。而且您有更专业的静态分析工具,例如 Frama-C,您可以扩展自定义 GCC 编译器(例如,使用MELT,一种特定领域的语言)来添加您的(例如在 TALPO 中)。

一个实际错误可能是声明一个巨大的局部变量,例如here。很可能,当 1Tbyte RAM 内存很普遍时,堆栈会有很多 GB,所以这个例子可以运行,但不是今天。

【讨论】:

  • 我只是在回答中这样做了。你在里面找不到吗?
  • @BasileStarynkevitch 你能帮我澄清一下我的疑问吗?如果我在 C 中的代码为int a2.5b; 怎么办?它根本不是一个有效的标识符,但是为此生成了哪些令牌? int 作为保留关键字,a 作为有效标识符,2 作为有效常量,. 作为特殊符号,5 作为有效常量,; 作为特殊符号。我的理解正确吗?
猜你喜欢
  • 2014-07-24
  • 2015-12-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
  • 2015-02-26
  • 2013-09-26
  • 1970-01-01
相关资源
最近更新 更多