lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


gcc 3 allows you to dump parse information:

gcc -c -fdump-translation-unit -fno-builtin -ffreestanding x.c

This creates x.c.tu, which is a textual representation of a parse tree.
I'm not sure what you get from C++ files but for C files you seem only to
get type information. (And lots of it, despite the attempt above to eliminate
builtin stuff.)

Anyway, .tu files are large and a pain to read. So here is a Lua program that
parses .tu files and builds a table containing the parse tree. This should
make it easier to parse and use the information in .tu files.

Here is an example:

$ cat x.c
int myX;
double myY;
typedef struct { float campoX, campoY; } myPoint;
myPoint myP;

const char* myT="Hello world";

$ lua tu.lua < x.c.tu
1       myT     pointer_type    x.c:6
4       myP     record_type     x.c:4
34      myY     real_type       x.c:2
43      myX     integer_type    x.c:1

If you follow the tree deeper you'd get all the type information for those
variables.

I'm not sure what you can do with this (automatic binding generation comes
to mind). I hope the code below is useful anyway.

Enjoy!
--lhf

-- tu.lua
-- parse gcc .tu files

local function add(i,T)
	local a=T[i]
	if a==nil then a={} T[i]=a end
	return a
end

local function store(L,T)
	if L then
		local ok,_,i,k=string.find(L,"^@(%d+) +(%S+)")
		assert(ok,"bad line")
		i=tonumber(i)
		local t=add(i,T)
		t.text=L
		t.kind=k
		for k,v in string.gfind(L,"(%w+): +(%S+)") do
			local _,_,j=string.find(v,"^@(%d+)$")
			if j then j=tonumber(j) v=add(j,T) assert(v,j) end
			t[k]=v
		end
	end
end

local function load(f)
	local T={}
	local L
	while true do
		local l=f:read()
		if l==nil then break end
		if string.find(l,"^@")  then
			store(L,T)
			L=l
		elseif string.find(l,"^ ") then
			L=L..l
		else
			error"bad line"
		end
	end
	store(L,T)
	return T
end

local T=load(io.stdin)

W={
var_decl = true,
-- type_decl = true,
-- function_decl = true,
}

for i,t in T do
	if W[t.kind] then
		if t.name then
			print(i,t.name.strg,t.type.kind,t.srcp)
		else
			print(i,nil,t.type.kind,t.srcp)
		end
	end
end