5

这种类型的错误是在类型检查期间还是在解析输入时产生的?应该在什么类型下解决错误?

4

4 回答 4

3

我认为这是一个语义错误,因为即使您使用的是以前未绑定的标识符,您的语言也能很好地解析——即句法分析只检查程序的格式是否正确。语义分析实际上检查您的程序是否具有有效的含义——例如绑定、作用域或类型。正如@pst 所说,您可以在解析期间进行范围检查,但这是一个实现细节。AFAIK 旧的编译器曾经这样做是为了节省一些时间和空间,但我认为今天这种方法是有问题的,如果你没有一些硬性能/内存限制。

于 2012-11-03T05:44:46.847 回答
2

该程序符合语言语法,因此在语法上是正确的。语言语法不包含诸如“必须声明标识符”之类的任何语句,并且确实没有任何方法可以这样做。在 Algol-68 项目中,按照这些思路构建两级语法的尝试失败了,据我所知,此后一直没有尝试过。

每一个的含义(如果有的话)是一个语义问题。Frank deRemer 将此类问题称为“静态语义”。

于 2012-11-04T09:12:37.283 回答
1

在我看来,这不是严格意义上的语法错误——也不是语义错误。如果我要为静态类型的编译语言(如 C 或 C++)实现此功能,那么我不会将检查放入解析器(因为解析器实际上无法检查此错误),而是放入代码生成器(编译器中遍历抽象语法树并将其转换为汇编代码的部分)。所以在我看来,它介于语法和语义错误之间:它是一个语法相关的错误,只能通过对代码进行语义分析来检查。

然而,如果我们考虑一种原始脚本语言,其中直接执行 AST(无需编译为字节码且没有 JIT),那么评估器/执行器函数本身会遍历 AST 并找到未声明的变量 - 在这种情况下,它将是运行时错误。不同之处在于“AST_walk()”例程位于程序生命周期的不同部分(编译时间和运行时),语言是脚本还是编译语言。

于 2012-11-03T13:51:39.540 回答
0

对于需要声明标识符的语言(有很多),具有未声明标识符的程序格式错误,因此缺少声明显然是语法错误。

处理这个问题的常用方法是将有关符号的信息合并到符号表中,以便解析可以使用这些信息。

以下是标识符类型如何影响解析的几个示例:

C / C++

一个经典案例:

(a)-b;

取决于a,这是强制转换或减法:

#include <stdio.h>

#if TYPEDEF
typedef double a;
#else
double a = 3.0;
#endif

int main() {
  int b = 3;
  printf("%g\n", (a)-b);
  return 0;
}

因此,如果a根本没有声明,编译器必须将程序拒绝为语法错误(这正是标准使用的词。)

XML

这个很简单:

<block>Hello, world</blob>

这是格式不正确的 XML,但无法使用 CFG 检测到。(尽管如此,所有 XML 解析器都会正确地拒绝它,因为它是格式错误的。)对于 HTML/SGML,在某些明确定义的情况下可能会省略结束标记,解析比较棘手,但仍然具有确定性;同样,标签的精确声明将决定有效输入的解析,并且很容易提出根据声明进行不同解析的输入。

英语

好吧,不是编程语言。我有很多其他编程语言示例,但我认为这可能会触发其他一些直觉。

考虑两个语法正确的句子:

The sheep is in the meadow.
The sheep are in the meadow.

现在,怎么样:

The cow is in the meadow.
(*) The cow are in the meadow.

第二句话是可以理解的,尽管模棱两可(名词或动词是错的吗?)但在语法上肯定是不正确的。但是为了知道那个(和其他类似的例子),我们必须知道它sheep有一个无标记的复数。确实,许多动物都有无标记的复数形式,所以我认为以下所有内容都是合乎语法的:

The caribou are in the meadow.
The antelope are in the meadow.
The buffalo are in the meadow.

但绝对不是:

(*) The mouse are in the meadow.
(*) The bird are in the meadow.

等等


似乎有一个普遍的误解,即由于句法分析器使用上下文无关语法分析器,因此语法分析仅限于解析上下文无关语法。这是不正确的。

在 C(和家族)的情况下,语法分析器使用符号表来帮助它解析。在 XML 的情况下,它使用标签堆栈,而在泛化 SGML(包括 HTML)的情况下,它也使用标签声明。因此,作为一个整体考虑的语法分析器比 CFG 更强大,而 CFG 只是分析的一部分。

给定程序通过语法分析的事实并不意味着它在语义上是正确的。例如,语法分析器需要知道是否是类型a才能正确解析被减去,在它是一个变量的情况下。这些验证可以在构建解析树后的类型分析期间发生,但它们仍然是编译时错误。(a)-baaba

于 2012-11-03T15:06:05.710 回答