Skip to content

Commit

Permalink
refactor(c): update sample for c language #24
Browse files Browse the repository at this point in the history
  • Loading branch information
phodal committed Jan 6, 2024
1 parent ace46e7 commit fc84931
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 30 deletions.
20 changes: 6 additions & 14 deletions chapi-ast-c/src/main/antlr/C.g4
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
grammar C;

compilationUnit
: includeDeclaration? translationUnit? EOF
: includeDeclaration? externalDeclaration+ EOF
;

includeDeclaration
Expand Down Expand Up @@ -179,14 +179,10 @@ constantExpression
;

declaration
: declarationSpecifiers initDeclaratorList? ';'
: declarationSpecifier+ initDeclaratorList? ';'
| staticAssertDeclaration
;

declarationSpecifiers
: declarationSpecifier+
;

declarationSpecifier
: storageClassSpecifier
| typeSpecifier
Expand Down Expand Up @@ -386,8 +382,8 @@ parameterList
;

parameterDeclaration
: declarationSpecifiers declarator
| declarationSpecifiers abstractDeclarator?
: declarationSpecifier+ declarator
| declarationSpecifier+ abstractDeclarator?
;

identifierList
Expand Down Expand Up @@ -501,7 +497,7 @@ forCondition
;

forDeclaration
: declarationSpecifiers initDeclaratorList?
: declarationSpecifier+ initDeclaratorList?
;

forExpression
Expand All @@ -518,18 +514,14 @@ jumpStatement
) ';'
;

translationUnit
: externalDeclaration+
;

externalDeclaration
: functionDefinition
| declaration
| ';' // stray ;
;

functionDefinition
: declarationSpecifiers? declarator declarationList? compoundStatement
: declarationSpecifier+ declarator declarationList? compoundStatement
;

declarationList
Expand Down
36 changes: 31 additions & 5 deletions chapi-ast-c/src/main/kotlin/chapi/ast/cast/CFullIdentListener.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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, "")
}
}

0 comments on commit fc84931

Please sign in to comment.