An alternative to extending enums?

Hi all. A bit of a crystal newb here. I’ve ported a Java pratt parser to crystal (GitHub - gundy818/pratt: Pratt parser implementation in Crystal), and the token type is declared as an enum (as it was in java). But I’d like the token type to be re-definable by a user of this library, so that when using it to parse an arbitrary language you have the ability to redefine the token types. I tried to subclass the enum (enum NewType < Pratt::TokenType::Type), but that wasn’t allowed.

My first thought was to convert the enum to a class, but enum seems to fit well. I’m wondering what would be the best approach to this in crystal?

Thanks for any help! I’m really loving crystal, and am starting to use it for everything. I’m very open to suggestions to improve other parts of the above code too. My porting method was to rename the .java files to .cr and fix errors until it compiled. So it’s still very ‘java-y’.

Thanks!

1 Like

Related: Reopening Enums · Issue #7629 · crystal-lang/crystal · GitHub and Support inheriting enums · Issue #7632 · crystal-lang/crystal · GitHub.

As a workaround, can you just declare a different enum type if you want to extend the token types? Shared members could be provided by a macro, for example.

enum MyTokenType
  {{ Prat::TokenType::Type.constants.join(";").id }}
  ADDITIONAL_TOKEN
  ANOTHER_TOKEN
end

Is this extension of token types implemented in Java as well? If so, how? You can’t reopen enums in Java either.

2 Likes

Make the parser generic, like Parser(TokenType)