feat: support define

This commit is contained in:
Kagura 2024-10-31 23:14:58 +08:00
parent 7302f831b0
commit 1120374505
2 changed files with 107 additions and 39 deletions

View file

@ -1,7 +1,9 @@
#include <stdio.h>
#define PLUS(first,later) first+later
// 你看我还能用 define
// 当然也能写注释
int add(int a, int b) {
int c = a + b;
int c = PLUS(a,b);
return c;
}

View file

@ -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()
}
// 处理 DEFINE, 支持如下
// #define SOMETHING ANOTHERTHING 这样的
// #define ADD(a, b) a + b
val noFuncInDefine = StringBuilder()
// 获取 define 的内容
val simpleDefineList = mutableMapOf<String, String>() // #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')
}
}
}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()
noComment.lines().forEach { line ->
if (line.contains('=') && line.contains(',')){ // 或许是连续赋值
if (!line.contains('{')){ // 不是函数调用
if (line.trim().matches(declarationRegex)){ // 满足像是连续赋值的样子
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){ // 获取标识符
if (identifier in types) { // 获取标识符
val parts = remain.split(',') // 逗号分开
var allHasEqual = true
for (part in parts){
if (!part.contains('=')){
for (part in parts) {
if (!part.contains('=')) {
allHasEqual = false
}
}
if (allHasEqual){
if (allHasEqual) { // 确定是
parts.forEach { part ->
noContinueValue.append("$identifier $part;")
}
}else{
} else {
noContinueValue.append(line)
}
}else{
} else {
noContinueValue.append(line)
}
}else{
noContinueValue.append(line)
}
}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<String,List<String>> {
val globalResult = mutableMapOf<String,List<String>>()
fun getUse(): Map<String, List<String>> {
val globalResult = mutableMapOf<String, List<String>>()
functions.forEach {
val funcResult = mutableListOf<String>()
@ -156,7 +222,7 @@ fun main() {
val funcs = sourceFile.parseFunction()
val relations = mutableMapOf<String, List<Relation>>()
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))