Looking for best practice for support for code completition in partial input

28 views
Skip to first unread message

Balázs Vissy

unread,
Mar 24, 2025, 10:55:58 AMMar 24
to antlr-discussion
Hi everyone!

I am working a very simple language implementation (mostly expressions) and integrating it to monaco editor.
There are a huge amount of examples about defining a language or on evaluating it.
However, after a week of info digging, I am still stuck how to (1) give more meaningful error messages and (2) detect context at caret position.

Let's see what I am looking for:

Error messages:
My main problem is that the parser returns meaningless (for users) "No viable alternative..." for partial expressions. Also, there is no normal entries in AST for these expressions.

Let's see an example:

My language contains an if expression (like in Kotlin):

ifExpression
: IF NL* condition NL* trueStatement (NL* ELSE NL* falseStatement )? 

This is correct, but when -- for example the trueStatement is missing: `if (x < 2) else 42` it gives the no viable error which is not too user frindly. My idea was to  use validator evaluator (visitor pattern, as it already is used to detect semantic problems) and handle partial if statement by checking the children. However, as it doesn't match the rule, there is no visitor call. Also I find that I could define rule for partial expression:

ifExpression
: IF NL* condition NL* trueStatement (NL* ELSE NL* falseStatement )? # completeIfExpression
| IF NL* condition? NL* trueStatement? ELSE? falseStatement? # errPartialIfExpression
;

Then I could handle this case nicely, but it would polute both my grammar and my visitor (the runtime, real evaluator visitor should throw error if this rule applied). So this works, but not nice. Also, it only handles the problem of if, so I may have to polute the grammar greatly to support other position.

Context detection for context sensitive autocomplete
The same problem appears when I would like to add intelligent suggestions. For this, what I need is to parse the script only until the caret and check what the next token could be and (for example) if it is a identifier, then list the available ones. The listing part is ok, but my problem the same: partial expressions doesn't parsed into the AST.

For example, when I open the condition parenthesis ( `if (` ), I would like to detect that the next token could be an identifier, and offer the options. However, as an unclosed paren is not viable condition, so it is not parsed as a partial condition. There are several other (operators, function arguments, assignment, etc.) where identifiers used, but the expression is partial before specifying one. 

So, what I am looking for is some help pointing me toward examples and detailed info about how to do it correctly. I tried to do it with special evaluator, error listener, etc, but failed to find a solution.

Any idea or hint is welcome, examples are even more welcome! Thank you!

(BTW: I use this in a typescript environment based on the antlr-ng as builder and antlr4ng as frontend lib.)

Balage

Mike Lischke

unread,
Mar 24, 2025, 2:05:24 PMMar 24
to antlr-di...@googlegroups.com
Hi Balage

You might find https://github.com/mike-lischke/antlr4-c3 useful for that kind of processing.

--
You received this message because you are subscribed to the Google Groups "antlr-discussion" group.
To unsubscribe from this group and stop receiving emails from it, send an email to antlr-discussi...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/antlr-discussion/ff9eff91-999e-4612-8510-22ac8b57da2dn%40googlegroups.com.


Reply all
Reply to author
Forward
0 new messages