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

Go target generated parser code does not have any calls to initialize base class parsers #3446

Open
kaby76 opened this issue Dec 30, 2021 · 0 comments

Comments

@kaby76
Copy link
Contributor

kaby76 commented Dec 30, 2021

This is a problem I discovered while porting grammars-v4/sql/plsql to Go (commonly referred to as "Golang" in order to appease web search engines). It appears that the nested struct of a parser base class cannot be initialized. This is a problem because it means you either have to initialize a "base class" in the driver code after creating the parser object, or you create semantic predicate action code to work with a "zero-default" struct.

This is completely different from every other target in how they all work. It also means that have to modify all split grammars that have superClass to either have a special-purpose driver to initialize the code for Go, or I rewrite all the defaults in the base class to "zero-based".


To explain why this is such a problem, one needs to look at the following grammar: grammars-v4/sql/plsql. This is a split grammar (a grammar that is defined with a lexer grammar and a parser grammar in separate .g4 files). The grammar requires several semantic predicates, in both the lexer grammar and the parser grammar. In the parser, _isVersion12 is set to true when the parser is created.

In order to arrive at grammars that can be "used" across different targets, one must move the code in the actions in the grammar into base classes. These are defined for each target, including Go (here). The grammar must then have the "superClass" option present. These are done in the parser and lexer grammars.

Most targets implement the parser and lexer as a class, so implementing a class hierarchy for the parser and lexer can be done natively, and includes class initialization with a constructor.

For Go, there is no class, only struct, and critically, there is no notion of a constructor method, only a "default of zeros" for a struct. This is "solved" by using some standard coding conventions. In this example, it is critical to initialize the base class _isVersion12 to true--for the predicate to work, but it does not do so.

The template defines the struct type here in go.stg. And, it initializes the base Antlr parser field here. But, it does not initialize the "superClass" itself anywhere in the generated code, so _isVersion12 cannot be set to true.

The solution is to either:

  • Rewrite all the base class code in my grammar so that the "zero default" is assumed, e.g., _isVersion12 is renamed to _isNotVersion12 which is by default false, and change all the predicate functions to use this new value.
  • Or, follow the "Init(struct)" protocol for non-pointer structs that many people use. The Init() function could then initialize _isVersion12 to true.
  • Or, follow the "New...()" protocol for a pointer to structs, which is used in the Antlr Go target, but only partially so. I could then provide a function NewPlSqlBaseParser() that initializes _isVersion12 to true.

If the "New()" protocol is chosen, which I recommend, all the struct superclasses must be turned into a pointer to struct rather than a struct. It will require all base classes to follow the convention. Further, the go.stg file would have to perform the initialization of the Antlr base parser class in the "superClass" user code.

In any fix, the instructions for the Go target, offered here, should be updated to describe in detail on how initialization should be implemented. The instructions that are currently there are not that good.

@kaby76 kaby76 changed the title Go runtime and Antlr tool should use/generate nested pointer to structs, not nested structs Go generated parse has no initializers for parsers with a "superClass" Jan 8, 2022
@kaby76 kaby76 changed the title Go generated parse has no initializers for parsers with a "superClass" Go target generated parser code does not have any calls to initialize base class parsers Jan 12, 2022
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

1 participant