feat: support define
This commit is contained in:
parent
7302f831b0
commit
1120374505
2 changed files with 107 additions and 39 deletions
|
@ -1,7 +1,9 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#define PLUS(first,later) first+later
|
||||||
|
// 你看我还能用 define
|
||||||
|
// 当然也能写注释
|
||||||
int add(int a, int b) {
|
int add(int a, int b) {
|
||||||
int c = a + b;
|
int c = PLUS(a,b);
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,56 +12,122 @@ class SourceFile {
|
||||||
val function_define_regex = """\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*\{""".toRegex() // main(){ 匹配函数名
|
val function_define_regex = """\b([a-zA-Z_][a-zA-Z0-9_]*)\s*\([^)]*\)\s*\{""".toRegex() // main(){ 匹配函数名
|
||||||
|
|
||||||
fun formatSource(src: String): String {
|
fun formatSource(src: String): String {
|
||||||
|
// 去掉注释
|
||||||
val noComment = src.lines()
|
val noComment = src.lines()
|
||||||
.filter { line -> !line.trimStart().startsWith("#include") && !line.trimStart().startsWith("//") }
|
.filter { line -> !line.trimStart().startsWith("#include") && !line.trimStart().startsWith("//") }
|
||||||
.joinToString("\n") { line ->
|
.joinToString("\n") { line ->
|
||||||
val withoutTrailingComment = line.replace(Regex("//.*$"), "")
|
val withoutTrailingComment = line.replace(Regex("//.*$"), "")
|
||||||
withoutTrailingComment.trimStart()
|
withoutTrailingComment.trimStart()
|
||||||
}
|
}
|
||||||
val noContinueValue = StringBuilder()
|
|
||||||
noComment.lines().forEach { line ->
|
// 处理 DEFINE, 支持如下
|
||||||
if (line.contains('=') && line.contains(',')){ // 或许是连续赋值
|
// #define SOMETHING ANOTHERTHING 这样的
|
||||||
if (!line.contains('{')){ // 不是函数调用
|
// #define ADD(a, b) a + b
|
||||||
if (line.trim().matches(declarationRegex)){ // 满足像是连续赋值的样子
|
val noFuncInDefine = StringBuilder()
|
||||||
val splits = line.split(' ')
|
// 获取 define 的内容
|
||||||
val identifier = splits.first()
|
val simpleDefineList = mutableMapOf<String, String>() // #define a 0 -> "a" -> "0"
|
||||||
val remain = splits.drop(1).joinToString(" ")
|
for (line in noComment.lines()) {
|
||||||
if (identifier in types){ // 获取标识符
|
if (line.trim().startsWith("#define")) {
|
||||||
val parts = remain.split(',') // 逗号分开
|
val args = line.trim().split(" ")
|
||||||
var allHasEqual = true
|
if (args.size >= 3) {
|
||||||
for (part in parts){
|
if (args[1].contains("(")){ // Define Function
|
||||||
if (!part.contains('=')){
|
val defFuncName = args[1].split('(').first().trim()
|
||||||
allHasEqual = false
|
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)
|
noContinueValue.append(line)
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
noContinueValue.append(line)
|
noContinueValue.append(line)
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
noContinueValue.append(line)
|
noContinueValue.append(line)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return noContinueValue
|
|
||||||
.toString()
|
return noContinueValue.toString()
|
||||||
.replace(";;",";")
|
.replace(";;", ";")
|
||||||
.replace(";",";\n")
|
.replace(";", ";\n")
|
||||||
.replace("{","{\n")
|
.replace("{", "{\n")
|
||||||
.replace("}","}\n")
|
.replace("}", "}\n")
|
||||||
.replace(" =","=")
|
.replace(" =", "=")
|
||||||
.replace("= ","=")
|
.replace("= ", "=")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,8 +164,8 @@ class SourceFile {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getUse(): Map<String,List<String>> {
|
fun getUse(): Map<String, List<String>> {
|
||||||
val globalResult = mutableMapOf<String,List<String>>()
|
val globalResult = mutableMapOf<String, List<String>>()
|
||||||
functions.forEach {
|
functions.forEach {
|
||||||
val funcResult = mutableListOf<String>()
|
val funcResult = mutableListOf<String>()
|
||||||
|
|
||||||
|
@ -156,7 +222,7 @@ fun main() {
|
||||||
val funcs = sourceFile.parseFunction()
|
val funcs = sourceFile.parseFunction()
|
||||||
val relations = mutableMapOf<String, List<Relation>>()
|
val relations = mutableMapOf<String, List<Relation>>()
|
||||||
funcs.forEach {
|
funcs.forEach {
|
||||||
relations.putAll(parseRelation(it.name,it.getTraceTree().getStringRepr()))
|
relations.putAll(parseRelation(it.name, it.getTraceTree().getStringRepr()))
|
||||||
}
|
}
|
||||||
for (function in funcs) {
|
for (function in funcs) {
|
||||||
println(funcs.getInvokeTree(function.name).getFuncRepr(function.name))
|
println(funcs.getInvokeTree(function.name).getFuncRepr(function.name))
|
||||||
|
|
Loading…
Reference in a new issue