diff --git a/.idea/misc.xml b/.idea/misc.xml
index f2a2ad2..b2652fc 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -7,7 +7,7 @@
-
+
\ No newline at end of file
diff --git a/src/main/kotlin/core/CFunction.kt b/src/main/kotlin/core/CFunction.kt
index d57d9b7..68cb69c 100644
--- a/src/main/kotlin/core/CFunction.kt
+++ b/src/main/kotlin/core/CFunction.kt
@@ -2,6 +2,7 @@ package core
import core.CLanguage.Companion.OPERATION.*
import core.CLanguage.Companion.typenameToTypeEnum
+import utils.Helper.Companion.antiC
class CFunction(
val name: String, source: String // 函数名
@@ -34,13 +35,27 @@ class CFunction(
paramNameList = if (paramsList.isNullOrEmpty() || paramsList.first().isEmpty()) {
emptyList()
} else {
- paramsList.map { it.split(' ').last() }
+ paramsList.map {
+ val param = it.split(' ').last()
+ val name = if (param.contains('`')) { // struct`*po -> *po)
+ param.split('`').last()
+ }else{
+ param
+ }
+ antiC(name)
+ }
}
return paramsList?.map { param ->
- val parts = param.split(" ")
- val type = typenameToTypeEnum(parts[0]) ?: return@map emptyMap()
- val name = parts.getOrNull(1) ?: ""
- mapOf(name to type)
+ if (param.contains('`')){ // struct`*po -> *po
+ val name = antiC(param.split(' ').last())
+ val type = CLanguage.Companion.TYPES.void
+ mapOf(name to type)
+ }else {
+ val parts = param.split(" ")
+ val type = typenameToTypeEnum(parts[0]) ?: return@map emptyMap()
+ val name = antiC(parts.getOrNull(1) ?: "")
+ mapOf(name to type)
+ }
}
}
diff --git a/src/main/kotlin/core/CLanguage.kt b/src/main/kotlin/core/CLanguage.kt
index 874b4c4..bf29e33 100644
--- a/src/main/kotlin/core/CLanguage.kt
+++ b/src/main/kotlin/core/CLanguage.kt
@@ -2,7 +2,7 @@ package core
class CLanguage {
companion object {
- val types = listOf("void", "char", "int", "short", "long", "float", "double", "struct")
+ var types = mutableListOf("void", "char", "int", "short", "long", "float", "double")
enum class OPERATION {
DEFINE_VALUE, // `type` identifier = RHand 题目里 def-use
@@ -11,7 +11,8 @@ class CLanguage {
DEFINE_VALUE_PARAM, // int a=b, 一直接在上一个后面
CHANGE_VALUE_PARAM, // a = b
PARAM, // 函数的参数初始化
- RETURN // 字面意思
+ RETURN, // 字面意思
+ IF_PARAM,
}
@Suppress("EnumEntryName")
diff --git a/src/main/kotlin/core/CParser.kt b/src/main/kotlin/core/CParser.kt
index 7a6a337..703370b 100644
--- a/src/main/kotlin/core/CParser.kt
+++ b/src/main/kotlin/core/CParser.kt
@@ -1,6 +1,7 @@
package core
import core.CLanguage.Companion.OPERATION.*
+import utils.Helper.Companion.antiC
class Sentence(val left: String, val right: String, val type: CLanguage.Companion.OPERATION)
@@ -50,13 +51,19 @@ class CParser(content: String, paramNameList: List) {
} else if (line.contains("return")) { // return
val returnValue = line.split(' ').last()
sentenceList.add(Sentence("return", returnValue, RETURN))
+ } else if (line.startsWith("if")){
+ val args = line.split('(').last().split(')').first()
+ args.split(',').forEach { arg ->
+ sentenceList.add(Sentence("if",arg.trim(),IF_PARAM))
+ }
} else { // 调用函数,解析参数就行了
val match = func_invoke_regex.find(line) // 如果是后面的就要这个
if (match != null) {
val funcName = match.groupValues[1].trim().split(' ').last() // Left-hand side (variable)
val args = match.groupValues[2].trim() // Right-hand side (value)
- args.split(',').forEach { arg ->
- if (arg in defineList) { // 定义过的变量
+ args.split(',').forEach { ar ->
+ var arg = antiC(ar).trim()
+ if (arg.split('.').first() in defineList) { // 定义过的变量
sentenceList.add(Sentence(funcName, arg, FUNCTION_INVOCATION))
}
}
@@ -90,16 +97,16 @@ class CParser(content: String, paramNameList: List) {
val funName = match.groupValues[1].trim()
val params = match.groupValues[2].trim().split(',')
for (param in params) {
- if (param.trim() in defineList) { // 定义过的才操作
- result.add(Sentence(funName, param.trim(), getType()))
+ if (antiC(param.trim()) in defineList) { // 定义过的才操作
+ result.add(Sentence(funName, antiC(param.trim()), getType()))
}
}
}
} else {
- if (right in defineList) { // 看看有没有使用值
+ if (antiC(right) in defineList) { // 看看有没有使用值
result.add(
Sentence(
- "-", right, getType()
+ "-", antiC(right), getType()
)
)
} else { // 看是不是有运算符号
diff --git a/src/main/kotlin/core/SourceFile.kt b/src/main/kotlin/core/SourceFile.kt
index 6d8aaf5..0016a5e 100644
--- a/src/main/kotlin/core/SourceFile.kt
+++ b/src/main/kotlin/core/SourceFile.kt
@@ -4,6 +4,7 @@ import java.io.File
import core.CLanguage.Companion.OPERATION.*
import core.CLanguage.Companion.declarationRegex
import core.CLanguage.Companion.types
+import utils.Helper.Companion.transformIfStatement
class SourceFile {
@Suppress("unused") // IDE 错误
@@ -96,9 +97,30 @@ class SourceFile {
noDefine.append(noFuncInDefine)
}
+ val noFor = StringBuilder()
+ var hasFor = false
+ noDefine.lines().forEach { line ->
+ if (line.trim().startsWith("for")) {
+ val useful = line.trim().split('(').last().split(';').first()
+ noFor.append("$useful;\n")
+ hasFor = true
+ } else {
+ if (hasFor) {
+ if (line.trim().startsWith('}')) {
+ hasFor = false
+ } else {
+ noFor.append(line + '\n')
+ }
+ } else {
+ noFor.append(line + '\n')
+ }
+ }
+ }
+
+
// 将 int a = 1, b=2,c=3;这样的行变为 int a = 1; int b =2; int c = 3; 方便分析
val noContinueValue = StringBuilder()
- noDefine.lines().forEach { line ->
+ noFor.toString().lines().forEach { line ->
if (line.contains('=') && line.contains(',')// 或许是连续赋值
&& !line.contains('{') // 不是函数调用
&& line.trim().matches(declarationRegex) // 满足像是连续赋值的样子
@@ -119,23 +141,91 @@ class SourceFile {
noContinueValue.append("$identifier $part;")
}
} else {
- noContinueValue.append(line)
+ noContinueValue.append("$line\n")
}
} else {
- noContinueValue.append(line)
+ noContinueValue.append("$line\n")
+ }
+ } else if (line.trim().split(' ').first() in types && line.contains(';') && !line.contains('(') && !line.contains('=')) {
+ val paras = line.trim().split(' ').drop(1).joinToString("").split(';').first().split(',')
+ val type = line.trim().split(' ').first()
+ paras.forEach { param ->
+ noContinueValue.append("$type $param=0;\n")
}
} else {
- noContinueValue.append(line)
+ noContinueValue.append("$line\n")
}
}
- return noContinueValue.toString()
+ val noIf = StringBuilder()
+ var hasIf = false
+ noContinueValue.lines().forEach { line ->
+ if (line.trim().startsWith("if")) {
+ noIf.append(transformIfStatement(line + '\n'))
+ hasIf = true
+ } else {
+ if (hasIf && line.trim().startsWith('}')) {
+ hasIf = false
+ } else {
+ noIf.append("$line\n")
+ }
+ }
+ }
+
+ // 处理 Struct
+ val noStruct = StringBuilder()
+ noIf.lines().forEach { line ->
+ if (line.trim().contains("struct")){
+ if (line.split('{').last().split(' ').first() in types){ // 定义结构体
+ val structName = line.trim().split(' ')[1].split('{').first()
+ types.add("struct`$structName")
+ }else{
+ val parts = line.replace("(","( ").split(' ')
+ val res = StringBuilder()
+ var findStruct = false
+ parts.forEach { part ->
+ if (part.contains("struct")){
+ findStruct = true
+ }else if (findStruct == false){
+ res.append("$part ")
+ }else {
+ res.append("struct`$part ")
+ findStruct = false
+ }
+ }
+ noStruct.append("$res\n")
+ }
+ }else if(line.isNotEmpty()){
+ noStruct.append(line.trim()+'\n')
+ }
+ }
+
+
+ // 修复创建 struct
+ val fixStruct = StringBuilder()
+ for (line in noStruct.toString().replace(";",";\n").lines()) {
+ if (line.contains('`') && line.contains('{') && line.contains('=')){ // 含有创建struct
+ // struct`Point p1 = {1, 2};
+ val left = line.split('=').first()
+ fixStruct.append("$left= struct_define_value;\n")
+ }else if (line.isNotEmpty()){
+ fixStruct.append("$line\n")
+ }
+ }
+
+ return fixStruct.toString()
.replace(";;", ";")
+ .replace(" "," ")
.replace(";", ";\n")
.replace("{", "{\n")
.replace("}", "}\n")
.replace(" =", "=")
.replace("= ", "=")
+ .replace("\n\n","\n")
+ .replace("\n\n","\n")
+ .replace("->",".")
+ .replace("( ","(")
+ .replace("\".*\"".toRegex(),"\"string_literal\"")
}
}
@@ -190,7 +280,6 @@ class SourceFile {
val globalResult = mutableMapOf>()
functions.forEach {
val funcResult = mutableListOf()
-
// 第一个处理参数
if (it.paramNameList.isEmpty()) {
funcResult.add("void")
@@ -202,24 +291,53 @@ class SourceFile {
// 后面的
val useCache = StringBuilder()
+ var useFuncName: String = ""
+ val ifCache = StringBuilder()
+
+ fun invalidCache(){
+ if (useCache.isNotEmpty()) {
+ funcResult.add(useCache.toString())
+ useCache.clear() // 清空
+ }
+ if (ifCache.isNotEmpty()) {
+ funcResult.add(ifCache.toString().dropLast(1))
+ ifCache.clear()
+ }
+ }
it.cParser.sentenceList.forEach { sentence ->
when (sentence.type) {
- FUNCTION_INVOCATION, RETURN -> {
- if (useCache.isNotEmpty()) {
+ FUNCTION_INVOCATION -> {
+ invalidCache()
+ if (useFuncName != sentence.left && useFuncName.isNotEmpty()){
+ useFuncName = sentence.left
funcResult.add(useCache.toString())
useCache.clear() // 清空
}
+ if (sentence.right in it.cParser.defineList) {
+ useCache.append("${sentence.right}-use;")
+ }else if (sentence.right.contains('.')) {
+ val param = sentence.right.split('.').first()
+ if (param in it.cParser.defineList){
+ useCache.append("${param}-use;")
+ }
+ }
+ }
+
+ RETURN -> {
+ invalidCache()
if (sentence.right in it.cParser.defineList) {
funcResult.add("${sentence.right}-use")
+ }else if (sentence.right.contains('.')) {
+ val param = sentence.right.split('.').first()
+ if (param in it.cParser.defineList){
+ funcResult.add("${param}-use")
+ }
}
}
DEFINE_VALUE, CHANGE_VALUE -> {
- if (useCache.isNotEmpty()) {
- funcResult.add(useCache.toString())
- useCache.clear()
- }
+ invalidCache()
useCache.append("${sentence.left}-def")
}
@@ -227,11 +345,19 @@ class SourceFile {
useCache.append(";${sentence.right}-use")
}
+ IF_PARAM -> {
+ if (useCache.isNotEmpty()) {
+ funcResult.add(useCache.toString())
+ useCache.clear()
+ }
+ ifCache.append("${sentence.right}-use;")
+ }
+
PARAM -> {} // 参数只用于构造def-use跨函数
}
}
if (useCache.isNotEmpty()) {
- funcResult.add(useCache.toString())
+ funcResult.add(useCache.toString())s
}
globalResult[it.name] = funcResult
}
diff --git a/src/main/kotlin/utils/Helper.kt b/src/main/kotlin/utils/Helper.kt
new file mode 100644
index 0000000..c9e3a8e
--- /dev/null
+++ b/src/main/kotlin/utils/Helper.kt
@@ -0,0 +1,18 @@
+package utils
+
+class Helper {
+ companion object{
+ fun transformIfStatement(input: String): String {
+ val regex = Regex("""\bif\s*\(\s*([^)]+)\s*\)\s*\{""")
+ return input.replace(regex) { matchResult ->
+ val condition = matchResult.groupValues[1]
+ val modifiedCondition = condition.replace(Regex("""\s*[><=!]+\s*"""), ",")
+ "if($modifiedCondition);\n"
+ }
+ }
+
+ // 解决引用解引用
+ fun antiC(string: String): String = string.replace("*","")
+ .replace("&","")
+ }
+}
\ No newline at end of file