Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sealed classes instead of multiple nullable values?! #178

Open
andretietz opened this issue Apr 9, 2024 · 5 comments
Open

sealed classes instead of multiple nullable values?! #178

andretietz opened this issue Apr 9, 2024 · 5 comments

Comments

@andretietz
Copy link

Hey during using this awesome library, I noticed a thing that bugs me a bit.

a parser rule that has multiple options

document: rule EOF;
rule
  : OPTIONA
  | OPTIONB;

generates into:

val rule = document.rule()
rule.getOptiona() // nullable
rule.getOptionb() // nullable

I would very much prefer if that generates into:

sealed class Rule {
   data class Optiona(...) : Rule
   data class Optionb(...) : Rule
}

Would that be possible?

Can you hint me to the generation part where this part happening, may be I take a look myself?

@ftomassetti
Copy link
Member

Hey during using this awesome library, I noticed a thing that bugs me a bit.

We just wanted to be sure it was not too awesome, so introduced a few problems on purpose :D

a parser rule that has multiple options

document: rule EOF;
rule
  : OPTIONA
  | OPTIONB;

generates into:

val rule = document.rule()
rule.getOptiona() // nullable
rule.getOptionb() // nullable

I would very much prefer if that generates into:

sealed class Rule {
   data class Optiona(...) : Rule
   data class Optionb(...) : Rule
}

Would that be possible?

I think this has been implemented in this way to reflect what was present in the Java runtime. Now, your approach is exactly what we do when mapping an ANTLR parse-tree to a Kolasu AST. We have an internal tool where we add annotations (in comments) in ANTLR grammars and when we use the annotation @oneOf we generate sealed classes and subclasses.

Personally I think that generating a more "kotlin-esque" AST would be nice, and perhaps we could control the generation through a flag: by default we could generate an AST in a more "standard" or "like-the-java-runtime" way (so that migration to the Kotlin target is very easy) and optionally, when a tag is specified, produce a different AST.

Can you hint me to the generation part where this part happening, may be I take a look myself?

Generation of code for all ANTLR targets is based on templates. Here there is the one for ANTLR Kotlin: https://github.com/Strumenta/antlr-kotlin/blob/master/antlr-kotlin-target/src/main/resources/org/antlr/v4/tool/templates/codegen/Kotlin/Kotlin.stg

@andretietz
Copy link
Author

andretietz commented Sep 6, 2024

Hey @ftomassetti!

For reasons I still didn't figure out how to use kolasu in my project. Is there a public project you know off, where I can see this in action?
Are there some links you can hint me to, to help me understand how to use it? I really need this!

ATM, I am taking the current option and call methods that does the "translation" for me, but it seems so pointless and is definitely an overhead.

Thank you anyways!

@ftomassetti
Copy link
Member

@andretietz we should write better tutorials at some point, but perhaps these could help:

https://tomassetti.me/build-an-editor-with-kolasu-and-language-servers/
https://tomassetti.me/building-advanced-parsers-using-kolasu/

@andretietz
Copy link
Author

andretietz commented Sep 6, 2024

Hey @ftomassetti thank you!

Now I at least understood what kolasu is supposed to do. It still doesn't do what I actually want to. As you mentioned in your first response, this is what I do atm already.

So you're telling me you're using an internal tool that can generate an AST directly in kotlin without kolasu or any other mappings?
If so, I would be really interested in that :D.

However I wonder what you use antlr-kotlin for, if you're targeting jvm targets anyway.
Why not use the java generator of antlr directly? I don't see the need (at least not for jvm targets).

I successfully used it in several KMP projects, where we target Android/iOS/Mac/Windows/Linux, there jvm compatibility is not a good thing.
What I want to say is: "Why providing a java friendly API for a kotlin first generator?"
If I would like to target jvm only, I don't need antlr-kotlin anyways, right?
Do I oversee something?

Is that something you're going to target one day?

@ftomassetti
Copy link
Member

So you're telling me you're using an internal tool that can generate an AST directly in kotlin without kolasu or any other mappings?
If so, I would be really interested in that :D.

At this time we do not have any plan to release that, but we have a long term plan to replace it with something we could eventually share. It is a few years down the road :D

However I wonder what you use antlr-kotlin for, if you're targeting jvm targets anyway.

Currently, we do not use it in production. However we plan to use it with version 1.6 of Kolasu, to provide parsers that run both on the JVM and in the browser. Possibly, we could also use the native version from Python (generating appropriate wrappers)

Why not use the java generator of antlr directly? I don't see the need (at least not for jvm targets).

Well, we started Kolasu as a small effort built on top of ANTLR, while adding a generator to ANTLR requires quite some work. We now have the skills and the time to do that, but we went another route 7 years ago and built habits, tools, and libraries to support working in this way so changing it is not trivial

What I want to say is: "Why providing a java friendly API for a kotlin first generator?"

Because we may want to generate a parser that we then integrate both in a Typescript application and in a Java application. In this situation we want to build such parser using ANTLR-Kotlin because of its multi-platform nature. In that similar context we could not use ANTLR Java.

In this case by parser I mean the combination of the basic ANTLR parser, generated by ANTLR and some Kotlin multi-platform code built on top of it. For example, I may write a simple grammar for an expression language. Then I may write some code in Kotlin that invoke the ANTLR parser, get the parse tree and validate it programmatically. We may want to use such piece of code from Typescript and Java, so we have to use ANTLR Kotlin + Kotlin multiplatform code. In this scenario we want the code to be convenient to use from Java.

Does this make sense? Sorry if the explanation sounds confused, it has been a long day so far

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants