tslediter/funcext/tvclib/parserch.tsf

749 lines
17 KiB
Plaintext

unit parserch ;
{**
@explan(说明)c头文件解析对外 接口 %%
**}
interface
function pcstruct(s,f);
function parserctokens(str);
function chtotslclass();
(*
//str := data();
//echo tostn(str22array(str)[:,3]);
//for := 0 to length(str) do
//return echo tostn(getgdihdata());
s := "
typedef struct _GdiplusStartupInput {
unsigned int GdiplusVersion;
unsigned int DebugEventCallback;
BOOL SuppressBackgroundThread;
BOOL SuppressExternalCodecs;
}GdiplusStartupInput;
";
return echo tostn(parsercstruct(parserctokens(s)));
rt := parsergdifunction(parserctokens(getgdihdata()));
echo tostn(rt);
*)
Implementation
function chtotslclass();
begin
parsergdifunction(parserctokens(getgdihdata()));
end
function pcstruct(s,f);
begin
{**
@explan(说明) 解析c结构体字符串到tsl结构化数据 %%
@param(s)(string) c结构体字符串 %%
@param(f)(bool) true 转换为小写 %%
@return(array) tag字段为名称
field 为字段信息
n : 名称
t : 类型 一个数组如果 array(unsigned,int)
l : 如果为数组 数组的长度
p : 如果为指针,指针的*个数
nick 别名
**}
return parsercstruct(parserctokens(f?lowercase(s):s));
end
function parsercstruct(tokens,indx);
begin
{**
@explan(说明)结构体解析 %%
**}
//名称
//别名,可能多个
//内容
len := length(tokens);
indx := indx ?: 0;
ret := array();
while indx<len do
begin
indx++;
v := tokens[indx,0];
if v="struct" then
begin
//indx++;
//ret["tag"] := tokens[indx,0];
ret["tag"]:= v;
end else
if v="{" then
begin
ret["field"]:= getstruct(tokens,indx,len);
ret["nick"]:= getstructnickename(tokens,indx,len);
return ret;
end else
if not(v in array(" ","\r","\n","\t"))then
begin
ret["tname"]:= v;
end
end
end
function getstructnickename(tokens,indx,len);
begin
{**
@explan(说明) 获取typedef 别名
**}
ret := array();
lret := 0;
while indx<len do
begin
indx++;
tkv := tokens[i,0];
if tkv=";" then
begin
return ret;
end else
if tkv="*" then
begin
end else
if tkv="," then
begin
end else
begin
ret[lret++]:= tkv;
end
end
return nil;
end
function getstruct(tokens,indx,len);
begin
{**
@explan(说明)获取struct字段定义
**}
ret := array();
//类型
//名称
//指针
//数组长度
lx := array();
lxlx := "";
mc := "";
ct := 0;
cd := "";
zz := 0;
while indx<len do
begin
indx++;
if tokens[indx,2]="//" or tokens[indx,2]="/*" then continue;
tkv := tokens[indx,0];
if tkv="}" then
begin
return ret;
end else
if tkv=";" then
begin
if not(mc)then mc := lxlx;
ret[ct++]:= array("n":mc,"t":lx,"l":cd,"p":zz);
lxlx := "";
mc := "";
cd := "";
zz := 0;
lx := array();
end else
if tkv="*" then
begin
zz++;
end else
if tkv="[" then
begin
while indx<len do
begin
indx++;
if tokens[indx,2]="//" or tokens[indx,2]="/*" then continue;
tkvi := tokens[indx,0];
if tkvi="]" then
begin
break;
end else
begin
cd += tkvi;
end
end
end else
begin
if lxlx then lx[length(lx)]:= lxlx;
lxlx := tkv;
end
end
end
function getgdihdata(rpth);
begin
{**
@explan(说明) 获取c头文件数据
**}
rpth := "E:\\360yun\\tinysoft\\tslAPI\\gdiplus\\gdiplusflat.h";
sz := filesize("",rpth);
if readFile(rwRaw(),"",rpth,0,sz,rdd)then return rdd;
return " ";
end
function str22array(str);
begin
{**
@ignore 忽略
**}
kg := array("\r","\t"," ");
hh := "\n";
kghh := kg union array(hh);
ret := array();
c := 0;
r := 0;
vs := "";
lret := 0;
stt := 0;
for i := 1 to length(str) do
begin
vi := str[i];
ifkg := vi in kg;
if(ifkg)and vs then
begin
ret[lret++]:= array(r,c,vs);
vs := "";
c++;
continue;
end else
if(vi=hh)then
begin
if vs then
begin
ret[lret++]:= array(r,c,vs);
vs := "";
end
if lret then r++;
c := 0;
end else
if not(vi in kghh)then
begin
vs += vi;
end
end
if vs then ret[lret++]:= array(r,c,vs);
//return ret;
rt := array();
for i,v in ret do
begin
rt[v[0],v[1]]:= v[2];
end
return rt;
end
function bdstring(str,len,f,fl,pos);
begin
{**
@explan(说明)字符串匹配查找
**}
bud := true;
for i := 1 to fl do
begin
vpos := pos+i-1;
if vpos>len then return 0;
if str[vpos]<> f[i]then
begin
bud := false;
break;
end
end
if bud then
begin
pos +=(fl-1);
end
return bud;
end
function findstringv(str,f,len,pos,zy,hl);
begin
{**
@explan(说明)查找以f结尾的字符串
**}
vs := "";
fl := length(f);
while pos<len do
begin
pos++;
vi := str[pos];
if vi=hl then continue;
if bdstring(str,len,f,fl,pos)then break;
if zy=vi then
begin
vs += str[pos];
pos++;
continue;
end
vs += vi;
end
return vs;
end;
function setvalue(dt,vs,indx,tp);
begin
{**
@explan(说明)保存token
**}
if vs then dt[length(dt)]:= array(vs,indx,tp);
vs := "";
end
function parserctokens(gdis);
begin
{**
@explan(说明)c分词 %%
**}
len := length(gdis);
indx := 0;
kg := array("\n","\t"," ");
vs := "";
ret := array();
while indx<len do
begin
indx++;
vi := gdis[indx];
if vi="\r" then continue;
if vi="\\" then
begin
setvalue(ret,vs,indx,"token");
vip := gdis[indx+1];
if vip="\r" then
begin
vip := gdis[indx+2];
if vip="\n" then
begin
setvalue(ret,"\\\r\n",indx,"link");
indx += 2;
end
end else
if vip="\n" then
begin
setvalue(ret,"\\\n",indx,"link");
indx += 1;
end
end else
if vi=">" then
begin
setvalue(ret,vs,indx,"token");
vip := gdis[indx+1];
if vip="=" then
begin
indx++;
setvalue(ret,">=",indx,"sym");
end else
setvalue(ret,">",indx,"sym");
end else
if vi="<" then
begin
setvalue(ret,vs,indx,"token");
vip := gdis[indx+1];
if vip="=" then
begin
indx++;
setvalue(ret,"<=",indx,"sym");
end else
setvalue(ret,"<",indx,"sym");
end else
if vi="=" then
begin
setvalue(ret,vs,indx,"token");
vip := gdis[indx+1];
if vip="=" then
begin
indx++;
setvalue(ret,"==",indx,"sym");
end else
setvalue(ret,"=",indx,"sym");
end else
if vi="[" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,"[",indx,"sym");
end else
if vi="]" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,"]",indx,"sym");
end else
if vi="&" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,"&",indx,"sym");
end else
if vi="*" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,"*",indx,"*");
end else
if vi="," then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,",",indx,",");
end else
if vi=";" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,";",indx,";");
end else
if vi="(" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,"(",indx,"(");
end else
if vi=")" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,")",indx,")");
end else
if vi="{" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,"{",indx,"sym");
end else
if vi="}" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,"}",indx,"sym");
end else
if vi="|" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,vi,indx,"sym");
end else
if vi="?" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,vi,indx,"sym");
end else
if vi=":" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,vi,indx,"sym");
end else
if vi="'" then
begin
setvalue(ret,vs,indx,"token");
vs := findstringv(gdis,"'",len,indx,"\\");
setvalue(ret,vs,indx,"'");
end else
if vi='"' then
begin
setvalue(ret,vs,indx,"token");
vs := findstringv(gdis,'"',len,indx,'\\');
setvalue(ret,vs,indx,'"');
end else
if vi="/" then
begin
setvalue(ret,vs,indx,"token");
vip := gdis[indx+1];
if vip="/" then
begin
indx += 1;
vs := findstringv(gdis,"\n",len,indx,nil,"\r");
setvalue(ret,vs,indx,"//");
end else
if vip="*" then
begin
indx += 1;
vs := findstringv(gdis,"*/",len,indx,nil);
setvalue(ret,vs,indx,"/*");
end else
begin
setvalue(ret,"/",indx,"/");
end
end else
if vi in kg then
begin
setvalue(ret,vs,indx,"token");
end else
if vi="\n" then
begin
setvalue(ret,vs,indx,"token");
setvalue(ret,"\n",indx,"\n");
end else
vs += vi;
end
setvalue(ret,vs,indx,"token");
return ret;
//writetofile("",ret);
//parsergdifunction(ret);
end
function nexttoken(tokens,indx,f);
begin
if not(f)then indx++;
return tokens[indx];
end
function backtoken(tokens,indx,f);
begin
if not(f)then indx--;
return tokens[indx];
end
function parsergdifunction(tokens);
begin
{**
@explan(说明) 提取头文件函数
**}
len := length(tokens)-1;
indx :=-1;
isyms := array("GDIPCONST","_In_","_Out_");
ret := array();
retl := 0;
hst := array();
s := "type TGdiplusflat=class\r\n";
s += "{**
@explan(说明)gdi+ 的c接口函数 %%
**}\r\n";
zs := "";
while indx<len do
begin
indx++;
tokent := tokens[indx,2];
tokenv := tokens[indx,0];
if tokenv in isyms then continue;
if tokent="/*" then
begin
//echo tostn(tokens[indx]);
zs += "(* "+tokenv+" *)\r\n";
end else
if tokent="//" then
begin
zs += "//"+tokenv+"\r\n";
end else
if tokenv="(" then
begin
cs := parenthesis(tokens,indx,len,1,isyms);
s += zs;
s += "\tclass ";
s += createhs(hst,cs)+"\r\n";
hst := array();
zs := "";
end else
begin
hst[length(hst)]:= tokens[indx];
end
end
s += "\r\nend ";
writetofile2(pp,s);
end
function createhs(hd,bd);
begin
{**
@explan(说明)构造函数声明
**}
//echo tostn(bd);
lex := array("INT":"integer",
"REAL":"single",
"float":"single",
"INT64":"int64",
"double":"double",
"int":"integer",
"UINT":"integer",
"void":1,
"VOID":1,
"ARGB":"integer",
"GpStatus":"integer",
"GpWrapMode":"integer",
"TextRenderingHint":"integer",
"SmoothingMode":"integer",
"GpFillMode":"integer",
"COLORREF":"integer",
"COLOR16":"short",
"WCHAR":"string",
);
ret := "Function ";
havlx := true;
ct := "stdcall";
tp := nil;
for i := 0 to length(hd)-1 do
begin
hdi0 := hd[i,0];
vi := hd[i,0];
lx := lex[vi];
if vi=";" then
begin
continue;
end
if vi="*" then
begin
tp := "pointer";
end else
if hdi0="WINGDIPAPI" then
begin
ct := "stdcall"; //
break;
end else
if hdi0="WINAPI" then
begin
ct := "stdcall";
break;
end else
if havlx and ifstring(lx)then
begin
havlx := false;
tp := lx;
end else
if havlx and lx=1 then
begin
havlx := false;
tp := 1;
end else
if havlx then
begin
havlx := false;
tp := "pointer";
end
end
fn := hd[length(hd)-1,0];
if tp=1 then
begin
ret := "procedure ";
tp := "";
end else
tp := ":"+tp;
fn := fn ?: "";
ret +=(fn ?: "")+"(";
ps := "";
dpn := "pn";
havlx := true;
ddpoint := 0;
for i := 0 to length(bd)-1 do
begin
vi := bd[i,0];
tvi := bd[i,2];
if vi="," then
begin
if not(pn)then pn := dpn+inttostr(i);
ps +=((ddpoint>1)?"var ":"")+gzhparam(pn);
ps += ":"+plx;
pn := 0;
ps += ";";
plx := 0;
havlx := true;
ddpoint := 0;
end else
if plx and(tvi="token")then
begin
pn := vi;
end else
if vi="*" then
begin
ddpoint++;
if plx in array("integer","single","hbitmap")then
begin
ddpoint++;
end else
if plx="string" then
begin
end else
plx := "pointer";
end else
if havlx and lex[vi]then
begin
havlx := false;
plx := lex[vi];
end else
if havlx then
begin
havlx := false;
plx := "pointer";
end else
if vi="[" {or vi = "]"}or vi="&" then
begin
plx := "pointer";
end
end
if plx then
begin
if not(pn)then pn := dpn+inttostr(i);
ps +=((ddpoint>1)?"var ":"")+gzhparam(pn)+":"+plx;
end
ret += ps;
//echo tostn(array(tp,ct,fn));
ret += format(')%s;%s;external "gdiplus.dll" name "%s";',tp,ct,fn);
//echo tostn(ret),"\r\n";
return ret;
end
function gzhparam(p);
begin
{**
@explan(说明) 特殊参数名替换
**}
if p="order" then return "order_";
else if p="unit" then return "unit_";
else if p="on" then return "on_";
return p;
end
function parenthesis(tokens,pos,len,iffunc,isyms);
begin
{**
@explan(说明) 函数参数解析
**}
ret := array();
retl := 0;
tkv := "";
while pos<len do
begin
pos++;
tk := tokens[pos];
tkt := tk[2];
if tk[0]in isyms then continue;
if tkt=")" then
begin
//跳出
//pos++;
return ret;
end else
begin
if iffunc and tkt="(" then
begin
if ret[retl-1][2]="token" then
begin
retl--;
reindex(ret,array(retl:nil));
end
parenthesis(tokens,pos,len,0,isyms);
end else
if iffunc then
begin
ret[retl++]:= tk;
end
tkv := tk[0];
end
end
end
function writetofile(pp,dt);
begin
{**
@explan(说明)保存分词结果到文件
**}
pp := "E:\\360yun\\tinysoft\\tslAPI\\gdiplus\\gdiplusflat.txt";
s := tostn(dt);
if FileExists("",pp)then
begin
filedelete("",pp);
end
writefile(rwRaw(),"",pp,0,length(s),s);
end
function writetofile2(pp,s);
begin
{**
@explan(说明)保存gdi函数到文件
**}
pp := "E:\\GitHub\\tsluilib\\tsluifunc\\TGdiplusflat.tsf";
if FileExists("",pp)then
begin
filedelete("",pp);
end
writefile(rwRaw(),"",pp,0,length(s),s);
end
function gdiplusfname();
begin
{**
explan(说明)读取gdi函数名
**}
rpth := "E:\\360yun\\tinysoft\\tslAPI\\gdiplus\\gdiplus.def";
sz := filesize("",rpth);
if readFile(rwRaw(),"",rpth,0,sz,rdd)then
begin
str22array(rdd);
end
return " ";
end
end.