最近在看sqlite3源码,不明白下面这段代码。如下面红色部分,不能调试,根本走不到那里,也高不明白是干什么。查了查#line,还是不明白。达人指点。

zsl6658 2008-10-20 12:41:52


static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){
switch( yymajor ){
/* Here is inserted the actions which take place when a
** terminal or non-terminal is destroyed. This can happen
** when the symbol is popped from the stack during a
** reduce or during error processing or when a parser is
** being destroyed before it is finished parsing.
**
** Note: during a reduce, the only symbols destroyed are those
** which appear on the RHS of the rule, but which are not used
** inside the C code.
*/
case 155: /* select */
{
#line 369 "parse.y"
sqlite3SelectDelete((yypminor->yy219));
#line 1277 "parse.c"

}
break;
case 169: /* term */
{
#line 629 "parse.y"
sqlite3ExprDelete((yypminor->yy172));
#line 1284 "parse.c"

}
break;
case 170: /* expr */
{
#line 627 "parse.y"
sqlite3ExprDelete((yypminor->yy172));
#line 1291 "parse.c"

}
break;
case 174: /* idxlist_opt */
{
#line 887 "parse.y"
sqlite3ExprListDelete((yypminor->yy174));
#line 1298 "parse.c"
}
break;
case 182: /* idxlist */
{
#line 885 "parse.y"
sqlite3ExprListDelete((yypminor->yy174));
#line 1305 "parse.c"
}
break;
case 188: /* fullname */
{
#line 486 "parse.y"
sqlite3SrcListDelete((yypminor->yy373));
#line 1312 "parse.c"
}
break;
case 189: /* oneselect */
{
#line 371 "parse.y"
sqlite3SelectDelete((yypminor->yy219));
#line 1319 "parse.c"
}
...全文
717 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
redleaves 2008-10-21
  • 打赏
  • 举报
回复
你的理解没有什么大问题.#line的功能很单纯,就是做行映射.只是对出错提示和调试有用而已.
在你的那个例子里.#line 369 "parse.y"被映射成sqlite3SelectDelete((yypminor->yy219));,这样,你在调试时,就可以跟踪语法规则运行的状况...
redleaves 2008-10-20
  • 打赏
  • 举报
回复
你看的那些代码是由YACC工具处理parse.y后自动生成的...
#line的作用是把当前源文件从下一行开始映射到另一个文件的某一行. 这样一来,就把你那个文件映射到parse.y上了.调试的时候,就可以直接调试parse.y的流程,而不用关注自动生成的代码的逻辑.
zsl6658 2008-10-20
  • 打赏
  • 举报
回复
redleaves
程序员(http://hi.baidu.com/scu319hy)
等级:
可用分等级:小地主
总技术分:6263
总技术分排名:3483

发表于:2008-10-20 11:03:124楼 得分:0
你看的那些代码是由YACC工具处理parse.y后自动生成的...
#line的作用是把当前源文件从下一行开始映射到另一个文件的某一行. 这样一来,就把你那个文件映射到parse.y上了.调试的时候,就可以直接调试parse.y的流程,而不用关注自动生成的代码的逻辑.



#line 369 "parse.y"
sqlite3SelectDelete((yypminor->yy219));
#line 1277 "parse.c"

这段代码是否可以这样理解:
#line 369 "parse.y" 告诉编译器(就是编译这个源文件的编译器-我的是vc),sqlite3SelectDelete((yypminor->yy219)); 是parse.y的第369行,
然后#line 1277 "parse.c"又告诉编译器,后边的"}"是parse.c的第1277行,这样在编译器看来(因为查了一下我的sqlite3的工程文件夹下并不存在parse.y这样一个文件)就存在这样一个parse.y文件,它的第369行是sqlite3SelectDelete((yypminor->yy219));

因为这段sqlite3的源代码是用来分析执行sql语句的,parse.y的语法规则就直接映射到一个函数,省去了代码生成的过程,直接由语法制导生成对应的C函数?
还在研究中..................

那位高人明白的指点一下。





zsl6658 2008-10-20
  • 打赏
  • 举报
回复
redleaves
程序员(http://hi.baidu.com/scu319hy)
等级:
可用分等级:小地主
总技术分:6263
总技术分排名:3483

发表于:2008-10-20 11:03:124楼 得分:0
你看的那些代码是由YACC工具处理parse.y后自动生成的...
#line的作用是把当前源文件从下一行开始映射到另一个文件的某一行. 这样一来,就把你那个文件映射到parse.y上了.调试的时候,就可以直接调试parse.y的流程,而不用关注自动生成的代码的逻辑.



#line 369 "parse.y"
sqlite3SelectDelete((yypminor->yy219));
#line 1277 "parse.c"

这段代码是否可以这样理解:
#line 369 "parse.y" 告诉编译器(就是编译这个源文件的编译器-我的是vc),sqlite3SelectDelete((yypminor->yy219)); 是parse.y的第369行,
然后#line 1277 "parse.c"又告诉编译器,后边的"}"是parse.c的第1277行,这样在编译器看来(因为查了一下我的sqlite3的工程文件夹下并不存在parse.y这样一个文件)就存在这样一个parse.y文件,它的第369行是sqlite3SelectDelete((yypminor->yy219));

因为这段sqlite3的源代码是用来分析执行sql语句的,parse.y的语法规则就直接映射到一个函数,省去了代码生成的过程,直接由语法制导生成对应的C函数?
还在研究中..................

那位高人明白的指点一下。





baihacker 2008-10-20
  • 打赏
  • 举报
回复
#line 100 "a.txt"
cout << __LINE__ << __FILE__ << endl;//这一行的行号是100,认为当前的源文件名是a.txt
baihacker 2008-10-20
  • 打赏
  • 举报
回复
http://hi.baidu.com/sworssman/blog/item/7d0a2fd065b0ab8ba0ec9c81.html
c语言里有个很少用到的宏 #line,这个宏通常是和__LINE__宏一起使用的,__LINE__宏表示当前c语句在源文件中的行数,以前也只是在书上看到过,写过一些实例小程序,实际应用中并无使用。
好了,废话不说,举个例子来说明 #line宏的使用:
1:#include "iostream"
2:#line 100
3:using namespace std;
4:
5:int main(int argc, char* argv[])

6:{
7:cout<<"__LINE__:"<<__LINE__<<endl;
8:
9: return 0;

10: }
输出结果是:__LINE__:104
本来应该是输出:__LINE__:7,因为“cout<<"__LINE__:"<<__LINE__<<endl;”语句在第7行;
但是有了#line 100 ,则从“#line 100”所在行的下一行被认为是第100行,所以输出的行号是104了。
baihacker 2008-10-20
  • 打赏
  • 举报
回复
http://www.cbi.pku.edu.cn/chinese/documents/csdoc/cman/yacc.html
Content-type: text/html
YACC
Section: User Commands (1)
Updated: July 15, 1990
Index Return to Main Contents
--------------------------------------------------------------------------------



NAME 名字
Yacc - 一个生成 LALR(1) 文法分析器的程序


SYNOPSIS 总览
yacc [ -dlrtv ] [ -b file_prefix ] [ -p symbol_prefix ] filename


DESCRIPTION 描述
Yacc 从 filename 所指定的文件中读出文法(grammar)定义,并为之生成一个 LR(1) 分析器。分析器是由一系列 LALR(1)分析表和用 C 语言写的驱动例程组成。通常把分析表和驱动例程写到文件 y.tab.c 中。
译注:余在翻译有关编译原理的东西时,总是区别语法(Syntax)和文法 (grammar)。驱动例程指的是自动生成的 yyparse 函数和相关函数的源代码。Yacc和 Lex 自动生成的常量、变量、结构,函数等的名称通常以 yy 为前缀,目的是不与用户自己的 C 程序定义的名称冲突。LALR(1)文法的分析是通过在堆栈上通过移进(shift)和归约(reduce)实现的,任何经过良好设计的语言(例如 Lisp,C,Perl,C++,Java),用LALR(1)实现起来是容易,高效和可靠的。


可得到下面的参数:


-b file_prefix
-b 选项改变的是为输出的文件名准备的前缀,这个字符串用 file_prefix 指定,缺省的前缀是 y.。

-d
-d -d 选项导致多写一个 y.tab.h 头文件。(包含一些词法定义)

-l
如果没有指定 -l 选项,则 yacc 将在生成的代码中插入 #line 宏命令 (directive)。 #line 宏命令用于让 C 编译器把在生成的 C 代码中的错误与用户的原始 yacc 代码联系起来。如果指定了 -l 选项,yacc 将不插入 #line 宏命令。用户指定的 #line 宏命令还是将被保留的。

-p symbol_prefix
-p 选项改变的是为 Yacc生成的符号(symbols)准备的前缀,这个字符串用 symbol_prefix 指定,缺省的前缀是 yy。

-r
-r 选项导致 yacc 生成生成分开的代码和表文件。代码文件名是 y.code.c,表文件名是 y.tab.c。

-t
-t 选项更改 Yacc 生成的预处理宏命令,这样调试语句就会被结合到编译后的代码中。

-v
-v 选项导致在文件 y.output 中写出可被人阅读的对生成的分析器的描述。

如果设置了环境变量TMPDIR,TMPDIR 所指定的字符串将被用作生成临时文件的路径名。



FILES 相关文件
y.code.c
y.tab.c
y.tab.h
y.output
/tmp/yacc.aXXXXXX
/tmp/yacc.tXXXXXX
/tmp/yacc.uXXXXXX


DIAGNOSTICS 诊断
如果有些规则永不归约,在标准错误输出上报告这些规则的数目。如果有任何 LALR(1) 冲突,在标准错误输出上报告这些冲突的数目。
译注:规则永不归约通常出现在文法有二义性规则的时候,术语叫归约-归约冲突。LALR(1) 冲突术语上叫移进-归约冲突,解决的方法一种是 Lisp 风格的语言的括号总动员,一种是 C 风格的语言的优先级排座次,还有一种是结构化的解决方法例如 Fortran77 的IF...ENDIF 及 Algol68 的if...fi。C 风格语言的一个标志就是至少有一个从 Algol60 至今死不改悔的移进-归约冲突--都是else(悬挂)惹的祸。只要你清楚并让用户知道,有移进-归约冲突可以是正常的,不象归约-归约冲突那样必须避免。



[中文版维护人]
mhss




[中文版最新更新]
2000/11/13 《中国Linux论坛man手册页翻译计划》:www.cmpp.net/


--------------------------------------------------------------------------------

Index
NAME 名字
SYNOPSIS 总览
DESCRIPTION 描述
FILES 相关文件
DIAGNOSTICS 诊断
[中文版维护人]
[中文版最新更新]

--------------------------------------------------------------------------------
This document was created by man2html, using the manual pages.
Time: 13:48:54 GMT, October 27, 2001

70,037

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧