|
|
|
|
 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-18 13:25 | 1,961 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - canopy [ 2005-08-21 12:23 | 69 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-21 13:55 | 14 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-21 15:09 | 741 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - BarcLiao [ 2005-08-20 14:55 | 400 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-20 17:32 | 3,647 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - BarcLiao [ 2005-08-20 20:22 | 42 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-20 22:04 | 82 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-20 22:12 | 54 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - BarcLiao [ 2005-08-20 22:54 | 194 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-20 23:20 | 104 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - BarcLiao [ 2005-08-21 00:08 | 121 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-21 00:26 | 303 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - BarcLiao [ 2005-08-21 01:37 | 53 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-21 01:42 | 97 byte(s)]
 Re: 关于预处理和遍的问题(回答一个问一个:P) - Xtim [ 2005-08-18 23:00 | 82 byte(s)]
|
|
|
|
[Original]
[Print]
[Top]
|
/*
请教各位前辈:
在我手头的项目里需要用到预处理机制,我打算用它来完成一些CONSTANT的计算,并且希望预处理能够与编译在同一遍(pass)中完成,也就是说我想把PPTOKEN和TOKEN一起处理,不单独做一个预处理器单独扫描一次生成类似什么PCH之类的东西。如果都是常量的话~问题不大,但是,与常规的C不同的是,我的CONSTANT包含了LABLE的地址,也就是标签的地址(我很需要这么做)。
比如:
*/
#macro CalcPageSize( __Arg_Base__, __Arg_Bound__ )
( ( &&__Arg_Bound__ ) - ( &&__Arg_Base__ ) ) //边界地址减去基地址 = 一个SIZE_T
package< g_FooPackage, public >
{
__Lable_CodeBase:
......
segment< PKG_HDR, private >
{
......
dword< dwPkgSize > = CalcPageSize( __Lable_CodeBase, __Lable_CodeBound );
.....
}
......
__Lable_CodeBound:
}
/*
由上面的代码我们看出,BASE标签是在取值前定义的,BOUND标签是在取值后定义的,那么BASE的值我们可以在展开宏“CalcPageSize”确定为一个常量,但是BOUND显然不行,有如下几个几个难处:
1、我们不知道后面还有多少代码。
2、后面的代码文本里面可能也包含了宏,展开后大小就会变大。
3、某些宏使用了递归类语法(非自引用递归)或预处理循环后代码的大小是不确定的。
MY QUESTION:
怎么解决LABLE的相对地址未决与宏展开后CONSTANT-EXPRESSION求值的问题。
REMARK:
一般来说,类似汇编器的语法都是LABLE扫描和预处理单独做,先做LABLE,但是遍数过多,如果文件很多的话就得WRAP很多次,编译速度自然就下来了,很让人郁闷~~~所以不知道能不能有什么好办法。
我曾经尝试的在我的AST上加个RECALC-EXPRESSION这样的FLAG~等全部编译完了以后再去尝试一次那些ID是否可以求值,然后选择报错或者再生成,这显然也是个失败的做法。很希望,很希望能听到您的建议。
*/
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
>>一般来说,类似汇编器的语法都是LABLE扫描和预处理单独做
第一、单纯就 Assembler 而言,十多年以前就已经是单遍扫描多于两遍扫描。
第二、Linker 应该根本不关心语法分析器是单遍扫描还是多遍扫描。
>>我曾经尝试的在我的AST上加个RECALC-EXPRESSION这样的FLAG~等全部编译完了以后再去尝试一次那些ID是否可以求值
这还用试吗?
|
|
|
----
破不破万有, 知一切全知 成一切真我, 现无相本相
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
>>一般来说,类似汇编器的语法都是LABLE扫描和预处理单独做
第一、单纯就 Assembler 而言,十多年以前就已经是单遍扫描多于两遍扫描。
第二、Linker 应该根本不关心语法分析器是单遍扫描还是多遍扫描。
——————————————————————————————————
首先感谢您的参与。
想先对您澄清一下:
一个多遍的汇编器也未必代表它是一个低效的编译器,我觉得这个取决与语法的设计和应用环境的侧重,据了解很多优秀汇编器都喜欢单独把LABLE做为一遍,好象是个比较正规的做法,要不这个LABLE还没被RECOGNIZE,汇编器无法确认它是一个标签还是一个变量,或者说指令选择的时候,汇编器要取决与这个ID的类型选择使用OFFSET 还是XWORD PTR对应处理,没有了这个过程汇编器应该很难计算MOD码以及选择正确的指令,而且由于汇编语言使用了全局标签的语法特性,它的代价最小是两遍也是无可厚非的(仅是我有限的理解,如果有更好的方法,很希望能得到指正),比方说NASM,您也许该看看nasm.c里面的assemble_file()过程,它是多遍的:)
BTW:LINKER当然不关心词法,它也许该多关心点RELOC-RECORD或者是如何更好的更快的多个文件中查找找一个SECTION。另外我的问题描述似乎也与LINKER无关。
我们知道ASM语言的编译器一般都是行编译的,也就是说它没有严格意义上的词法和语法部分,以NASM为例子,它一般这么做:
char* * line = NULL;
#line "nasm.c" 834 // NASM 0.98.38
while ( (line = preproc->getline()) )
{
globallineno++;
//TODO:AS u like:)
}
——————————————————————————————————————————————
>>我曾经尝试的在我的AST上加个RECALC-EXPRESSION这样的FLAG~等全部编译完了以后再去尝试一次那些ID是否可以求值
这还用试吗?
——————————————————————————————————————————————
因为在全部标签扫描和预处理完成前,我的编译器无法得知那些没有被识别的标签的RVA(PS:我也知道填零然后等待下一阶段去RELOC,不过在这我不想讨论这个,因为有的地方需要的是值,并不是所有标签都是用来Bcc/JMP的~),起码目前我还没找到好办法,所以我现在也很头疼这个问题。此外我也想顺便的稍微做优化一下,做点简单的CONSTANT PRECALC的工作:p 不过优化做的真不多,所以看起来这个方法的确有点做作,也许时间能使这个令我烦恼的机制有所改变:)
——————————————————————————————————————————————
ADDITIONAL REMARK:
my “Compiler” is not an "Assembler ",it's a human readable meta-language translator,
it uses for check whether my compiler works properly or not, and build a VM-IMAGE file as soon as possible.
_____________________________________________________________________________________
OK~~RETURN TO THE QUESTION:
i still want to find a way which i can complete the preprocess and lable regonition in one pass,maybe someone doesn't understand why i do it this way,cause my IMAGE-FILE is working in a vitrual machine over the window$. it used filemapping and virtualalloc mechanism to load it, so as we know , we must care about the memory alignment problem. sometimes we need to calculate the size of the section, and do some padding, i do i t as a PP-LOOP-DIRECTIVE,such as:
.......
#const segSize = Lable_Bound - Lable_Base
.......
#if NEED_PADDING
# loop segSize % PAGESZIE
# emit __bytefield( PADDING_BYTE , 1 )
# end loop
#end if // NEED_PADDING
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
Maybe, depend on how do you define the meaning of "online" for a forum.
This forum have email notifying, so any time you reply my post, I am always online.
|
|
----
破不破万有, 知一切全知 成一切真我, 现无相本相
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
|
You are not a compiler developer. What you say is just bosh. I need not discuss any detail of your post, it is senseless.
|
|
----
破不破万有, 知一切全知 成一切真我, 现无相本相
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
呵呵~~这样就不对了~务实点,别炒概念~~既然要否认别人就拿出证据来,做概念贩子是要被鄙视的:)
我想我所接触的东西的确还比较肤浅,总有个过程对吧? 另外讨论是平等和相互尊重的,用词过于偏激和泛泛是说服不了别人地,大家都是做技术的,用事实说话。何必这么大火气 对人褒贬?要牛气也得下点料吧~呵呵~~哎~~~~~
|
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
|
So, I am noble, so what? I need not discuss anything.
|
|
----
破不破万有, 知一切全知 成一切真我, 现无相本相
|
|
[Original]
[Print]
[Top]
|
|
[Original]
[Print]
[Top]
|
canopy前辈:
回填解决了我第一个问题,的确是我我看书不细致(BTW:TO BarcLiao:昨天晚上晚些时候与您在MSN上争论,您告诉我书里面有,让我自己去找,我不相信。最后的确是我没找到,在这向您道歉,希望您海涵:) ),也是我现在太急于求成,不知道canopy前辈是否愿意继续指点一二?我还有一个小问题,就是这个标签取值的问题在AST还没形成之前该怎么做?我想把LABLE的地址值作为一个PP-CONSTANT来使用是不是可行呢?大概想法是这样,想在预处理里面把标签的地址作为一个常量,然后用两个标签的差来和“Allocation Granularity”相MOD,然后在预处理里决定是否要把这个差值给填填充上一些东西。主要是想在预处理里面做。刚刚接触编译原理不久,没有什么经验,所以很多东西要从头开始做的时候觉得特别迷茫。所以如果您能再点一下,就象刚刚,那对我帮助太大了!先谢谢了!
|
|
|
[Original]
[Print]
[Top]
|
|
|