From 112037450555e5bb51cb03148e65ee4321ec4b45 Mon Sep 17 00:00:00 2001 From: Kagura Date: Thu, 31 Oct 2024 23:14:58 +0800 Subject: [PATCH] feat: support define --- src/main/CTests/test.c | 6 +- src/main/kotlin/core/SourceFile.kt | 140 +++++++++++++++++++++-------- 2 files changed, 107 insertions(+), 39 deletions(-) diff --git a/src/main/CTests/test.c b/src/main/CTests/test.c index ccadb5a..0eed7db 100644 --- a/src/main/CTests/test.c +++ b/src/main/CTests/test.c @@ -1,7 +1,9 @@ #include - +#define PLUS(first,later) first+later +// 你看我还能用 define +// 当然也能写注释 int add(int a, int b) { - int c = a + b; + int c = PLUS(a,b); return c; } diff --git a/src/main/kotlin/core/SourceFile.kt b/src/main/kotlin/core/SourceFile.kt index b72fe49..7fb0b99 100644 --- a/src/main/kotlin/core/SourceFile.kt +++ b/src/main/kotlin/core/SourceFile.kt @@ -12,56 +12,122 @@ class SourceFile { val function_define_regex = """\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*\{""".toRegex() // main(){ 匹配函数名 fun formatSource(src: String): String { + // 去掉注释 val noComment = src.lines() .filter { line -> !line.trimStart().startsWith("#include") && !line.trimStart().startsWith("//") } .joinToString("\n") { line -> val withoutTrailingComment = line.replace(Regex("//.*$"), "") withoutTrailingComment.trimStart() } - val noContinueValue = StringBuilder() - noComment.lines().forEach { line -> - if (line.contains('=') && line.contains(',')){ // 或许是连续赋值 - if (!line.contains('{')){ // 不是函数调用 - if (line.trim().matches(declarationRegex)){ // 满足像是连续赋值的样子 - val splits = line.split(' ') - val identifier = splits.first() - val remain = splits.drop(1).joinToString(" ") - if (identifier in types){ // 获取标识符 - val parts = remain.split(',') // 逗号分开 - var allHasEqual = true - for (part in parts){ - if (!part.contains('=')){ - allHasEqual = false + + // 处理 DEFINE, 支持如下 + // #define SOMETHING ANOTHERTHING 这样的 + // #define ADD(a, b) a + b + val noFuncInDefine = StringBuilder() + // 获取 define 的内容 + val simpleDefineList = mutableMapOf() // #define a 0 -> "a" -> "0" + for (line in noComment.lines()) { + if (line.trim().startsWith("#define")) { + val args = line.trim().split(" ") + if (args.size >= 3) { + if (args[1].contains("(")){ // Define Function + val defFuncName = args[1].split('(').first().trim() + val defineFuncArgs = args[1] + .split('(').last() + .split(')').first() + .split(',').map { it.trim() } // 获取参数列表 + + val defineFunc = args.drop(2).joinToString() + // 现在处理,不然太麻烦了 + for (line in noComment.lines()) { + if (line.contains(" $defFuncName\\(".toRegex()) && !line.startsWith('#')) { // 多加一个括号确保是函数调用,前面保证不是哪个函数的名字(太刁钻了这个) + val prev = line.split("$defFuncName(") // 应该是调用之前的内容 + val later = prev.last().split(')') // 应该是调用之后的内容 + val callArgs = later.first().split(',').map { it.trim() } // 和上面一样的 + if (callArgs.size <= defineFuncArgs.size){ + var newFunction = defineFunc + for (i in callArgs.indices){ // 参数不够不管了 + newFunction = newFunction.replace(defineFuncArgs[i],callArgs[i]) + } + //改回去 + noFuncInDefine.append(prev.first() + newFunction + later.last()) + noFuncInDefine.append('\n') + }else{ // 参数多了我有啥办法 + noFuncInDefine.append(line) + noFuncInDefine.append('\n') } + }else if (!line.startsWith('#')) { + noFuncInDefine.append(line) + noFuncInDefine.append('\n') } - if (allHasEqual){ - parts.forEach { part -> - noContinueValue.append("$identifier $part;") - } - }else{ - noContinueValue.append(line) - } - }else{ - noContinueValue.append(line) } - }else{ + }else { // #define SOMETHING ANOTHER 这样的 + simpleDefineList[args[1]] = args[2] + } + } + } + } + // 可能上面代码因为没define没执行,这里保证下 + if (noFuncInDefine.isEmpty()){ + noFuncInDefine.append(noComment) + } + + val noDefine = StringBuilder() + if (simpleDefineList.isNotEmpty()) { + for (key in simpleDefineList.keys) { + val regex = " $key ".toRegex() + for (line in noFuncInDefine.lines()) { + if (line.matches(regex)) { + line.replace(" $key ", " ${simpleDefineList[key]} ") // 加上空格放置改了不改改变的 + } + noDefine.append(line) + noDefine.append('\n') + } + } + }else{ + noDefine.append(noFuncInDefine) + } + + // 将 int a = 1, b=2,c=3;这样的行变为 int a = 1; int b =2; int c = 3; 方便分析 + val noContinueValue = StringBuilder() + noDefine.lines().forEach { line -> + if (line.contains('=') && line.contains(',')// 或许是连续赋值 + && !line.contains('{') // 不是函数调用 + && line.trim().matches(declarationRegex) // 满足像是连续赋值的样子 + ) { + val splits = line.split(' ') + val identifier = splits.first() + val remain = splits.drop(1).joinToString(" ") + if (identifier in types) { // 获取标识符 + val parts = remain.split(',') // 逗号分开 + var allHasEqual = true + for (part in parts) { + if (!part.contains('=')) { + allHasEqual = false + } + } + if (allHasEqual) { // 确定是 + parts.forEach { part -> + noContinueValue.append("$identifier $part;") + } + } else { noContinueValue.append(line) } - }else{ + } else { noContinueValue.append(line) } - }else{ + } else { noContinueValue.append(line) } } - return noContinueValue - .toString() - .replace(";;",";") - .replace(";",";\n") - .replace("{","{\n") - .replace("}","}\n") - .replace(" =","=") - .replace("= ","=") + + return noContinueValue.toString() + .replace(";;", ";") + .replace(";", ";\n") + .replace("{", "{\n") + .replace("}", "}\n") + .replace(" =", "=") + .replace("= ", "=") } } @@ -98,8 +164,8 @@ class SourceFile { return result } - fun getUse(): Map> { - val globalResult = mutableMapOf>() + fun getUse(): Map> { + val globalResult = mutableMapOf>() functions.forEach { val funcResult = mutableListOf() @@ -156,7 +222,7 @@ fun main() { val funcs = sourceFile.parseFunction() val relations = mutableMapOf>() funcs.forEach { - relations.putAll(parseRelation(it.name,it.getTraceTree().getStringRepr())) + relations.putAll(parseRelation(it.name, it.getTraceTree().getStringRepr())) } for (function in funcs) { println(funcs.getInvokeTree(function.name).getFuncRepr(function.name))