fuck
This commit is contained in:
parent
ab5821a062
commit
0bba6d9943
6 changed files with 194 additions and 27 deletions
|
@ -7,7 +7,7 @@
|
|||
<component name="PWA">
|
||||
<option name="wasEnabledAtLeastOnce" value="true" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_23" default="true" project-jdk-name="openjdk-22" project-jdk-type="JavaSDK">
|
||||
<component name="ProjectRootManager" version="2" languageLevel="JDK_22" default="true" project-jdk-name="openjdk-22" project-jdk-type="JavaSDK">
|
||||
<output url="file://$PROJECT_DIR$/out" />
|
||||
</component>
|
||||
</project>
|
|
@ -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,15 +35,29 @@ 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 ->
|
||||
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 = parts.getOrNull(1) ?: ""
|
||||
val name = antiC(parts.getOrNull(1) ?: "")
|
||||
mapOf(name to type)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun parseContent(source: String): String {
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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<String>) {
|
|||
} 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<String>) {
|
|||
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 { // 看是不是有运算符号
|
||||
|
|
|
@ -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<String, List<String>>()
|
||||
functions.forEach {
|
||||
val funcResult = mutableListOf<String>()
|
||||
|
||||
// 第一个处理参数
|
||||
if (it.paramNameList.isEmpty()) {
|
||||
funcResult.add("void")
|
||||
|
@ -202,24 +291,53 @@ class SourceFile {
|
|||
|
||||
// 后面的
|
||||
val useCache = StringBuilder()
|
||||
var useFuncName: String = ""
|
||||
val ifCache = StringBuilder()
|
||||
|
||||
it.cParser.sentenceList.forEach { sentence ->
|
||||
when (sentence.type) {
|
||||
FUNCTION_INVOCATION, RETURN -> {
|
||||
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 -> {
|
||||
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
|
||||
}
|
||||
|
|
18
src/main/kotlin/utils/Helper.kt
Normal file
18
src/main/kotlin/utils/Helper.kt
Normal file
|
@ -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("&","")
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue