-
Notifications
You must be signed in to change notification settings - Fork 3.3k
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
Visitor Pattern in Golang #4395
Comments
Try implementing a dispatch routine. E.g.,
|
Of course. The Antlr Visitor code doesn't work. Likely for Listeners as well. But, you asked: "Anyone [have] any idea how the visitor pattern should work in Go?". I am just saying, that if you are trying to get something to work now, then you might want to give that a try. |
I think an end-to-end example of a Visitor is in order. The doc only shows a Listener. Both are needed. I could not get Antlr Visitors to work unless I do the following:
Also, in the example in the doc for the listener, the struct type declares the base as pointer. Line 244 in a27cf84
VisitProg() must still be defined. |
I use both. I have not had time to look at what is happening here, but you
don’t need to implement all funcs. Just the ones you need.
I do wish to make some improvements to the way variables are accessed. But
I have not had time to do so. It does all work though. If you are new to
go, then it might not be obvious. I should create some example projects to
help.
Jim
…On Mon, Aug 28, 2023 at 09:09 Ken Domino ***@***.***> wrote:
I think an end-to-end example is in order. I could not get Antlr Visitors
to work unless I do the following:
- Define Visitor as you describe:
type Visitor struct {
parser.BaseExprVisitor
}
- Define Visit() as you describe:
func (v *Visitor) Visit(tree antlr.ParseTree) any {
return tree.Accept(v)
}
- Define each and every Visit...() function:
func (v *Visitor) VisitProg(ctx *parser.ProgContext) any {
fmt.Println("VisitProg")
return v.VisitChildren(ctx)
}
func (v *Visitor) VisitDecl(ctx *parser.DeclContext) any {
fmt.Println("VisitDecl")
return v.VisitChildren(ctx)
}
func (v *Visitor) VisitExpr(ctx *parser.ExprContext) any {
fmt.Println("VisitExpr")
return v.VisitChildren(ctx)
}
In other words, the generated Visit...() functions do not work:
func (v *BaseExprVisitor) VisitProg(ctx *ProgContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseExprVisitor) VisitDecl(ctx *DeclContext) interface{} {
return v.VisitChildren(ctx)
}
func (v *BaseExprVisitor) VisitExpr(ctx *ExprContext) interface{} {
return v.VisitChildren(ctx)
}
- Define VisitChildren(), because the default implementation is
"return nil".
func (v *Visitor) VisitChildren(tree antlr.RuleNode) any {
n := tree.GetChildCount()
for i := 0; i < n; i++ {
c := tree.GetChild(i)
val := c.(antlr.ParseTree)
_ = v.Visit(val)
}
return 0
}
Note, this implementation does not "sum" the results of visiting the
children, nor does it "short-circuit" the tree walking.
—
Reply to this email directly, view it on GitHub
<#4395 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAJ7TMFMT5QI2UF2N3SPOGLXXPVTRANCNFSM6AAAAAA37NBKR4>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>
|
The code attached implements a Visitor for the Java and Go targets. I have one for CSharp, but it behaves like the Java target, so I haven't included it. The applications are generated for Windows Msys2. In this example, I define all Visit...() methods/func except ProgVisit(). For Java, the tree walker visits the entire tree, which you can see by the output for DeclVisit() and ExprVisit(). For Go, the visitor does not appear to visit the Expr and Decl nodes because "func ProgVisit()" is commented out. If "func ProgVisit()" is uncommented, I get the output from the ExprVisit() and DeclVisit() funcs. I haven't determined whether it calls the Antlr tool generated func's, but it certainly doesn't call the ones that I define.
Here are the two applications in .zip files. Generated-Java.zip Again, just looking through the Antlr Go runtime, there's no func that defines VisitChildren() that actually traverses all children of a tree node. The only VisitChildren() implementation is the stub implementation in tree.go.
Every other runtime has an implementation somewhere to loop through all children of a parse tree node. I just don't see how this could have ever worked for Go--unless one implements a VisitChildren(). as I have done
|
That function is essentially the code that you gave above!
But, besides, the implementation I made is equivalent to the "base class" implementation except for the function receiver. antlr4/runtime/Go/antlr/v4/tree.go Line 61 in a27cf84
Doing what you suggest--commenting out the Visit() implementation in Test.go that I made--does not work either. It's moot anyway because the overarching fact remains: VisitChildren() is unimplemented, yet the Antlr tool generates code with VisitChildren() function calls. The Visitor code can only work with all the func's implemented as I mentioned above. |
I really don't know what you are referring to. What is "it" in "It's a bug!"?? So as to be clear, I've checked in all the generated driver code here, https://github.com/kaby76/antlr-4395, so you can use Github Permalinks to address what "it" is. Thanks. |
No description provided.
The text was updated successfully, but these errors were encountered: