2007-08-01
python的小工具,把hibernate reverse engine生成的java文件转换为scala的
关键字: java scala python hibernate regexp最近需要把hibernate reverse enginering生成的java entity代码转换为scala的(虽然scala能够直接调用java的代码)。Scala的语法虽然和java很相近,但是手工改起来还是很麻烦。
先是考察了antlr,不过由于hibernate生成的文件格式十分工整,用antlr似乎有点牛刀杀鸡的嫌疑。看了python antlr的文档,发现antlr3的语法变得厉害,而且对ast解析的tree parser也很复杂,不像是短时间内能搞定的,于是决定放弃lexer,裸写正则表达式处理,主要牵涉到annotation、构造函数以及函数定义的处理,大约2个多小时完工,这是代码。
python 代码
- import os,sys,re
- def doFunction(*args):
- arglist = args[3].split(",")
- newargs = []
- for arg in arglist:
- newargs.append( re.sub("(\S+)\s+(\S+)", r"\2: \1", arg.strip()) )
- newargstr = ", ".join(newargs)
- return "%sdef %s(%s) = %s\n" % (args[0], args[2], newargstr, args[4])
- def doConstructor(*args):
- arglist = args[2].split(",")
- newargs = []
- for arg in arglist:
- newargs.append( re.sub("(\S+)\s+(\S+)", r"\2: \1", arg.strip()) )
- newargstr = ", ".join(newargs)
- return "%sdef this(%s) = %s\n%sthis();\n" % (args[0], newargstr, args[3], " "*16)
- def doAnnotation(*args):
- arglist = args[2].split(",")
- newargs = []
- for arg in arglist:
- newargs.append( re.sub("(\S+)\s*=\s*(\S+)", r"val \1 = \2", arg.strip()) )
- newargstr = ", ".join(newargs)
- return "%s@%s{%s}%s" % (args[0], args[1], newargstr, args[3])
- isInDefaultConstructor = False
- def enterDefaultConstructor(*args):
- global isInDefaultConstructor
- isInDefaultConstructor = True
- return ""
- def leaveDefaultConstructor(*args):
- global isInDefaultConstructor
- if isInDefaultConstructor:
- isInDefaultConstructor = False
- return ""
- else:
- return "%s}%s" % (args[0], args[1])
- funclist = (
- ("(\s*)public\s+(\S+)\s*\(([^\)]+)\)(.*)", doConstructor),
- ("(\s*)public\s+(\S+)\s+([^\(;{]+)\s*\(\s*([^\)]+)\s*\)(.*)", doFunction),
- ("(\s*)public\s+(\S+)\s*\(\s*\)(.*)", enterDefaultConstructor),
- ("(\s*)}(\s*)", leaveDefaultConstructor),
- ("(\s*)@(\w+)\(([^\)=]+=[^\)]+)\)([^{]*)", doAnnotation),
- )
- relist = (
- ("import ([^;\*]+)(\*);", r"import \1._"),
- ("import ([^;\*]+);", r"import \1"),
- ("(\w+)\s+class\s+(\w+)\s+implements(.*)", r"class \2 extends \3"),
- ("(\s*)public\s+(\S+)\s+([^;\(]+);", r"var \3: \2 = _"),
- ("(\s*)private\s+(\S+)\s+([^;\(]+);", r"\1private var \3: \2 = _"),
- ("(\s*)public\s+(\S+)\s+([^\(;{]+)\s*\(\s*\)(.*)", r"\1def \3() = {"),
- ("(\s*)return\s+([^;]+);(.*)", r"\1\2"),
- )
- def convert(inputfile, outputfile):
- input = file(inputfile, "r")
- output = file(outputfile, "w")
- for eachline in input.readlines():
- matched = False
- for reitem in relist:
- if re.match(reitem[0], eachline):
- newline = re.sub(reitem[0], reitem[1], eachline)
- matched = True
- print newline.rstrip()
- output.write(newline)
- continue
- if matched:
- continue
- for reitem in funclist:
- result = re.match(reitem[0], eachline)
- if result:
- newline = reitem[1](*result.groups())
- matched = True
- print newline
- output.write(newline)
- continue
- if matched:
- continue
- print eachline
- output.write(eachline)
- def getOutputFilename(inputfile):
- if inputfile.endswith(".java"):
- return inputfile[:-5] + ".scala"
- else:
- return inputfile + ".scala"
- if __name__ == "__main__":
- inputfile = "./src/base/input.java"
- outputfile = getOutputFilename(inputfile)
- convert(inputfile, outputfile)
输入一个java文件
java 代码
- package base;
- import java.util.Date;
- import javax.persistence.Column;
- import javax.persistence.Entity;
- import javax.persistence.Id;
- import javax.persistence.Table;
- import javax.persistence.Temporal;
- import javax.persistence.TemporalType;
- /**
- * VoteVote generated by hbm2java
- */
- @Entity
- @Table(name = "mytable", catalog = "mydb")
- public class MyTable implements java.io.Serializable {
- private int id;
- private String text;
- private Date date;
- private String tags;
- public VoteVote() {
- }
- public VoteVote(int id, String text, Date date) {
- this.id = id;
- this.text = text;
- this.date = date;
- }
- public VoteVote(int id, String text, Date date, String tags) {
- this.id = id;
- this.text = text;
- this.date = date;
- this.tags = tags;
- }
- @Id
- @Column(name = "id", unique = true, nullable = false)
- public int getId() {
- return this.id;
- }
- public void setId(int id) {
- this.id = id;
- }
- @Column(name = "text", nullable = false)
- public String getText() {
- return this.text;
- }
- public void setText(String text) {
- this.text = text;
- }
- @Temporal(TemporalType.DATE)
- @Column(name = "date", nullable = false, length = 0)
- public Date getDate() {
- return this.date;
- }
- public void setDate(Date date) {
- this.date = date;
- }
- @Column(name = "tags")
- public String getTags() {
- return this.tags;
- }
- public void setTags(String tags) {
- this.tags = tags;
- }
- }
输出scala代码
scala 代码
- package base;
- import java.util.Date
- import javax.persistence.Column
- import javax.persistence.Entity
- import javax.persistence.Id
- import javax.persistence.Table
- import javax.persistence.Temporal
- import javax.persistence.TemporalType
- /**
- * VoteVote generated by hbm2java
- */
- @Entity
- @Table{val name = "mytable", val catalog = "mydb"}
- class MyTable extends java.io.Serializable {
- private var id: int = _
- private var text: String = _
- private var date: Date = _
- private var tags: String = _
- def this(id: int, text: String, date: Date) = {
- this();
- this.id = id;
- this.text = text;
- this.date = date;
- }
- def this(id: int, text: String, date: Date, tags: String) = {
- this();
- this.id = id;
- this.text = text;
- this.date = date;
- this.tags = tags;
- }
- @Id
- @Column{val name = "id", val unique = true, val nullable = false}
- def getId() = {
- this.id
- }
- def setId(id: int) = {
- this.id = id;
- }
- @Column{val name = "text", val nullable = false}
- def getText() = {
- this.text
- }
- def setText(text: String) = {
- this.text = text;
- }
- @Temporal(TemporalType.DATE)
- @Column{val name = "date", val nullable = false, val length = 0}
- def getDate() = {
- this.date
- }
- def setDate(date: Date) = {
- this.date = date;
- }
- @Column{val name = "tags"}
- def getTags() = {
- this.tags
- }
- def setTags(tags: String) = {
- this.tags = tags;
- }
- }
呵呵,完美完成任务
评论
fakechris
2007-08-02
嗯,输入太工整了
正则表达式也就能处理这么工整的代码了,格式比较乱的还是要上ast才行啊
正则表达式也就能处理这么工整的代码了,格式比较乱的还是要上ast才行啊
Lich_Ray
2007-08-02
这个。。是张搞笑帖吧?无论是看哪段代码都有种要晕的感觉——是在是太“工整”了。
发表评论
- 浏览: 10116 次
- 性别:

- 来自: 北京

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
在scala里调用Hibernate ...
是在JVM上的一种函数式语言,和java可以互相调用,http://www.sc ...
-- by fakechris -
scala学习笔记(1)
用了 Java 的实现描述语法我知道;不过利用了虚类,确实有点新意啊。
-- by Lich_Ray -
scala学习笔记(1)
实际上String=>Unit 是一个scala的trait,相当于java的接 ...
-- by fakechris -
scala学习笔记(1)
var fn = new ( String=>Unit ) { def ap ...
-- by Lich_Ray -
python的小工具,把hibern ...
嗯,输入太工整了正则表达式也就能处理这么工整的代码了,格式比较乱的还是要上ast ...
-- by fakechris






评论排行榜