为什么我的自定义转换代码将C ++转换为Java时会给出此结果?

问题描述 投票:-1回答:1

我在大约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

java c++ converters
1个回答
0
投票

为什么会发生?

因为您的转换器不正确。您的代码显然将转换应用于某些标识符,而没有考虑使用标识符的语法上下文。显然,当标识符出现在分配的左侧或标识符为左值的任何其他上下文中时,不应应用从<identifier>(<identifier>)&0xFF的转换。

但是更大的问题是,这是编写代码转换器的不好方法。除了有限的简单示例集之外,极不可能让此代码对任何其他代码都起作用。您无法使用文本模式匹配和替换操作来翻译源代码。

要正确执行代码翻译,您需要:

  1. 将源代码解析为C ++代码的抽象语法树
  2. 解析符号并执行类型分析,并装饰C ++树
  3. 通过一系列图形转换/重写从C ++树中创建等效的Java树。
  4. 从最终的Java树生成Java源代码。

适当地做很多工作,特别是如果您还没有以CS学位学习编译器写作课程(或花了很长时间阅读/学习教科书等)

[我的建议:为该工具付款,或手动进行翻译。

© www.soinside.com 2019 - 2024. All rights reserved.