阅读:2545回复:5
用XML实现编程语言间的互译 [分享]
用XML实现编程语言间的互译
编程语言间的隔阂虽然不如人类语言间的隔阂那么大,但确实是比较困挠程序员的一个问题。如果能通过某种方法实现象Delphi->c之类的转换,将是一件引人注目的事情,但这也许并不能使人们花大量的时间来实现这样的转换。我们来看,如果你是一个Delphi或C++Builder的高手,你一定做过这两者间的转换吧。每天都有大量的人做这类事的事情将带来多么大的浪费呀。而且,如果真的有可能实现的话,无疑会为开发智能编程机器积累技术和经验,给象国产的易语言这类生僻的编程语言更大的生机。为此,我作了一些思考。 首先,我们应当慢慢来。我假设所要面对的是普通的Windows GUI程序,为使用更多的先进技术(大部分的商业软件就是如此)。因为Windows编程几乎全部基于Windows API中的函数。所以,有比较好的共性。在选择转换技术上我选择了XML。因为它得到了广泛的支持,且有很强的扩展性。主题思想如下图: V B || \ / \/ XML(面向具体的编程语言,仅仅考虑完善的描述不考虑通用性。 || \ / \/ Delphi =====>> XML(同上)====>>>XPML(我瞎编的,一种通用性的程序描述格式,使用xml)………… /\ / \ || || XML(同上) /\ / \ || || C++Builder 这种花瓣形的互译模式,可以减少许多过程。转换时面对的都是统一的标准格式XPML。简明可操作。 然后要着手是使编程语言到描述其的XML语言的转换。我已经坐了一小步,定了一个描述delphi语言源文件的xml格式,描述了dpr,pas,dfm文件。如下: <?xml version="1.0" encoding="gb2312"?> <delphi> <project> <program>Project1 </program> <uses><name>Forms</name> </uses> <uses><name>Unit1</name><path>Unit1.pas</path><comment>Form1</comment> </uses> <res> </res> <Initialize> <exp><Application><Initialize></Initialize></Application></exp> <exp><Application><CreateForm><param>TForm1</param><param>Form1</param></CreateForm></Application></exp> <exp><Application><Run></Run></Application></exp> </Initialize> </project> <description> <Unit1> <Form1 source='TForm1'> <attribute> <Left>192</Left> <Top>107</Top> <Width>544</Width> <Height>375</Height> <Caption>'Hello World'</Caption> <Color>clBtnFace</Color> <Font> <Charset>DEFAULT_CHARSET</Charset> <Color>clWindowText</Color> <Height>-11</Height> <Name>'MS Sans Serif'</Name> <Style>[]</Style> </Font> <OldCreateOrder>False</OldCreateOrder> <PixelsPerInch>96</PixelsPerInch> <TextHeight>13</TextHeight> </attribute> </Form1> </Unit1> </description> <source> <Unit1> <interface> <uses>Windows </uses> <uses>Messages </uses> <uses>SysUtils </uses> <uses>Classes </uses> <uses>Graphics </uses> <uses>Controls </uses> <uses>Forms </uses> <uses>Dialogs </uses> </interface> <implementation> </implementation> </Unit1> </source> </delphi> 然后编出具体的代码,实现这一步的转换,我也坐了一小步,实现了dpr->xml的一部分,即转换工程名,Uses段和资源段,初始化段上为实施。如下,程序使用Windows Scripting Host写的,很业余,运行请保存为*.js双击即可。 // Windows Script Host to convert delphi's project file into xml file // // ------------------------------------------------------------------------ // Copyright (C) 2001 hcstudio // // You have a royalty-free right to use, modify, reproduce and distribute // the Application Files (and/or any modified version) in any way // you find useful, provided that you agree that hcstudio has no warranty, // obligations or liability for any Application Files. // ------------------------------------------------------------------------ // This script will convert delphi's project file into xml file. var source; var program,uses,resource; var program=new Array(); var uses = new Array(); filename="Project1.dpr"; source=ReadFile(filename); program=FindProgram(source); uses=FindUses(program[1]); resource=FindResource(uses[uses.length-1]); program=program[0]; CreateXml(program,uses,resource); ////////////////////////////////////////////////////////////////////////////////// // // ReadFile to parse and return the file content as string // function ReadFile(filename) { var fso,file,stream,source; fso = new ActiveXObject("Scripting.FileSystemObject"); file = fso.GetFile(filename); stream = file.OpenAsTextStream(1,-2); source=stream.readall(); return(source); } ////////////////////////////////////////////////////////////////////////////////// // // Find the Program name and return the rest // function FindProgram(source) { var program,next,uptarget,downtarget,up,down; var toReturn; uptarget=/program/; downtarget=/;/; up=source.search(uptarget); down=source.search(downtarget); program=source.substring(up,down); uptarget=/\s/; up=program.search(uptarget); program=program.slice(up); next=source.slice(down+1); var toReturn=new Array(); toReturn[0]=program; toReturn[1]=next; return(toReturn); } ////////////////////////////////////////////////////////////////////////////////// // // A group of function to find uses // function FindUses(source) { var uses; uses=new Array(); var Uses,uptarget,downtarget,up,down; uptarget=/uses/; downtarget=/;/; up=source.search(uptarget); down=source.search(downtarget); Uses=source.substring(up,down); uptarget=/\s/; up=Uses.search(uptarget); Uses=Uses.slice(up); uses=FindUsesDetail(Uses); next=source.slice(down+1); uses[uses.length]=next; return(uses); } function FindUsesDetail(Uses) { var auses,first,second,ifin,ifleft,ifright,i; first=new Array(); auses=new Array(); first=Uses.split(","); ifin=/\sin\s/; ifleft=/'*'/; ifright=/\./; for(i=0;i<first.length;i++) { if(first.search(ifin)==-1) { auses[i*2]=first; auses[i*2+1]=0; } else { auses[i*2]=first.substring(0,first.search(ifin)); auses[i*2+1]=first.substring(first.search(ifleft)+1,first.search(ifright)+4); } } return(auses); } ////////////////////////////////////////////////////////////////////////////////// // // Find the Resource and return the next // function FindResource(source) { var ifres,resource, j,found; ifres=/{/; var resource=new Array(); j=0; do { if(found!=-1) { found=source.search(ifres); resource[j]=source.substring((found+3),source.search(/}/)); j++; source=source.slice(source.search(/}/)+1); } } while (found!=-1); resource[resource.length]=source; return(resource); } ////////////////////////////////////////////////////////////////////////////////// // // to createXml file using program,uses(array of string) // function CreateXml(program,uses,resource) { var filename; filename="delphi.xml"; WriteFlag(filename); var i; var xmlDoc = new ActiveXObject("Msxml2.DOMDocument"); xmlDoc.load(filename); var rootElement=xmlDoc.createElement("delphi"); var projectElement=xmlDoc.createElement("Project"); var programElement=xmlDoc.createElement("program"); var programElementText=xmlDoc.createTextNode(program); programElement.appendChild(programElementText); projectElement.appendChild(programElement); for(i=0;i<uses.length-1;i=i+2) { var usesElement=xmlDoc.createElement("uses"); var usesnameElement=xmlDoc.createElement("name"); var usespathElement=xmlDoc.createElement("path"); var usesnameElementText=xmlDoc.createTextNode(uses); var usespathElementText=xmlDoc.createTextNode(uses[i+1]); usesnameElement.appendChild(usesnameElementText); usespathElement.appendChild(usespathElementText); usesElement.appendChild(usesnameElement); usesElement.appendChild(usespathElement); projectElement.appendChild(usesElement); } for(i=0;i<resource.length-2;i++) { var resourceElement=xmlDoc.createElement("resource"); var resourceElementText=xmlDoc.createTextNode(resource); resourceElement.appendChild(resourceElementText); projectElement.appendChild(resourceElement); } rootElement.appendChild(projectElement); xmlDoc.appendChild(rootElement); xmlDoc.save(filename); } function WriteFlag(filename) { var fso,file,stream,source; fso = new ActiveXObject("Scripting.FileSystemObject"); file = fso.CreateTextFile(filename,true); file.WriteLine("<?xml version=\"1.0\" encoding=\"gb2312\"?>"); file.Close(); } ////////////////////////////////////////////////////////////////////////////////// // // for debug use // function Display(program) { var WshShell = WScript.CreateObject("WScript.Shell") WshShell.Popup(program); } 最后综合各种语言的xml描述形式,定出XPML(Extensive Programming Markup Language)的标准。关键的互译开始了。 |
|
1楼#
发布于:2004-10-02 19:57
re
|
|
2楼#
发布于:2004-10-11 13:32
数据
<img src="images/post/smile/dvbbs/em02.gif" /> |
|
3楼#
发布于:2004-10-11 13:33
re
<img src="images/post/smile/dvbbs/em04.gif" /><img src="images/post/smile/dvbbs/em05.gif" /> |
|
4楼#
发布于:2004-10-11 13:34
re
<img src="images/post/smile/dvbbs/em02.gif" /> |
|
5楼#
发布于:2004-10-11 22:19
xml包治百病。还是要衡量啊。
|
|