tunnelvisionlabs / antlr4ts

Optimized TypeScript target for ANTLR 4
Other
624 stars 106 forks source link

How to generate final actual code output from parser? #510

Closed shama closed 2 years ago

shama commented 2 years ago

Apologies if it's super obvious and I'm just being dense but once you have a parser, how do you generate the final output string of actual code?

How do I do that?


The closes thing I've found was:

const tree = parser.program() // program being the top level declaration in the TypeScript.g4 file
console.log(tree.text) === "functiontest():number{return1;}<EOF>"

But that isn't valid TypeScript


Again sorry if it's super obvious and I'm just missing it in the docs, issues or tests. Any help would be much appreciated, thanks!

sharwell commented 2 years ago

The string that you passed to the ANTLRInputStream constructor is the code. You can use that directly and don't need the parser for it.

This probably isn't a helpful answer, but it's not clear to me what the specific question is that would have a different answer. Please feel free to clarify. 😄

shama commented 2 years ago

Thanks for the response! Sorry I wasn't clear enough. My end goal is to eventually transpile TypeScript to Kotlin. If you know of existing efforts towards that please let me know as I would love to contribute.

As a first step, I want to see if I can feed some TypeScript code into an antlr4 generated parser and then have it export the code back. If I can do that, then I was going to attempt to modify the AST and have it export the modified TypeScript code.

So far I've been unable to figure out how to export the final code after it's been read and modified with a parser.

If I can modify and export TypeScript then later I was then planning on trying to map TypeScript syntax to Kotlin syntax using the KotlinLexer.g4 and KotlinParser.g4 files. Then start to transpile TypeScript code into Kotlin code.

Another thing I tried was with the Visitor:

class TypeScript2Kotlin extends AbstractParseTreeVisitor<string> implements TypeScriptVisitor<string> {
    defaultResult() {
        return ""
    }
    aggregateResult(aggregate: string, nextResult: string) {
        return aggregate + nextResult
    }
    visitType(context: TypeContext): string {
        switch (context.text) {
            case "number":
                return "Int"
        }
        return context.text + super.visitChildren(context)
    }
}

But that appears I would have to write a visit[SyntaxPart] for every piece of syntax in TypeScript and format the output code by hand. I assumed if antlr4 can build parsers to read languages it could also write languages and I was missing on how to do that.

I'm fairly new to antlr and have only worked with custom built AST parsers so pardon my ignorance. If I'm going about it the wrong way and there is a better way to convert one source into another source I would love to know. Thank you so much!

shama commented 2 years ago

I think this talk answered my question: https://www.youtube.com/watch?v=BD-I3f0aTbs

I was mistakenly thinking of the parser as an AST which I am now understanding it is different. My understanding now is the parser is a Parse Tree which is read only. You then use a Visitor to traverse the parse tree to generate the final output code and how the code is generated is up to me.