我在大约6个月前尝试将一些复杂的C ++代码转换为Java,只是几天前才再次将其提取。我决定尝试手动转换代码太困难了,并认为尽管我不想为此软件付费,而且所有免费软件都没有提供我所需要的东西,但是c ++到java的转换器可以解决问题。因此,我决定编写自己的代码,这就是我创建的代码,但是我得到的结果如下所述。
public class Main {
HashMap<String,String> vars = new HashMap<>();
HashMap<String,String> funcVars = new HashMap<>();
public static void main(String[] args) {
new Main("Code.txt");
}
public Main(String loc) {
try {
long last = System.nanoTime();
BufferedReader r = new BufferedReader(new FileReader(new File(loc)));
String l;
String out = "";
boolean varZone = false;
boolean func = false;
while ((l = r.readLine()) != null) {
String cl = "";
String[] line = l.split(" ");
//Get Variables
if(varZone&&!l.equals("***")) {
if(line[0].equals("var")) {
for(String var:line) {
if(var.equals(line[0])||var.equals(line[1])) continue;
else {
vars.put(var, line[1]);
}
}
} else out+="INVALID VAR SYNTAX: "+l+"\r\n";
continue;
}
//First Pass
if(l.equals("***")) varZone = !varZone;
else if(Pattern.compile("//").matcher(l).find());
else if(Pattern.compile("}").matcher(l).find()) {
cl=l+"\r\n";
funcVars.clear();
func = false;
} else if(Pattern.compile("setFlag",Pattern.CASE_INSENSITIVE).matcher(l).find()) out += " setFlag(" +
line[0].replace(" SetFlag(", "") + " " + bitWiseBool(subString(line, 1).replace(");", "")) + ");\r\n";
else if(!func&&Pattern.compile("olc6502",Pattern.CASE_INSENSITIVE).matcher(l).find()) {
out += "public byte "+line[1].replace("olc6502::", "") + " {\r\n";
func = true;
} else if(Pattern.compile("return").matcher(l).find()) cl=l.replaceAll("return ", "return 0x0")
+"\r\n";
else if(Pattern.compile("if").matcher(l).find()) cl=l.replaceAll("uint8_t", "byte").replaceAll("uint16_t", "short")
.replaceAll("GetFlag", "getFlag")+"\r\n";
else if(Pattern.compile("else").matcher(l).find()) cl=l+"\r\n";
else if(Pattern.compile("uint8_t").matcher(l).find()) {
cl=l.replaceAll("uint8_t", "byte").replaceAll("uint16_t","short").replaceAll("GetFlag", "getFlag")+"\r\n";
funcVars.put(line[1], "8");
}
else if(Pattern.compile("uint16_t").matcher(l).find()) {
cl=l.replaceAll("uint8_t", "byte").replaceAll("uint16_t","short").replaceAll("GetFlag", "getFlag")+"\r\n";
funcVars.put(line[1], "16");
}
else {
for(String var:vars.keySet()) {
if(Pattern.compile(var).matcher(line[0]).find()&&vars.get(var)=="func") {
cl=l+"\r\n";
break;
}
else if(Pattern.compile(var).matcher(line[0]).find()&&!(vars.get(var)=="arr")) {
cl=l.replaceAll("uint8_t", "byte").replaceAll("uint16_t", "short").replaceAll("GetFlag", "getFlag")
+"\r\n";
break;
}
}
}
//Second Pass
HashMap<String,String> cVars = vars;
cVars.putAll(funcVars);
String[] vrs = sortInOrder(cl,cVars.keySet().parallelStream().toArray(String[]::new));
if(vrs.length>1) {
System.out.println("Before:"+cl);
if(cVars.get(vrs[0]).equals("16")&&cVars.get(vrs[1]).equals("8")) {
if(!vrs[1].equals("read")) cl=cl.replaceAll(vrs[1], "("+vrs[1]+"&0xFF)");
else cl=cl.replace(line[line.length-1], "read("+line[line.length-1].replace("read(", "")
.replace(");", "")+")&0xFF;");
} else if(cVars.get(vrs[0]).equals("arr")) cl=cl.replaceAll(vrs[1], vrs[1]+"&0xFF");
System.out.println("After:"+cl);
}
out+=cl;
}
r.close();
FileWriter w = new FileWriter(new File(loc+".txt"));
w.write(out);
w.close();
System.out.println("Run Time: "+(System.nanoTime()-last)/1000000000f);
} catch (Exception e) {
e.printStackTrace();
}
}
public String[] sortInOrder(String str, String[] words) {
int i = 0;
for(String var:vars.keySet()) if(Pattern.compile(var).matcher(str).find()) i++;
TreeMap<Integer,String> matchWords = new TreeMap<>();
for(String var:vars.keySet()) {
Matcher m = Pattern.compile(var).matcher(str);
if(m.find()) matchWords.put(m.start(), var);
}
String[] sorted = new String[i];
i = 0;
for(Map.Entry<Integer,String> entry:matchWords.entrySet()) sorted[i++]=entry.getValue();
return sorted;
}
public String bitWiseBool(String cpp) {
cpp = cpp.replaceAll("uint8_t", "byte");
cpp = cpp.replaceAll("uint16_t", "short");
if(cpp.contains("&")) {
if(cpp.contains(">>")) {
} else if(cpp.contains("<<")) {
} else if(!cpp.contains("==")&&!cpp.contains(">")) {
return "("+cpp+")!=0";
}
}
return cpp;
}
public String subString(String[] arr, int i) {
String s = "";
for (int l = i; l < arr.length; l++) s += arr[l];
return s;
}
public String subString(String[] arr, int i, int z) {
String s = "";
for (int l = i; l < z; l++) s += arr[l];
return s;
}
}
它专为我想转换的代码类型而设计,尽管我无法使其正常工作。我在麻烦的代码中设置了一些printlns,这是一些结果:
之前:stkp = x;
之后:(stkp&0xFF)= x;
之前:返回0x00;
之后:返回0(x&0xFF)00;
之前:stkp ++;
之后:(stkp&0xFF)++;
我认真地不知道会发生什么情况,从而导致该代码跳过if并导致很多问题。此处是输入和输出文件:https://www.dropbox.com/s/0x4v5wmvuxqm8bx/Code.zip?dl=0
谢谢,GLS
为什么会发生?
因为您的转换器不正确。您的代码显然将转换应用于某些标识符,而没有考虑使用标识符的语法上下文。显然,当标识符出现在分配的左侧或标识符为左值的任何其他上下文中时,不应应用从<identifier>
到(<identifier>)&0xFF
的转换。
但是更大的问题是,这是编写代码转换器的不好方法。除了有限的简单示例集之外,极不可能让此代码对任何其他代码都起作用。您无法使用文本模式匹配和替换操作来翻译源代码。
要正确执行代码翻译,您需要:
适当地做很多工作,特别是如果您还没有以CS学位学习编译器写作课程(或花了很长时间阅读/学习教科书等)
[我的建议:为该工具付款,或手动进行翻译。