You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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, _isVersion12is 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.
The text was updated successfully, but these errors were encountered:
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
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
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:
_isVersion12
is renamed to_isNotVersion12
which is by default false, and change all the predicate functions to use this new value._isVersion12
to true._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.
The text was updated successfully, but these errors were encountered: