-
Notifications
You must be signed in to change notification settings - Fork 44
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(thrift): add Thrift grammar, analyser, and build setup
This commit introduces a Thrift grammar definition, a Thrift parser listener for extracting code information, a Thrift analysis class, and the necessary Gradle build files to support the Thrift AST functionality within the project.
- Loading branch information
Showing
5 changed files
with
385 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
plugins { | ||
id("antlr") | ||
java | ||
kotlin("jvm") | ||
kotlin("plugin.serialization") version "1.6.10" | ||
|
||
`jacoco-conventions` | ||
} | ||
|
||
repositories { | ||
mavenCentral() | ||
mavenLocal() | ||
} | ||
|
||
dependencies { | ||
antlr("org.antlr:antlr4:4.13.1") | ||
|
||
// project deps | ||
implementation(project(":chapi-domain")) | ||
|
||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.3.2") | ||
|
||
implementation(kotlin("stdlib-jdk8")) | ||
implementation(kotlin("reflect")) | ||
// Kotlin reflection. | ||
testImplementation(kotlin("test")) | ||
|
||
// JUnit 5 | ||
testImplementation("org.junit.jupiter:junit-jupiter-api:5.6.0") | ||
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.6.0") | ||
testRuntimeOnly("org.junit.platform:junit-platform-console:1.6.0") | ||
|
||
implementation("org.antlr:antlr4:4.13.1") | ||
implementation("org.antlr:antlr4-runtime:4.13.1") | ||
} | ||
|
||
sourceSets.main { | ||
java.srcDirs("${project.buildDir}/generated-src") | ||
} | ||
|
||
tasks.generateGrammarSource { | ||
maxHeapSize = "64m" | ||
arguments = arguments + listOf("-package", "chapi.ast.antlr") + listOf("-visitor", "-long-messages") | ||
outputDirectory = file("${project.buildDir}/generated-src/chapi/ast/antlr") | ||
} | ||
|
||
tasks.withType<AntlrTask> { | ||
|
||
} | ||
|
||
tasks.named("compileKotlin") { | ||
dependsOn(tasks.withType<AntlrTask>()) | ||
} | ||
|
||
tasks.withType<Test> { | ||
useJUnitPlatform() | ||
testLogging { | ||
events("passed", "skipped", "failed") | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,279 @@ | ||
// $antlr-format alignTrailingComments true, columnLimit 150, minEmptyLines 1, maxEmptyLinesToKeep 1, reflowComments false, useTab false | ||
// $antlr-format allowShortRulesOnASingleLine false, allowShortBlocksOnASingleLine true, alignSemicolons hanging, alignColons hanging | ||
|
||
grammar Thrift; | ||
|
||
document | ||
: header* definition* EOF | ||
; | ||
|
||
header | ||
: include_ | ||
| namespace_ | ||
| cpp_include | ||
; | ||
|
||
include_ | ||
: 'include' LITERAL | ||
; | ||
|
||
namespace_ | ||
: 'namespace' '*' (IDENTIFIER | LITERAL) | ||
| 'namespace' IDENTIFIER (IDENTIFIER | LITERAL) type_annotations? | ||
| 'cpp_namespace' IDENTIFIER | ||
| 'php_namespace' IDENTIFIER | ||
; | ||
|
||
cpp_include | ||
: 'cpp_include' LITERAL | ||
; | ||
|
||
definition | ||
: const_rule | ||
| typedef_ | ||
| enum_rule | ||
| senum | ||
| struct_ | ||
| union_ | ||
| exception | ||
| service | ||
; | ||
|
||
const_rule | ||
: 'const' field_type IDENTIFIER ('=' const_value)? list_separator? | ||
; | ||
|
||
typedef_ | ||
: 'typedef' field_type IDENTIFIER type_annotations? | ||
; | ||
|
||
enum_rule | ||
: 'enum' IDENTIFIER '{' enum_field* '}' type_annotations? | ||
; | ||
|
||
enum_field | ||
: IDENTIFIER ('=' integer)? type_annotations? list_separator? | ||
; | ||
|
||
senum | ||
: 'senum' IDENTIFIER '{' (LITERAL list_separator?)* '}' type_annotations? | ||
; | ||
|
||
struct_ | ||
: 'struct' IDENTIFIER '{' field* '}' type_annotations? | ||
; | ||
|
||
union_ | ||
: 'union' IDENTIFIER '{' field* '}' type_annotations? | ||
; | ||
|
||
exception | ||
: 'exception' IDENTIFIER '{' field* '}' type_annotations? | ||
; | ||
|
||
service | ||
: 'service' IDENTIFIER ('extends' IDENTIFIER)? '{' function_* '}' type_annotations? | ||
; | ||
|
||
field | ||
: field_id? field_req? field_type IDENTIFIER ('=' const_value)? type_annotations? list_separator? | ||
; | ||
|
||
field_id | ||
: integer ':' | ||
; | ||
|
||
field_req | ||
: 'required' | ||
| 'optional' | ||
; | ||
|
||
function_ | ||
: oneway? function_type IDENTIFIER '(' field* ')' throws_list? type_annotations? list_separator? | ||
; | ||
|
||
oneway | ||
: ('oneway' | 'async') | ||
; | ||
|
||
function_type | ||
: field_type | ||
| 'void' | ||
; | ||
|
||
throws_list | ||
: 'throws' '(' field* ')' | ||
; | ||
|
||
type_annotations | ||
: '(' type_annotation* ')' | ||
; | ||
|
||
type_annotation | ||
: IDENTIFIER ('=' annotation_value)? list_separator? | ||
; | ||
|
||
annotation_value | ||
: integer | ||
| LITERAL | ||
; | ||
|
||
field_type | ||
: base_type | ||
| IDENTIFIER | ||
| container_type | ||
; | ||
|
||
base_type | ||
: real_base_type type_annotations? | ||
; | ||
|
||
container_type | ||
: (map_type | set_type | list_type) type_annotations? | ||
; | ||
|
||
map_type | ||
: 'map' cpp_type? '<' field_type COMMA field_type '>' | ||
; | ||
|
||
set_type | ||
: 'set' cpp_type? '<' field_type '>' | ||
; | ||
|
||
list_type | ||
: 'list' '<' field_type '>' cpp_type? | ||
; | ||
|
||
cpp_type | ||
: 'cpp_type' LITERAL | ||
; | ||
|
||
const_value | ||
: integer | ||
| DOUBLE | ||
| LITERAL | ||
| IDENTIFIER | ||
| const_list | ||
| const_map | ||
; | ||
|
||
integer | ||
: INTEGER | ||
| HEX_INTEGER | ||
; | ||
|
||
INTEGER | ||
: ('+' | '-')? DIGIT+ | ||
; | ||
|
||
HEX_INTEGER | ||
: '-'? '0x' HEX_DIGIT+ | ||
; | ||
|
||
DOUBLE | ||
: ('+' | '-')? (DIGIT+ ('.' DIGIT+)? | '.' DIGIT+) (('E' | 'e') INTEGER)? | ||
; | ||
|
||
const_list | ||
: '[' (const_value list_separator?)* ']' | ||
; | ||
|
||
const_map_entry | ||
: const_value ':' const_value list_separator? | ||
; | ||
|
||
const_map | ||
: '{' const_map_entry* '}' | ||
; | ||
|
||
list_separator | ||
: COMMA | ||
| ';' | ||
; | ||
|
||
real_base_type | ||
: TYPE_BOOL | ||
| TYPE_BYTE | ||
| TYPE_I16 | ||
| TYPE_I32 | ||
| TYPE_I64 | ||
| TYPE_DOUBLE | ||
| TYPE_STRING | ||
| TYPE_BINARY | ||
; | ||
|
||
TYPE_BOOL | ||
: 'bool' | ||
; | ||
|
||
TYPE_BYTE | ||
: 'byte' | ||
; | ||
|
||
TYPE_I16 | ||
: 'i16' | ||
; | ||
|
||
TYPE_I32 | ||
: 'i32' | ||
; | ||
|
||
TYPE_I64 | ||
: 'i64' | ||
; | ||
|
||
TYPE_DOUBLE | ||
: 'double' | ||
; | ||
|
||
TYPE_STRING | ||
: 'string' | ||
; | ||
|
||
TYPE_BINARY | ||
: 'binary' | ||
; | ||
|
||
LITERAL | ||
: '"' (ESC_SEQ | ~[\\"])* '"' | ||
| '\'' ( ESC_SEQ | ~[\\'])* '\'' | ||
; | ||
|
||
fragment ESC_SEQ | ||
: '\\' [rnt"'\\] | ||
; | ||
IDENTIFIER | ||
: (LETTER | '_') (LETTER | DIGIT | '.' | '_')* | ||
; | ||
COMMA | ||
: ',' | ||
; | ||
fragment LETTER | ||
: 'A' ..'Z' | ||
| 'a' ..'z' | ||
; | ||
fragment DIGIT | ||
: '0' ..'9' | ||
; | ||
fragment HEX_DIGIT | ||
: DIGIT | ||
| 'A' ..'F' | ||
| 'a' ..'f' | ||
; | ||
WS | ||
: (' ' | '\t' | '\r' '\n' | '\n')+ -> channel(HIDDEN) | ||
; | ||
SL_COMMENT | ||
: ('//' | '#') (~'\n')* ('\r')? '\n' -> channel(HIDDEN) | ||
; | ||
ML_COMMENT | ||
: '/*' .*? '*/' -> channel(HIDDEN) | ||
; |
26 changes: 26 additions & 0 deletions
26
chapi-ast-thrift/src/main/kotlin/chapi/ast/thrift/ThriftAnalyser.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
package chapi.ast.thrift | ||
|
||
import chapi.ast.antlr.ThriftLexer | ||
import chapi.ast.antlr.ThriftParser | ||
import chapi.domain.core.CodeContainer | ||
import chapi.parser.Analyser | ||
import org.antlr.v4.runtime.* | ||
import org.antlr.v4.runtime.tree.ParseTreeWalker | ||
|
||
class ThriftAnalyser : Analyser { | ||
override fun analysis(code: String, filePath: String): CodeContainer { | ||
val context = this.parse(code).document() | ||
val listener = ThriftFullIdentListener(fileName = filePath) | ||
ParseTreeWalker().walk(listener, context) | ||
|
||
return listener.getNodeInfo() | ||
} | ||
|
||
private fun parse(str: String): ThriftParser { | ||
val fromString = CharStreams.fromString(str) | ||
val lexer = ThriftLexer(fromString) | ||
val tokenStream = CommonTokenStream(lexer) | ||
val parser = ThriftParser(tokenStream) | ||
return parser | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
chapi-ast-thrift/src/main/kotlin/chapi/ast/thrift/ThriftFullIdentListener.kt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package chapi.ast.thrift | ||
|
||
import chapi.ast.antlr.ThriftBaseListener | ||
import chapi.ast.antlr.ThriftParser | ||
import chapi.domain.core.CodeContainer | ||
|
||
class ThriftFullIdentListener(fileName: String) : ThriftBaseListener() { | ||
private var codeContainer: CodeContainer = CodeContainer(FullName = fileName) | ||
|
||
override fun enterNamespace_(ctx: ThriftParser.Namespace_Context?) { | ||
val prefix = ctx!!.children[0].text | ||
val namespace = ctx.text.removePrefix(prefix).trim() | ||
codeContainer.PackageName = namespace | ||
} | ||
|
||
fun getNodeInfo(): CodeContainer { | ||
return codeContainer | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters