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 { // 找所有的函数定义