【问题标题】:How are tokens managed?代币如何管理?
【发布时间】:2015-03-22 03:42:06
【问题描述】:

请解释以下段落

通常使用词法分析器/解析器,标记是一种结构,它不仅包含标记的名称,还包含组成标记的字符/符号以及组成标记的字符串的开始和结束位置, 开始和结束位置用于错误报告、突出显示等。 标记更有可能保存表示标记和词位的字符/符号的开始和结束位置,字符/符号的序列可以根据需要从开始和结束位置导出,因为输入是静态的。

我不明白令牌将持有的开始和结束位置,请澄清一下。

【问题讨论】:

  • 在输入文件中的位置。 (例如,第 7 行,从第 5 个字符开始,一直持续到第 11 个字符。)

标签: compiler-construction


【解决方案1】:

将源代码位置信息附加到令牌的原因有很多,包括:

  • 解析器需要它们以便以用户友好的方式报告语法错误。如果解析器无权访问源代码位置,则用户可能必须扫描整个文件以查找与解析器报告的语法错误一致的语法错误,因为它无法告诉您它发生在哪里。
  • 编译器的后期阶段可能还需要访问源代码位置。例如,您可能希望在二进制文件中包含调试信息。如果是这种情况,编译器中的其他数据结构也需要修改以携带和转发此信息(例如ASTIR)。

您也不一定要存储它的全部(开始和结束行/列)。通常存储令牌开始的行就足够了。但是,位置越精确,您就可以更好地报告错误。考虑以下代码 sn-p:

int x;
Foo y;

int z = x + y;

假设+ 运算符没有为(int, Foo) 定义。只知道每个标记的行号的编译器将被限制为报告错误,例如:

<file>:4: Error: Operator + is not defined for (int, Foo).

如果我们添加一个列号,我们会突然知道+ 符号的确切位置。这使我们能够报告更好的错误消息:

<file>:4: Error: Operator + is not defined for (int, Foo).
          In statement: int z = x + y;
          ------------------------^

如果这个简单的例子不能说服你,我强烈建议你将最近的 clang 产生的错误与旧的 gcc 进行比较。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 2023-01-04
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 2021-02-20
    • 1970-01-01
    相关资源
    最近更新 更多