许多 C 书中很少提及#line指令。
他们中的许多人说这个指令是由野牛工具的yacc使用但不是 展示任何实际例子。
任何人都可以向我展示这个指令的一些真实用法或者让我变得实用 野牛或yacc使用的例子?
答案 0 :(得分:3)
任何从其他文件中的其他内容生成C(或C ++)代码的程序或脚本也应该发出大量#line
指令(将生成的C行关联到该另一个文件中的位置)。
这对诊断消息和调试器非常有用。
例如,在某个example.y
文件上运行bison并查看生成的C代码,或者构建,安装和使用MELT(一种特定于域的语言来扩展{{3}查看它从.melt
文件生成的许多C ++文件。您将在生成的代码中找到类似
#ifndef MELTGCC_NOLINENUMBERING
#line 63 "warmelt-outobj.melt" /**::procdecl::**/
#endif /*MELTGCC_NOLINENUMBERING*/
MELT_EXTERN melt_ptr_t MELT_MODULE_VISIBILITY meltrout_2_WARMELTmiOUTOBJ_OUTPUT_DESCRIPTIVE_COMMENT(meltclosure_ptr_t meltclosp_, melt_ptr_t meltfirstargp_, const melt_argdescr_cell_t meltxargdescr_[], union meltparam_un *meltxargtab_, const melt_argdescr_cell_t meltxresdescr_[], union meltparam_un *meltxrestab_);
和
/*getarg#0*/
MELT_LOCATION("warmelt-outobj.melt:63:/ getarg");
#ifndef MELTGCC_NOLINENUMBERING
#line 63 "warmelt-outobj.melt" /**::getarg::**/
#endif /*MELTGCC_NOLINENUMBERING*/
/*_.SEXP__V2*/ meltfptr[1] = (melt_ptr_t) meltfirstargp_;
/*getarg#1*/
/*^getarg*/
#ifndef MELTGCC_NOLINENUMBERING
#line 63
#endif
if (meltxargdescr_[0] != MELTBPAR_PTR) goto meltlab_endgetargs;
/*_.ENV__V3*/ meltfptr[2] = (meltxargtab_[0].meltbp_aptr) ? (*(meltxargtab_[0].meltbp_aptr)) : NULL;
gcc_assert(melt_discr((melt_ptr_t)(/*_.ENV__V3*/ meltfptr[2])) != NULL);
以及文件warmelt-outobj.melt
的第63行和第13行
(defmacro output_descriptive_comment (sexp env mexpander modctx)
(let ( (sloc (get_field :loca_location sexp))
(scont (get_field :sexp_contents sexp))
(xargs (expand_restlist_as_tuple scont env mexpander modctx))
(argout (multiple_nth xargs 0))
(argobj (multiple_nth xargs 1))
)
(when (!=i (multiple_length xargs) 2)
(error_at sloc "MELT output_descriptive_comment needs two arguments")
(return))
BTW,根据经验,当您开发严格的C或C ++代码生成器时,需要发出正确的#line
指令,这是代码生成器中的一个重要负担。这可能需要大量的工作。