This commit is contained in:
kagura 2024-11-06 21:13:02 +08:00
parent ab5821a062
commit 0bba6d9943
6 changed files with 194 additions and 27 deletions

View file

@ -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>

View file

@ -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 {

View file

@ -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")

View file

@ -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 { // 看是不是有运算符号

View file

@ -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
}

View 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("&","")
}
}