From fc84931ea9e6a678e8aaff7b1163332fdd739757 Mon Sep 17 00:00:00 2001 From: Phodal Huang Date: Sat, 6 Jan 2024 15:57:57 +0800 Subject: [PATCH] refactor(c): update sample for c language #24 --- chapi-ast-c/src/main/antlr/C.g4 | 20 ++++------- .../chapi/ast/cast/CFullIdentListener.kt | 36 ++++++++++++++++--- .../chapi/ast/cast/CFullIdentListenerTest.kt | 19 +++++----- 3 files changed, 45 insertions(+), 30 deletions(-) diff --git a/chapi-ast-c/src/main/antlr/C.g4 b/chapi-ast-c/src/main/antlr/C.g4 index b039547a..5381fb27 100644 --- a/chapi-ast-c/src/main/antlr/C.g4 +++ b/chapi-ast-c/src/main/antlr/C.g4 @@ -34,7 +34,7 @@ grammar C; compilationUnit - : includeDeclaration? translationUnit? EOF + : includeDeclaration? externalDeclaration+ EOF ; includeDeclaration @@ -179,14 +179,10 @@ constantExpression ; declaration - : declarationSpecifiers initDeclaratorList? ';' + : declarationSpecifier+ initDeclaratorList? ';' | staticAssertDeclaration ; -declarationSpecifiers - : declarationSpecifier+ - ; - declarationSpecifier : storageClassSpecifier | typeSpecifier @@ -386,8 +382,8 @@ parameterList ; parameterDeclaration - : declarationSpecifiers declarator - | declarationSpecifiers abstractDeclarator? + : declarationSpecifier+ declarator + | declarationSpecifier+ abstractDeclarator? ; identifierList @@ -501,7 +497,7 @@ forCondition ; forDeclaration - : declarationSpecifiers initDeclaratorList? + : declarationSpecifier+ initDeclaratorList? ; forExpression @@ -518,10 +514,6 @@ jumpStatement ) ';' ; -translationUnit - : externalDeclaration+ - ; - externalDeclaration : functionDefinition | declaration @@ -529,7 +521,7 @@ externalDeclaration ; functionDefinition - : declarationSpecifiers? declarator declarationList? compoundStatement + : declarationSpecifier+ declarator declarationList? compoundStatement ; declarationList diff --git a/chapi-ast-c/src/main/kotlin/chapi/ast/cast/CFullIdentListener.kt b/chapi-ast-c/src/main/kotlin/chapi/ast/cast/CFullIdentListener.kt index 313ba7d6..f456595e 100644 --- a/chapi-ast-c/src/main/kotlin/chapi/ast/cast/CFullIdentListener.kt +++ b/chapi-ast-c/src/main/kotlin/chapi/ast/cast/CFullIdentListener.kt @@ -21,8 +21,35 @@ open class CFullIdentListener(fileName: String) : CAstBaseListener() { codeContainer.Imports += imp } - override fun enterStructOrUnionSpecifier(ctx: CParser.StructOrUnionSpecifierContext?) { - val nodeName = ctx?.Identifier()?.text ?: "" + + override fun enterDeclaration(ctx: CParser.DeclarationContext?) { + val isTypeDef = ctx?.declarationSpecifier()?.any { + it.storageClassSpecifier()?.Typedef() != null + } ?: false + + val maybeNodeName = ctx?.declarationSpecifier()?.filter { + it.typeSpecifier()?.typedefName() != null + }?.map { + it.typeSpecifier()?.typedefName()?.text + }?.firstOrNull() + + val structOrUnionSpecifier = ctx?.declarationSpecifier()?.filter { + it.typeSpecifier()?.structOrUnionSpecifier() != null + }?.map { + it.typeSpecifier()?.structOrUnionSpecifier() + }?.firstOrNull() + + structOrUnionSpecifier?.let { + var nodeName = maybeNodeName ?: structOrUnionSpecifier.Identifier()?.text + if (nodeName.isNullOrEmpty()) { + nodeName = structOrUnionSpecifier.structOrUnion().text + } + + handleStructOrUnion(structOrUnionSpecifier, nodeName ?: "") + } + } + + private fun handleStructOrUnion(ctx: CParser.StructOrUnionSpecifierContext?, nodeName: String) { structMap.getOrPut(nodeName) { CodeDataStruct(NodeName = nodeName, Position = buildPosition(ctx)) }.let { @@ -70,7 +97,7 @@ open class CFullIdentListener(fileName: String) : CAstBaseListener() { parseDirectDeclarator(ctx.directDeclarator()) currentFunction.Parameters = ctx.parameterTypeList().parameterList().parameterDeclaration().mapNotNull { - val type = it.declarationSpecifiers().declarationSpecifier().firstOrNull()?.typeSpecifier()?.text + val type = it.declarationSpecifier().firstOrNull()?.typeSpecifier()?.text val name = it.declarator().directDeclarator()?.let { directDeclarator -> when (directDeclarator) { @@ -112,8 +139,7 @@ open class CFullIdentListener(fileName: String) : CAstBaseListener() { override fun enterFunctionDefinition(ctx: CParser.FunctionDefinitionContext?) { currentFunction = CodeFunction(Position = buildPosition(ctx)) - - ctx?.declarationSpecifiers()?.declarationSpecifier()?.map { + ctx?.declarationSpecifier()?.map { if (it.typeSpecifier().text != null) { if (it.typeSpecifier().typedefName() != null) { currentFunction.Name = it.typeSpecifier().typedefName().text diff --git a/chapi-ast-c/src/test/kotlin/chapi/ast/cast/CFullIdentListenerTest.kt b/chapi-ast-c/src/test/kotlin/chapi/ast/cast/CFullIdentListenerTest.kt index 8348f0ad..e8fe584a 100644 --- a/chapi-ast-c/src/test/kotlin/chapi/ast/cast/CFullIdentListenerTest.kt +++ b/chapi-ast-c/src/test/kotlin/chapi/ast/cast/CFullIdentListenerTest.kt @@ -184,17 +184,14 @@ typedef struct { } element; // Complete definition """ val codeFile = CAnalyser().analysis(code, "helloworld.c") - assertEquals(codeFile.DataStructures.size, 2) - - val firstDs = codeFile.DataStructures[0] - assertEquals(firstDs.NodeName, "element") - assertEquals(firstDs.Fields.size, 0) + assertEquals(codeFile.DataStructures.size, 1) - val secondDs = codeFile.DataStructures[1] -// assertEquals(secondDs.NodeName, "element") -// assertEquals(secondDs.Fields.size, 2) -// assertEquals(secondDs.Fields[0].TypeType, "int") -// assertEquals(secondDs.Fields[0].TypeValue, "value") -// assertEquals(secondDs.Fields[1].TypeType, "struct element*") + val elementDs = codeFile.DataStructures[0] + assertEquals(elementDs.NodeName, "element") + assertEquals(elementDs.Fields.size, 2) + assertEquals(elementDs.Fields[0].TypeType, "int") + assertEquals(elementDs.Fields[0].TypeValue, "value") +// assertEquals(elementDs.Fields[1].TypeType, "struct element*") + assertEquals(elementDs.Fields[1].TypeValue, "") } }