JetBrains / Grammar-Kit

Grammar files support & parser/PSI generation for IntelliJ IDEA
Other
704 stars 126 forks source link

JFlex '%implements' Doesn't Support Implimentations Of Generic Classes #333

Closed FlipperPlz closed 1 year ago

FlipperPlz commented 1 year ago

I am currently working on developing a lexer using JFlex with the help of the Grammarkit IDE plugin. In order to achieve my desired functionality, I need my lexer to extend an interface that has a generic taking its state type.

As per the JFlex documentation, the correct syntax for implementing such an interface is %implements classname<classname1, classname2>. However, it seems that the Gramma-Kit plugin doesn't support this syntax, and highlights the < symbol as an unexpected input. I have tried different workarounds, but none of them seem to work without some compromise in functionality or code quality.

Steps To Reproduce:

  1. Create a new JFlex lexer using the Grammar-Kit IDE plugin.
  2. Add a %implements statement with a generic type parameter, like %implements EnfusionFlexLexer<ParamLexerState> (This is the use in my codebase).

Expected Behavior:

The lexer code should have no syntax errors and generate smoothly

Actual Behavior:

The Grammar-Kit plugin highlights the < symbol as an unexpected input. The lexer still generates fine (tested with Gradle plugin as well as right-click -> Run JFlex Generator).

Workaround:

I was able to create a workaround by creating an interface that extends EnfusionFlexLexer<ParamLexerState> and having my lexer implement that interface. However, I would like to be able to use the correct syntax without a workaround.

Proposed Solution:

It seems that the Grammar-Kit IDE plugin's grammar doesn't have a rule that supports generics in %implements statements. I propose adding a new rule to the grammar that allows for this syntax. Currently the rules for parsing java types is

java_type ::= id ( safe_dot id ) * {pin(".*")=1 methods=[getReferences]}
private safe_dot ::= '.' !'*'
private java_type_list ::= [java_type (',' java_type) *] {pin(".*")=1 recoverWhile=declaration_recover}

Final Notes

I also plan to create a fork of the repository to fix these issues and submit a pull request, but I wanted to bring this issue to your attention first.

Thank you for your attention to this matter.