├── README.md ├── main.go ├── py2go.exe ├── py2go_test.go ├── pytree.go ├── res ├── test.go └── test.py ├── togolang.go └── trans.go /README.md: -------------------------------------------------------------------------------- 1 | 转换python代码结构到golang的小工具。只是简单的结构代码转换,方便再手动调整。 2 | 3 | ### 完成的内容 4 | - 基本语法树的分析,重建。 5 | - 转换成golang,稍微改下可以支持转换到其他语言 6 | - class,func,if,else,for的基本转换 7 | - 一些关键字的批量替换 8 | 9 | ### 未完成的内容 10 | - 变量的初始化 11 | - 类型识别 12 | - 特殊语法的转换(例如:if a in []) 13 | 14 | ### 已知问题 15 | - 无法转换通过"\"分割的多行语句 16 | ### 使用方法 17 | - 转换单个python文件(示例:py2go.exe res/test.py) 18 | - 转换所有当前目录和res目录的python文件(直接执行exe) 19 | 20 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "path/filepath" 9 | "strings" 10 | ) 11 | 12 | func main() { 13 | fmt.Println(os.Args) 14 | if len(os.Args) > 1 { 15 | for i := 1; i < len(os.Args); i++ { 16 | path := os.Args[i] 17 | if err := TransPy(path); err != nil { 18 | fmt.Println("TransPy error:", err) 19 | return 20 | } 21 | } 22 | } else { 23 | if err := ScanDir("./res/"); err != nil { 24 | fmt.Println("ScanDir error:", err) 25 | return 26 | } 27 | if err := ScanDir("./"); err != nil { 28 | fmt.Println("ScanDir error:", err) 29 | return 30 | } 31 | } 32 | } 33 | 34 | func ScanDir(dir string) error { 35 | files, err := ListDir(dir, ".py") 36 | if err != nil { 37 | //fmt.Println("ListDir error:", err) 38 | return nil 39 | } 40 | for _, path := range files { 41 | if err := TransPy(path); err != nil { 42 | return err 43 | } 44 | } 45 | return nil 46 | } 47 | 48 | //获取指定目录下的所有文件,不进入下一级目录搜索,可以匹配后缀过滤。 49 | func ListDir(dirPth string, suffix string) (files []string, err error) { 50 | files = make([]string, 0, 10) 51 | dir, err := ioutil.ReadDir(dirPth) 52 | if err != nil { 53 | return nil, err 54 | } 55 | PthSep := string(os.PathSeparator) 56 | suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写 57 | for _, fi := range dir { 58 | if fi.IsDir() { // 忽略目录 59 | continue 60 | } 61 | if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) { //匹配文件 62 | files = append(files, dirPth+PthSep+fi.Name()) 63 | } 64 | } 65 | return files, nil 66 | } 67 | 68 | func TransPy(path string) error { 69 | fmt.Println("translate:", path) 70 | data, err := ioutil.ReadFile(path) 71 | if err != nil { 72 | fmt.Println("ReadFile fail:", path, err) 73 | return err 74 | } 75 | 76 | buf := bytes.NewBuffer(data) 77 | 78 | var part = new(CodePart) 79 | part.partType = CodePart_Root 80 | err = part.Parse(buf) 81 | if err != nil { 82 | fmt.Println("Parse fail:", err) 83 | return err 84 | } 85 | 86 | r := part.Translate() 87 | 88 | last := strings.LastIndex(path, ".py") 89 | newPath := path[0:last] + ".go" 90 | fmt.Println("write file:", newPath) 91 | err = ioutil.WriteFile(newPath, []byte(r), os.ModeType) 92 | if err != nil { 93 | fmt.Println("WriteFile error:", err) 94 | } 95 | return err 96 | } 97 | 98 | //获取指定目录及所有子目录下的所有文件,可以匹配后缀过滤。 99 | func WalkDir(dirPth, suffix string) (files []string, err error) { 100 | files = make([]string, 0, 30) 101 | suffix = strings.ToUpper(suffix) //忽略后缀匹配的大小写 102 | err = filepath.Walk(dirPth, func(filename string, fi os.FileInfo, err error) error { //遍历目录 103 | //if err != nil { //忽略错误 104 | // return err 105 | //} 106 | if fi.IsDir() { // 忽略目录 107 | return nil 108 | } 109 | if strings.HasSuffix(strings.ToUpper(fi.Name()), suffix) { 110 | files = append(files, filename) 111 | } 112 | return nil 113 | }) 114 | return files, err 115 | } 116 | -------------------------------------------------------------------------------- /py2go.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/magicsea/py2go/10a13cccf3f7f42c03771e3343bc8bafd8e4e672/py2go.exe -------------------------------------------------------------------------------- /py2go_test.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io/ioutil" 7 | "testing" 8 | ) 9 | 10 | func TestPy2go(t *testing.T) { 11 | 12 | fmt.Print(':', '\r', '\n', "--") 13 | path := "res/utility.py" 14 | //path := "res/test.py" 15 | data, err := ioutil.ReadFile(path) 16 | if err != nil { 17 | fmt.Println("ReadFile fail:", path, err) 18 | return 19 | } 20 | //log.Info("read len=%d", len(data)) 21 | //log.Info("%s", data) 22 | buf := bytes.NewBuffer(data) 23 | fmt.Println(buf.Len()) 24 | 25 | var part = new(CodePart) 26 | part.partType = CodePart_Root 27 | err = part.Parse(buf) 28 | if err != nil { 29 | fmt.Println("Parse fail:", err) 30 | return 31 | } 32 | 33 | fmt.Println("tree:") 34 | part.Print() 35 | r := part.Translate() 36 | fmt.Println("result:") 37 | fmt.Println(r) 38 | 39 | } 40 | 41 | func TestFile(t *testing.T) { 42 | path := "res/test.py" 43 | err := TransPy(path) 44 | fmt.Println(err) 45 | } 46 | 47 | func TestDir(t *testing.T) { 48 | if err := ScanDir("./res/"); err != nil { 49 | fmt.Println("ScanDir error:", err) 50 | return 51 | } 52 | if err := ScanDir("./"); err != nil { 53 | fmt.Println("ScanDir error:", err) 54 | return 55 | } 56 | } 57 | func TestSimple(t *testing.T) { 58 | var list = []int{0, 1, 2, 3, 4} 59 | var n = 3 60 | list = append(list[0:n], list[n+1:]...) 61 | fmt.Println(list) 62 | 63 | } 64 | -------------------------------------------------------------------------------- /pytree.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "io" 7 | "strings" 8 | ) 9 | 10 | //key word 11 | const ( 12 | CLASS = "class" 13 | FUNC = "def" 14 | FOR = "for" 15 | IF = "if" 16 | ELSEIF = "elif" 17 | ELSE = "else" 18 | ) 19 | 20 | type CodePartType int 21 | 22 | const ( 23 | CodePart_class CodePartType = iota 24 | CodePart_func 25 | CodePart_for 26 | CodePart_if 27 | CodePart_elseif 28 | CodePart_else 29 | 30 | CodePart_raw 31 | 32 | CodePart_NONE = -1 33 | CodePart_Root = -10 34 | ) 35 | 36 | var codePartHeadMap = map[CodePartType]string{ 37 | CodePart_class: CLASS, 38 | CodePart_func: FUNC, 39 | CodePart_for: FOR, 40 | CodePart_if: IF, 41 | CodePart_elseif: ELSEIF, 42 | CodePart_else: ELSE, 43 | } 44 | 45 | type TransFunc func(part *CodePart) string 46 | 47 | //反向map 48 | var codePartHeadMapRev = make(map[string]CodePartType) 49 | 50 | func ReplaceKeys(str string) string { 51 | l := len(str) 52 | for k, v := range keywordMap { 53 | str = strings.Replace(str, k, v, l) 54 | } 55 | return str 56 | } 57 | 58 | type CodePart struct { 59 | partType CodePartType 60 | children []*CodePart 61 | parent *CodePart 62 | //head string 63 | data string 64 | headPos int 65 | trans ITranslate 66 | } 67 | 68 | func init() { 69 | for key, val := range codePartHeadMap { 70 | codePartHeadMapRev[val] = key 71 | } 72 | } 73 | 74 | func getHeadPos(line string) int { 75 | trimline := strings.TrimSpace(line) 76 | pos := strings.Index(line, trimline) 77 | return pos 78 | } 79 | 80 | func getHeadType(line string) (CodePartType, int, string) { 81 | for key, val := range codePartHeadMap { 82 | trimline := strings.TrimSpace(line) 83 | vals := val 84 | 85 | if strings.HasPrefix(trimline, vals) { 86 | pos := strings.Index(line, trimline) 87 | return key, pos, vals 88 | } 89 | } 90 | return CodePart_NONE, 0, "" 91 | } 92 | 93 | func (p *CodePart) Parse(buf *bytes.Buffer) error { 94 | buf.WriteString("\n\n") 95 | return p.doParse(buf, CodePart_Root, -1, "", nil) 96 | /* 97 | head, err := buf.ReadString('\n') 98 | if err == io.EOF { 99 | return nil 100 | } 101 | 102 | if err != nil { 103 | fmt.Errorf("%v", err) 104 | } 105 | 106 | if tp, headpos, vals := getHeadType(head); tp == CodePart_NONE { 107 | return errors.New(fmt.Sprintf("getHeadType fail", head)) 108 | } else { 109 | return p.doParse(buf, tp, headpos, parseHead(head, vals), nil) 110 | } 111 | */ 112 | } 113 | 114 | func parseHead(head string, key string) string { 115 | //fmt.Println("parseHead pre:", head, []byte(head), len(head)) 116 | head = strings.TrimSpace(head) 117 | head = strings.TrimPrefix(head, key) 118 | end := strings.LastIndex(head, ":") 119 | head = head[0:end] 120 | //fmt.Println("parseHead:", head, "@@@@", key, "@@@", end) 121 | return head 122 | 123 | } 124 | 125 | func (p *CodePart) doParse(buf *bytes.Buffer, setpart CodePartType, headpos int, head string, parent *CodePart) error { 126 | p.partType = setpart 127 | p.headPos = headpos 128 | p.data = head 129 | p.trans = GetGolangTrans(setpart) //to golang 130 | p.parent = parent 131 | if p.partType == CodePart_raw { 132 | return nil 133 | } 134 | for { 135 | //fmt.Println("buf:", len(buf.Bytes())) 136 | line, err := buf.ReadString('\n') 137 | if err == io.EOF { 138 | //fmt.Println("to end:", line) 139 | break 140 | } 141 | //判断空行 142 | if len(strings.TrimSpace(line)) <= 1 { 143 | continue 144 | } 145 | newpos := getHeadPos(line) 146 | //判断是否子块内 147 | if newpos > p.headPos { 148 | //块内,自己解 149 | if tp, headpos, vals := getHeadType(line); tp != CodePart_NONE { 150 | //新块类型 151 | var newpart = CodePart{} 152 | newpart.doParse(buf, tp, headpos, parseHead(line, vals), p) 153 | p.children = append(p.children, &newpart) 154 | continue 155 | } else { 156 | //基础代码 157 | if len(line) > 1 { 158 | line = line[0 : len(line)-2] 159 | } 160 | var newpart = CodePart{} 161 | newpart.doParse(buf, CodePart_raw, newpos, strings.TrimSpace(line), p) 162 | p.children = append(p.children, &newpart) 163 | //var newpart = CodePart{partType: CodePart_raw, data: line,} 164 | //p.children = append(p.children, &newpart) 165 | //fmt.Println("parse line:", line) 166 | } 167 | } else { 168 | //fmt.Println("parse out:", line) 169 | //塞回去,让上层解 170 | var left []byte 171 | left = append(left, buf.Bytes()...) 172 | buf.Reset() 173 | buf.WriteString(line) 174 | buf.Write(left) 175 | return nil 176 | } 177 | 178 | } 179 | 180 | return nil 181 | } 182 | 183 | //缩进 184 | func (p *CodePart) writeScale(buf *bytes.Buffer) { 185 | var inClass bool = false 186 | var pr *CodePart = p 187 | //fmt.Println("writeScale ", pr) 188 | for { 189 | pr = pr.parent 190 | if pr == nil { 191 | break 192 | } 193 | if pr.partType == CodePart_class { 194 | inClass = true 195 | break 196 | } 197 | } 198 | //fmt.Println("writeScale end", inClass) 199 | var lastPos = p.headPos 200 | if inClass { 201 | lastPos -= 4 202 | } 203 | for index := 0; index < lastPos; index++ { 204 | buf.WriteString(" ") 205 | } 206 | } 207 | func (p *CodePart) doTranslate(buf *bytes.Buffer) { 208 | //fmt.Println("doTranslate:", p, " p:", p, " trans:", p.trans) 209 | 210 | p.trans.WriteHead(p, buf) 211 | p.trans.WriteBodyPre(p, buf) 212 | for _, v := range p.children { 213 | v.doTranslate(buf) 214 | } 215 | 216 | p.trans.WriteBodyEnd(p, buf) 217 | } 218 | 219 | func (p *CodePart) Translate() string { 220 | var buf = bytes.NewBufferString("") 221 | p.doTranslate(buf) 222 | str := string(buf.Bytes()) 223 | str = ReplaceKeys(str) 224 | return str 225 | } 226 | 227 | func (p *CodePart) Print() { 228 | printTree(p, 0) 229 | } 230 | 231 | func printTree(part *CodePart, blk int) { 232 | for i := 0; i < blk; i++ { 233 | fmt.Print(" ") //缩进 234 | } 235 | fmt.Printf("|—<%v:%s-%d>\n", part.partType, part.data, part.headPos) //打印"|—"形式 236 | for i := 0; i < len(part.children); i++ { 237 | printTree(part.children[i], blk+1) //打印子树,累加缩进次数 238 | } 239 | } 240 | -------------------------------------------------------------------------------- /res/test.go: -------------------------------------------------------------------------------- 1 | 2 | type BattleCard struct {} 3 | 4 | func (self *BattleCard) checkBuffLimit( buffId, bigRound) { 5 | buffInfo = d_buff_info.getInfo(buffId) 6 | if self.rub_BigRound != bigRound { 7 | self.rub_BigRound = bigRound 8 | self.roundUsedBuffDict = {} 9 | } 10 | if buffId !in self.roundUsedBuffDict { 11 | self.roundUsedBuffDict[buffId] = 1 12 | return true 13 | } else if buffInfo.RoundLimit > self.roundUsedBuffDict[buffId] { 14 | self.roundUsedBuffDict[buffId] += 1 15 | return true 16 | } 17 | if cardId !in self.ownCardDict { 18 | self.ownCardDict[cardId] = cardNum 19 | } else { 20 | self.ownCardDict[cardId] += cardNum 21 | } 22 | return false 23 | } 24 | func (self *BattleCard) checkBuffLimit2( buffId, bigRound) { 25 | buffInfo2 = d_buff_info.getInfo(buffId) 26 | if self.rub_BigRound != bigRound { 27 | self.rub_BigRound = bigRound 28 | self.roundUsedBuffDict = {} 29 | } 30 | a = 3 31 | if a==b&&(value==1||value== 2)&&c==d { 32 | a = 4 33 | } 34 | if ( X==-233|| X== -232|| X== -247) { 35 | fmt.Println('a') 36 | } 37 | cardInfo.equipList=append(cardInfo.equipList,1) 38 | _list=append(_list,(cardId, equipList)) 39 | if buffId !in self.roundUsedBuffDict { 40 | self.roundUsedBuffDict[buffId] = 1 41 | return true 42 | } else if buffInfo.RoundLimit > self.roundUsedBuffDict[buffId] { 43 | self.roundUsedBuffDict[buffId] += 1 44 | return true 45 | } 46 | return true 47 | } 48 | func (self *BattleCard) testFor() { 49 | for _, _guildId :=range lists { 50 | fmt.Println(_guildId) 51 | } 52 | for uid,_ :=range guild.guildMember { 53 | fmt.Println(uid) 54 | } 55 | for _, guild :=range self.guildDict { 56 | fmt.Println(guild) 57 | } 58 | for uid, member :=range guild.guildMember { 59 | fmt.Println(uid, member) 60 | } 61 | for i:=0; i<100; i++ { 62 | fmt.Println(i) 63 | } 64 | } -------------------------------------------------------------------------------- /res/test.py: -------------------------------------------------------------------------------- 1 | class BattleCard(object): 2 | def checkBuffLimit(self, buffId, bigRound): 3 | buffInfo = d_buff_info.getInfo(buffId) 4 | if self.rub_BigRound != bigRound: 5 | self.rub_BigRound = bigRound 6 | self.roundUsedBuffDict = {} 7 | if buffId not in self.roundUsedBuffDict: 8 | self.roundUsedBuffDict[buffId] = 1 9 | return True 10 | elif buffInfo.RoundLimit > self.roundUsedBuffDict[buffId]: 11 | self.roundUsedBuffDict[buffId] += 1 12 | return True 13 | if cardId not in self.ownCardDict: 14 | self.ownCardDict[cardId] = cardNum 15 | else: 16 | self.ownCardDict[cardId] += cardNum 17 | return False 18 | 19 | def checkBuffLimit2(self, buffId, bigRound): 20 | buffInfo2 = d_buff_info.getInfo(buffId) 21 | if self.rub_BigRound != bigRound: 22 | self.rub_BigRound = bigRound 23 | self.roundUsedBuffDict = {} 24 | a = 3 25 | if a==b and value in [1, 2] and c==d: 26 | a = 4 27 | if X in [-233, -232, -247]: 28 | print 'a' 29 | cardInfo.equipList.append(1) 30 | _list.append((cardId, equipList)) 31 | if buffId not in self.roundUsedBuffDict: 32 | self.roundUsedBuffDict[buffId] = 1 33 | return True 34 | elif buffInfo.RoundLimit > self.roundUsedBuffDict[buffId]: 35 | self.roundUsedBuffDict[buffId] += 1 36 | return True 37 | return True 38 | def testFor(self): 39 | for _guildId in lists: 40 | print _guildId 41 | for uid in guild.guildMember.iterkeys(): 42 | print uid 43 | for guild in self.guildDict.itervalues(): 44 | print guild 45 | for uid, member in guild.guildMember.iteritems(): 46 | print uid, member 47 | for i in xrange(100): 48 | print i 49 | 50 | -------------------------------------------------------------------------------- /togolang.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "strings" 7 | ) 8 | 9 | //替换关键字 10 | var keywordMap = map[string]string{ 11 | " True": " true", 12 | " False": " false", 13 | " not ": " !", 14 | " and ": "&&", 15 | " or ": "||", 16 | "is not None": "!=nil", 17 | " is not ": "!=", 18 | " is ": "==", 19 | " None ": "nil", 20 | "#": "//", 21 | } 22 | 23 | type GoRoot struct { 24 | } 25 | 26 | func (this *GoRoot) WriteHead(part *CodePart, buf *bytes.Buffer) { 27 | } 28 | func (this *GoRoot) WriteBodyPre(part *CodePart, buf *bytes.Buffer) { 29 | 30 | } 31 | func (this *GoRoot) WriteBodyEnd(part *CodePart, buf *bytes.Buffer) { 32 | 33 | } 34 | 35 | type GoClass struct { 36 | } 37 | 38 | func (this *GoClass) WriteHead(part *CodePart, buf *bytes.Buffer) { 39 | last := strings.LastIndex(part.data, "(") 40 | str := part.data[0:last] 41 | //fmt.Println("str:%d %d %s", last, len(part.data), str) 42 | temp := "\ntype ##head## struct {}\n" 43 | temp = strings.Replace(temp, "##head##", str, 255) 44 | buf.WriteString(temp) 45 | } 46 | func (this *GoClass) WriteBodyPre(part *CodePart, buf *bytes.Buffer) { 47 | 48 | } 49 | func (this *GoClass) WriteBodyEnd(part *CodePart, buf *bytes.Buffer) { 50 | 51 | } 52 | 53 | type GoFunc struct { 54 | } 55 | 56 | func (this *GoFunc) WriteHead(part *CodePart, buf *bytes.Buffer) { 57 | buf.WriteString("\n") 58 | part.writeScale(buf) 59 | temp := `func ##class## ##head## ` 60 | classfPrefix := "" 61 | if part.parent != nil && part.parent.partType == CodePart_class { 62 | last := strings.LastIndex(part.parent.data, "(") 63 | str := part.parent.data[0:last] 64 | str = strings.TrimSpace(str) 65 | classfPrefix = fmt.Sprintf("(self *%s)", str) 66 | } 67 | temp = strings.Replace(temp, "##class##", classfPrefix, 255) 68 | temp = strings.Replace(temp, "##head##", part.data, 255) 69 | temp = strings.Replace(temp, "(self,", "(", 255) 70 | temp = strings.Replace(temp, "(self)", "()", 255) 71 | buf.WriteString(temp) 72 | } 73 | func (this *GoFunc) WriteBodyPre(part *CodePart, buf *bytes.Buffer) { 74 | buf.WriteString("{") 75 | } 76 | func (this *GoFunc) WriteBodyEnd(part *CodePart, buf *bytes.Buffer) { 77 | buf.WriteString("\n") 78 | part.writeScale(buf) 79 | buf.WriteString("}") 80 | } 81 | 82 | type GoIf struct { 83 | } 84 | 85 | func (this *GoIf) WriteHead(part *CodePart, buf *bytes.Buffer) { 86 | buf.WriteString("\n") 87 | part.writeScale(buf) 88 | 89 | data := part.data 90 | if strings.Contains(data, " in [") { 91 | fmt.Println("if in=>", data) 92 | //X in [-233, -232, -247] 93 | //a==b and value in [1, 2] and c==d 94 | s := strings.Split(data, " in [") 95 | if len(s) == 2 { 96 | fmt.Println("if in1=>", s[0], "=>", s[1]) 97 | left, right := s[0], s[1] //a==b and value => 1, 2] and c==d 98 | llpos := strings.LastIndex(left, " ") 99 | var head string 100 | if llpos > 0 { 101 | head = left[0 : llpos+1] 102 | left = left[llpos+1:] 103 | } 104 | 105 | //fmt.Println("trans append2:", left, "=>", right) 106 | index := strings.LastIndex(right, "]") 107 | if index >= 0 { 108 | fmt.Println("if in2=>", right, index) 109 | 110 | var end = "" 111 | if index < len(right)-1 { 112 | end = right[index+1:] //and c==d 113 | fmt.Println("if end=>", end) 114 | } 115 | 116 | right = right[0:index] //1,2 117 | rights := strings.Split(right, ",") 118 | if len(rights) > 0 { 119 | fmt.Println("if in3=>", data) 120 | data = fmt.Sprintf("(%s==%s", left, rights[0]) 121 | for i := 1; i < len(rights); i++ { 122 | data += fmt.Sprintf("||%s==%s", left, rights[i]) 123 | } 124 | data += ")" 125 | } 126 | data = head + data + end 127 | } 128 | } 129 | } 130 | 131 | temp := `if ##head## ` 132 | temp = strings.Replace(temp, "##head##", data, 255) 133 | buf.WriteString(temp) 134 | } 135 | func (this *GoIf) WriteBodyPre(part *CodePart, buf *bytes.Buffer) { 136 | buf.WriteString("{") 137 | } 138 | func (this *GoIf) WriteBodyEnd(part *CodePart, buf *bytes.Buffer) { 139 | buf.WriteString("\n") 140 | part.writeScale(buf) 141 | buf.WriteString("}") 142 | } 143 | 144 | type GoIfelse struct { 145 | } 146 | 147 | func (this *GoIfelse) WriteHead(part *CodePart, buf *bytes.Buffer) { 148 | //删掉一个\n 149 | //var left []byte 150 | //left = append(left, buf.Bytes()...) 151 | //buf.Reset() 152 | //buf.Write(left[0 : len(left)-1]) 153 | 154 | temp := ` else if ##head## ` 155 | temp = strings.Replace(temp, "##head##", part.data, 255) 156 | buf.WriteString(temp) 157 | } 158 | func (this *GoIfelse) WriteBodyPre(part *CodePart, buf *bytes.Buffer) { 159 | buf.WriteString("{") 160 | } 161 | func (this *GoIfelse) WriteBodyEnd(part *CodePart, buf *bytes.Buffer) { 162 | buf.WriteString("\n") 163 | part.writeScale(buf) 164 | buf.WriteString("}") 165 | } 166 | 167 | type GoElse struct { 168 | } 169 | 170 | func (this *GoElse) WriteHead(part *CodePart, buf *bytes.Buffer) { 171 | //删掉一个\n 172 | //var left []byte 173 | //left = append(left, buf.Bytes()...) 174 | //buf.Reset() 175 | //buf.Write(left[0 : len(left)-1]) 176 | 177 | temp := ` else ` 178 | buf.WriteString(temp) 179 | } 180 | func (this *GoElse) WriteBodyPre(part *CodePart, buf *bytes.Buffer) { 181 | buf.WriteString("{") 182 | } 183 | func (this *GoElse) WriteBodyEnd(part *CodePart, buf *bytes.Buffer) { 184 | buf.WriteString("\n") 185 | part.writeScale(buf) 186 | buf.WriteString("}") 187 | } 188 | 189 | type GoFor struct { 190 | } 191 | 192 | //for _guildId in list: slice 193 | //for uid in guild.guildMember.iterkeys(): map.keys 194 | //for guild in self.guildDict.itervalues(): map.values 195 | //for uid, member in guild.guildMember.iteritems(): map k v 196 | //for i in xrange(cardNum): for i 197 | 198 | func (this *GoFor) WriteHead(part *CodePart, buf *bytes.Buffer) { 199 | buf.WriteString("\n") 200 | part.writeScale(buf) 201 | data := part.data 202 | 203 | if strings.HasSuffix(data, ".iteritems()") { 204 | //for uid, member in guild.guildMember.iteritems(): map k v 205 | data = strings.TrimSuffix(data, ".iteritems()") //remove tail 206 | data = strings.Replace(data, " in ", " :=range ", 1024) 207 | } else if strings.HasSuffix(data, ".itervalues()") { 208 | //for guild in self.guildDict.itervalues(): map.values 209 | s := strings.Split(data, " in ") 210 | head, tail := s[0], s[1] 211 | data = fmt.Sprintf("_,%s :=range %s", head, tail) 212 | data = strings.TrimSuffix(data, ".itervalues()") //remove tail 213 | } else if strings.HasSuffix(data, ".iterkeys()") { 214 | //for uid in guild.guildMember.iterkeys(): map.keys 215 | s := strings.Split(data, " in ") 216 | head, tail := s[0], s[1] 217 | data = fmt.Sprintf("%s,_ :=range %s", head, tail) 218 | data = strings.TrimSuffix(data, ".iterkeys()") //remove tail 219 | } else if strings.Contains(data, " xrange(") { 220 | //for i in xrange(cardNum): for i 221 | s := strings.Split(data, " in xrange(") 222 | head, tail := s[0], s[1] 223 | tail = strings.TrimSuffix(tail, ")") //remove tail 224 | data = fmt.Sprintf("%s:=0;%s<%s;%s++", head, head, tail, head) 225 | } else { 226 | //for _guildId in list: slice 227 | data = "_," + data 228 | data = strings.Replace(data, " in ", " :=range ", 1024) 229 | } 230 | 231 | temp := `for ##head## ` 232 | temp = strings.Replace(temp, "##head##", data, 1024) 233 | buf.WriteString(temp) 234 | 235 | } 236 | func (this *GoFor) WriteBodyPre(part *CodePart, buf *bytes.Buffer) { 237 | buf.WriteString("{") 238 | } 239 | func (this *GoFor) WriteBodyEnd(part *CodePart, buf *bytes.Buffer) { 240 | buf.WriteString("\n") 241 | part.writeScale(buf) 242 | buf.WriteString("}") 243 | } 244 | 245 | type GoRaw struct { 246 | } 247 | 248 | func (this *GoRaw) WriteHead(part *CodePart, buf *bytes.Buffer) { 249 | buf.WriteString("\n") 250 | part.writeScale(buf) 251 | 252 | data := part.data 253 | trim := strings.TrimSpace(data) 254 | if len(trim) > 0 && trim[0] != '#' { //不是注释 255 | 256 | if strings.Contains(data, ".append(") { 257 | //cardInfo.equipList.append(1)转换 258 | //fmt.Println("trans append:", data) 259 | s := strings.Split(data, ".append(") 260 | if len(s) >= 2 { 261 | left, right := s[0], s[1] //cardInfo.equipList,1) 262 | //fmt.Println("trans append2:", left, "=>", right) 263 | index := strings.LastIndex(right, ")") 264 | if index >= 0 { 265 | right = right[0:index] //1 266 | data = fmt.Sprintf("%s=append(%s,%s)", left, left, right) 267 | } 268 | } 269 | 270 | } else if strings.HasPrefix(trim, "del ") { 271 | //del self.buffList[i-1] 272 | trim = strings.TrimPrefix(trim, "del ") 273 | li := strings.Index(trim, "[") 274 | if li > 0 { 275 | left := trim[0:li] 276 | ri := strings.LastIndex(trim, "]") 277 | if ri > 0 { 278 | right := trim[li:ri] 279 | data = fmt.Sprintf("%s = append(%s[0:%s], %s[%s+1:]...)", left, left, right, left, right) 280 | } 281 | } 282 | } else if strings.HasPrefix(trim, "print ") { 283 | //print "layout" 284 | trim = strings.TrimPrefix(trim, "print ") 285 | data = fmt.Sprintf("fmt.Println(%s)", trim) 286 | 287 | } 288 | } 289 | 290 | buf.WriteString(data) 291 | } 292 | func (this *GoRaw) WriteBodyPre(part *CodePart, buf *bytes.Buffer) { 293 | 294 | } 295 | func (this *GoRaw) WriteBodyEnd(part *CodePart, buf *bytes.Buffer) { 296 | //buf.WriteString("\n") 297 | } 298 | -------------------------------------------------------------------------------- /trans.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import "bytes" 4 | 5 | type ITranslate interface { 6 | WriteHead(*CodePart, *bytes.Buffer) 7 | WriteBodyPre(*CodePart, *bytes.Buffer) 8 | WriteBodyEnd(*CodePart, *bytes.Buffer) 9 | } 10 | 11 | func GetGolangTrans(ctype CodePartType) ITranslate { 12 | switch ctype { 13 | case CodePart_class: 14 | return new(GoClass) 15 | case CodePart_func: 16 | return new(GoFunc) 17 | case CodePart_for: 18 | return new(GoFor) 19 | case CodePart_if: 20 | return new(GoIf) 21 | case CodePart_elseif: 22 | return new(GoIfelse) 23 | case CodePart_else: 24 | return new(GoElse) 25 | case CodePart_raw: 26 | return new(GoRaw) 27 | case CodePart_Root: 28 | return new(GoRoot) 29 | default: 30 | return new(GoRaw) 31 | } 32 | } 33 | --------------------------------------------------------------------------------