From 20956c52fd30dac122a9bd464ddb87ee821a2192 Mon Sep 17 00:00:00 2001 From: Kagura Date: Wed, 30 Oct 2024 09:37:32 +0800 Subject: [PATCH] fix --- .idea/misc.xml | 2 +- src/main/CTests/test.c | 23 ++++-------- src/main/kotlin/core/CFunction.kt | 27 ++++++++------ src/main/kotlin/core/CLanguage.kt | 7 +++- src/main/kotlin/core/CParser.kt | 31 ++++++++++------ src/main/kotlin/core/GraphvizHelper.kt | 27 ++++---------- src/main/kotlin/core/SourceFile.kt | 50 +++++++++++++++++++++++--- 7 files changed, 104 insertions(+), 63 deletions(-) diff --git a/.idea/misc.xml b/.idea/misc.xml index ac2c845..36970fa 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/src/main/CTests/test.c b/src/main/CTests/test.c index f26d027..12dacf0 100644 --- a/src/main/CTests/test.c +++ b/src/main/CTests/test.c @@ -1,19 +1,10 @@ int main(){ - int x=0,y =0; - int z =1; - printf("%d\n",z);//用户输入 - x= A(z); - y= x; - printf("%d\n",y);//main函数尾部 + int a = 0,b=1; + int k = add(a,b); + print(k) } -int A(int a){ - int m = a; - return m; -} - -//char Test(int para1,char para2){ -// int c1 = para1, i_doNothingbuttest = 2; -// c1 = para2; -// return c2; -//} \ No newline at end of file +int add(int a, int b){ + int c = a+b; + return c; +} \ No newline at end of file diff --git a/src/main/kotlin/core/CFunction.kt b/src/main/kotlin/core/CFunction.kt index d9ea148..d76e306 100644 --- a/src/main/kotlin/core/CFunction.kt +++ b/src/main/kotlin/core/CFunction.kt @@ -84,22 +84,27 @@ class CFunction( // y,x,CHANGE_VALUE // -,x,CHANGE_VALUE_PARAM if (index > 0) { // 按理来说肯定成立,加个检查防止意外 - val left = cParser.sentenceList[index - 1].left + var i = 0 + var left = cParser.sentenceList[index - 1].left + while (left == "-" && index - i >= 0) { + left = cParser.sentenceList[index - i].left + i++ + } val lNode = nodes.findNode(left) val rNode = nodes.findNode(sentence.right) if (lNode != null && rNode != null) { rNode.changes.add(lNode) } } - } else if (sentence.type == PARAM && invokeInfo != null){ - if (invokeInfo.param.lastIndex >= paramIndex){ // 在 InvokeTree 里面 + } else if (sentence.type == PARAM && invokeInfo != null) { + if (invokeInfo.param.lastIndex >= paramIndex) { // 在 InvokeTree 里面 val rNode = nodes.findNode(sentence.right) - val lNode = TraceTree("${invokeInfo.caller}:${invokeInfo.param[paramIndex]}",mutableListOf()) - if (rNode!= null) { + val lNode = TraceTree("${invokeInfo.caller}:${invokeInfo.param[paramIndex]}", mutableListOf()) + if (rNode != null) { lNode.changes.add(rNode) } nodes.add(lNode) - paramIndex ++ + paramIndex++ } } } @@ -127,14 +132,14 @@ fun List.find(name: String): CFunction? { * @param name: 从哪个函数开始查找 * @return 特制的 TraceTree */ -fun List.getInvokeTree(name: String): Map> { +fun List.getInvokeTree(name: String): Map> { // 先找到开始的函数 val func = this.find(name) ?: return emptyMap() val invokeTrees = mutableListOf() val args = mutableListOf() var funcName = "" - val resultMap = mutableMapOf>() + val resultMap = mutableMapOf>() func.cParser.sentenceList.forEach { sentence -> // 🌰: @@ -144,10 +149,10 @@ fun List.getInvokeTree(name: String): Map> { args.add(sentence.right) funcName = sentence.left } - }else{ // 更新 + } else { // 更新 val function = this.find(funcName) - if (function!=null) { - val info = InvokeInfo(name,args) + if (function != null) { + val info = InvokeInfo(name, args) val tt = function.getTraceTree(info) invokeTrees.addAll(tt) } diff --git a/src/main/kotlin/core/CLanguage.kt b/src/main/kotlin/core/CLanguage.kt index 5add865..ee0b947 100644 --- a/src/main/kotlin/core/CLanguage.kt +++ b/src/main/kotlin/core/CLanguage.kt @@ -2,7 +2,8 @@ package core class CLanguage { companion object { - val types = listOf("void","char","int","short","long","float","double","struct") + val types = listOf("void", "char", "int", "short", "long", "float", "double", "struct") + enum class OPERATION { DEFINE_VALUE, // `type` identifier = RHand 题目里 def-use FUNCTION_INVOCATION, // func(value-param) 题目里 @@ -12,6 +13,7 @@ class CLanguage { PARAM, // 函数的参数初始化 RETURN // 字面意思 } + enum class CTYPES { void, char, @@ -23,6 +25,9 @@ class CLanguage { struct } + val typeRegex = types.joinToString("|") { "\\b$it\\b" } + val declarationRegex = Regex("($typeRegex)\\s+([^;]+);") + fun typenameToTypeEnum(typename: String): CTYPES? { return when (typename) { "void" -> CTYPES.void diff --git a/src/main/kotlin/core/CParser.kt b/src/main/kotlin/core/CParser.kt index e7e59fa..e5fcec0 100644 --- a/src/main/kotlin/core/CParser.kt +++ b/src/main/kotlin/core/CParser.kt @@ -9,6 +9,8 @@ class CParser(content: String, paramNameList: List) { companion object { val lrexp_regex = "(.*)[ ]?=[ ]?(.*)[ ]?;?$".toRegex() // 左1右2 val func_invoke_regex = "(.*)[ ]?\\((.*)\\)[ ]?$".toRegex() // 匹配到的是1:函数名2:参数列表 + val c_op_list = listOf("+", "-", "*", "/", "%", "<<", ">>") + } val sentenceList = mutableListOf() @@ -29,16 +31,15 @@ class CParser(content: String, paramNameList: List) { if (line.contains('=')) { // 出现了left hand 和 right hand if (line.split(' ').first() in CLanguage.types) { // 最开始是一个 type // 说明这是一个 define 语句 - line.split(',').forEach { - val match = lrexp_regex.find(" " + it.trim()) // 如果是后面的就要这个 - if (match != null) { - val leftHand = match.groupValues[1].trim().split(' ').last() // Left-hand side (variable) - val rightHand = match.groupValues[2].trim() // Right-hand side (value) - sentenceList.add(Sentence(leftHand, rightHand, DEFINE_VALUE)) - defineList.add(leftHand) - sentenceList.addAll(rightHandSimpleParser(rightHand, DEFINE_VALUE)) - } + val match = lrexp_regex.find(" " + line) // 如果是后面的就要这个 + if (match != null) { + val leftHand = match.groupValues[1].trim().split(' ').last() // Left-hand side (variable) + val rightHand = match.groupValues[2].trim() // Right-hand side (value) + sentenceList.add(Sentence(leftHand, rightHand, DEFINE_VALUE)) + defineList.add(leftHand) + sentenceList.addAll(rightHandSimpleParser(rightHand, DEFINE_VALUE)) } + } else { // 重新定义 val match = lrexp_regex.find(line.trim()) if (match != null) { @@ -96,13 +97,23 @@ class CParser(content: String, paramNameList: List) { } } } - } else { + } + else { if (right in defineList) { // 看看有没有使用值 result.add( Sentence( "-", right, getType() ) ) + } else{ // 看是不是有运算符号 + for (op in c_op_list){ + if (op in right){ + val splits = right.split(op) + splits.forEach { split -> + result.addAll(rightHandSimpleParser(split.trim(),type)) + } + } + } } } return result diff --git a/src/main/kotlin/core/GraphvizHelper.kt b/src/main/kotlin/core/GraphvizHelper.kt index 2194842..cc2fa47 100644 --- a/src/main/kotlin/core/GraphvizHelper.kt +++ b/src/main/kotlin/core/GraphvizHelper.kt @@ -1,5 +1,7 @@ package core +import kotlin.math.abs + data class Relation(val from: String, val to: String) fun generateGraph(relations: Map>, crossLabelPaths: List? = null): String { @@ -14,7 +16,8 @@ fun generateGraph(relations: Map>, crossLabelPaths: List< for (relation in edges) { uniquePaths.add("${relation.from} -> ${relation.to}") - sb.append(" ${relation.from} -> ${relation.to};\n") + sb.append("${relation.from}$label[label=${relation.from}];\n${relation.to}$label[label=${relation.to}];\n") + sb.append("${relation.from}$label -> ${relation.to}$label;\n") } sb.append(" }\n") @@ -30,7 +33,7 @@ fun generateGraph(relations: Map>, crossLabelPaths: List< val fromNode = subPath[0] // 这里就是z val toNode = subPath[1] // 下一个就是 // from 到 to 用虚线 - sb.append(" $fromNode -> $toNode [style=dashed];\n") + sb.append(" $fromNode${parts[1]} -> $toNode${parts[0]} [style=dashed];\n") } } } @@ -71,21 +74,5 @@ fun List.getInvokeGraph(funcName: String): String { } val crossLabelPaths = this.getInvokeTree(func.name).getFuncRepr(func.name) - return generateGraph(relations,crossLabelPaths.split('\n')) -} - -fun main() { - val relations = mapOf( - "main" to listOf( - Relation("x", "y"), - Relation("z", "x"), - Relation("c", "d") - ), - "A" to listOf( - Relation("a", "m") - ) - ) - - val graphCode = generateGraph(relations) - println(graphCode) -} + return generateGraph(relations,crossLabelPaths.split('\n')) + "\n" +} \ No newline at end of file diff --git a/src/main/kotlin/core/SourceFile.kt b/src/main/kotlin/core/SourceFile.kt index 2d74c4c..13a3e05 100644 --- a/src/main/kotlin/core/SourceFile.kt +++ b/src/main/kotlin/core/SourceFile.kt @@ -4,6 +4,8 @@ package core import java.io.File import core.CLanguage.Companion.OPERATION.* +import core.CLanguage.Companion.declarationRegex +import core.CLanguage.Companion.types import utils.getDefineList import utils.getUseList @@ -11,13 +13,53 @@ class SourceFile { companion object { val function_define_regex = """\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*\{""".toRegex() // main(){ 匹配函数名 - fun deleteNotes(src: String): String { - return src.lines() + 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 + } + } + if (allHasEqual){ + parts.forEach { part -> + noContinueValue.append("$identifier $part;") + } + }else{ + noContinueValue.append(line) + } + }else{ + noContinueValue.append(line) + } + }else{ + noContinueValue.append(line) + } + }else{ + noContinueValue.append(line) + } + }else{ + noContinueValue.append(line) + } + } + return noContinueValue + .toString() + .replace(";;",";") + .replace(";",";\n") } } @@ -28,11 +70,11 @@ class SourceFile { if (!file.isFile) { throw NoSuchFileException(file) } - content = deleteNotes(file.readText()) + content = formatSource(file.readText()) } constructor(content: String) { - this.content = deleteNotes(content.trim()) + this.content = formatSource(content.trim()) } fun parseFunction(): List { // 找所有的函数定义