Compiling DMD parser?
davidl
davidl at 126.com
Tue Jul 15 08:00:07 PDT 2008
在 Tue, 15 Jul 2008 16:44:25 +0800,Markus Koskimies
<markus at reaaliaika.net> 写道:
> On Mon, 14 Jul 2008 04:07:00 +0000, Markus Koskimies wrote:
>
>>> actually dparser is not 1.014 anymore. it's somewhat 1.024ish the
>>> parsing ability has been improved a lot, it can parse itself, and some
>>> ctfes.
>>> 700 or so cases from dstress fail.
>>
>> :o
>>
>> I fetched the sources (I tried to select the latest ones), and attached
>> that DParser to my own code.
>
> Jihuu! Now it works!
>
> I wrote a somewhat general purpose AST walker. It can be inherited and
> modified for different purposes. As an example, I made a class for
> scanning unused local variables:
>
> class UnusedScan : ASTWalk
> {
> /* To track down variable usage from nested functions, the
> * variable reference table is global.
> */
> bool[VarDeclaration] referenced;
> /* Frame holds list of local variable definitions */
> class Frame { VarDeclaration[] vars; }
>
> Stack!(Frame) frames;
>
> //-------------------------------------------------------------------------
> // Whenever we meet a new variable frame, push it. When popping it
> out,
> // we check, if the variable was referenced.
> //-------------------------------------------------------------------------
> void push()
> {
> frames.push( new Frame() );
> }
> void pop()
> {
> Frame frame = frames.pop();
> foreach(VarDeclaration var; frame.vars)
> {
> if(referenced[var]) continue;
> writefln("%s: Unused variable: %s",
> var.loc.toString(),
> var.toString()
> );
> }
> }
> //-------------------------------------------------------------------------
> // Constructor
> //-------------------------------------------------------------------------
> this()
> {
> frames = new Stack!(Frame)();
> }
>
> //-------------------------------------------------------------------------
> // Whenever we meet a function, class or similar, make a new frame.
> // After scanning, check if there were unreferenced variables.
> //-------------------------------------------------------------------------
>
> override void walk(Module m)
> {
> push(); super.walk(m); pop();
> }
> override void walk(ClassDeclaration d)
> {
> push(); super.walk(d); pop();
> }
> override void walk(FuncDeclaration f)
> {
> push(); super.walk(f); pop();
> }
> //-------------------------------------------------------------------------
> // For every var declaration, put it to frame.
> //-------------------------------------------------------------------------
> override void walk(VarDeclaration var)
> {
> referenced[var] = false;
> frames.top().vars ~= var;
> }
>
> //-------------------------------------------------------------------------
> // When var is used, mark it to frame.
> //-------------------------------------------------------------------------
> override void walk(VarExp var)
> {
> referenced[cast(VarDeclaration)var.var] = true;
> }
> }
>
> ---
>
> Then I tested it against a small D program:
>
> import std.stdio;
>
> void main()
> {
> int a, b;
> int unused;
>
> // a is used inside expression
> writefln("%d", 23+a);
>
> // b is used from local function
> int f1() { int f2() { return b; } return f2(); }
>
> // unused is shadowed; still, the main unused should remain
> // not referred.
> void f3() { int unused; unused = 1; }
> return;
> }
>
> ---
>
> And it reports:
>
> PASS 1: Building parse tree...
> semantic1 done
> semantic2 done
> semantic3 done 0
> PASS 2: Walking parse tree...
> UnusedLocal1.d(8): Unused variable: unused
>
> ...Just as it should do :D
>
> I'll put the full sources available somewhere (to my home pages, at
> least), and continue developing walking & warning thing.
>
> Davidl, do you want the sources for your repository?
Of course!
Send me the patch? If you get a dsource account, maybe you're the right
guy to cooperate on this interesting project, I may grant you write access
;)
--
使用 Opera 革命性的电子邮件客户程序: http://www.opera.com/mail/
More information about the Digitalmars-d
mailing list