24

以下行有什么作用?

#line 25 "CSSGrammar.y"

扩展名是什么?

4

7 回答 7

19

根据标准:

§16.4.3:

形式的预处理指令

# line digit-sequence new-line

使实现表现得好像以下源代码行序列以具有由数字序列指定的行号(解释为十进制整数)的源代码行开头。如果数字序列指定零或大于 2147483647 的数字,则行为未定义。

§16.4.4:

形式的预处理指令

# line digit-sequence " s-char-sequenceopt" new-line

类似地设置假定的行号并将源文件的假定名称更改为字符串文字的内容。

§16.4.5:

形式的预处理指令

# line pp-tokens new-line

(与前两种形式之一不匹配)是允许的。指令上行之后的预处理标记与普通文本一样被处理(当前定义为宏名称的每个标识符都被其预处理标记的替换列表替换)。如果在所有替换后产生的指令与前两种形式之一不匹配,则行为未定义;否则,将适当处理结果。

扩展名正是作者.y选择使用的,也许是为了让它明显是一个 YACC 文件(“语法”这个词也指出了这一点,尽管这只是一个猜测)。

于 2012-02-05T20:49:40.740 回答
11

它只是说明当前代码行来自第 25 行CSSGrammar.y,这是一个 YACC 样式的语法文件,是生成此代码的位置。

调试器可以使用它来单步执行语法本身,而不是生成的代码。

于 2012-02-05T20:49:11.333 回答
5

#line指令修改编译器的报告位置,并被代码生成软件用来帮助程序员识别原始源代码中的问题。任何人都可以使用它来帮助重定向错误报告以提供更多信息。

因此,例如,您的解析器生成一个 CSSGrammar.cpp 文件,该文件由 c++ 编译器编译,其中包含 c++ 片段,一条#line 25 "CSSGrammar.y"指令告诉 c++ 编译器将文件中的特定点视为第 25 行CSSGrammar.y

编译器将继续解析后续行并在该指令的初始条件下报告错误。

因此,如果在 3 行之后发生错误,它将报告 CSSGrammar.y 的第 28 行发生错误

请注意,单个源文件可以有来自多个部分的源;并且该指令可以非常有效地用于指示错误情况。

通常,您会看到#line沿途有多个指令;他们只是在那里解释沿途的各种注射(如果您愿意,可以重置报告插入符号)。

请注意,任何生成器都可以使用#line 指令,包括您自己的生成器,并且无论如何都不限于解析器生成器。

于 2012-02-05T20:58:57.580 回答
3

它指示编译器相信以下行是 file 中的第 25 行CSSGrammar.y。然后,如果编译器在下 2 行检测到错误,则将报告为来自第 26 行CSSGrammar.y

生成 C 文件的程序,如bison、 或yacc、 或flex、 或ANTLR,甚至(过时的)MELT都使用了这种可能性。

如果生成了调试信息(例如使用gcc -g),它将指向CSSGrammar.y您示例中的文件。

于 2012-02-05T20:51:31.563 回答
2

“yacc”解析器生成器使用以 .y 结尾的文件,并发出包含 c 或 c++ 的文件。它添加了这些#line 行以允许调试器返回到旧的原始源,不接受任何替代品。

于 2012-02-05T20:48:52.037 回答
2

它是 ac 预处理器选项。它告诉 c-parser 放弃它的源文件的行数,假装这是第 25 行。

有了这些信息,您就可以更轻松地调试源文件。yacc 文件将被翻译成 c 源代码,其中这是伪装的源代码行。

于 2012-02-05T20:49:36.413 回答
0

使用#line 会强制编译器忘记它正在编译的文件以及它所在的行,并加载新数据。

注意:编译器仍然从它所在的行开始编译。

于 2019-04-14T16:29:41.190 回答