I am trying to create a parser using golang's yacc tool. I found nex to simplify creating a lexer to give the parser. My problem now is that the generated parser has no method or field to give me access to the parsing result. I could just store the parse result in a global variable, but that seems wrong.
Currently I've added the following as an initial attempt to the top of my parser.y file:
type ResultParser interface {
yyParser // Generated parser interface
Result() s.Expr // s.Expr is an interface for the parsed result
}
func (p *yyParserImpl) Result() s.Expr {
return p.stack[1].expr
}
func NewResultParser() ResultParser {
return &yyParserImpl{}
}
Is there a recomended/better way of getting at the result from the parser?
(Since this feels like a bit of an abuse of the generator...)
No, accessing stack[1]
does not work reliably. It doesn’t contain any result as soon as the stack needs to grow beyond 16, its initial size. (See #16163.)
The if
statement after the yystack
label then creates a new stack and totally forgets about the one saved in yyParserImpl
.
I did the following.
Add a result
field to the lexer type:
type ShellLexer struct {
/* … */
result *ShellProgram
}
Extend the grammar by the following rule at the very beginning:
start : program {
shyylex.(*ShellLexer).result = $$
}
(This depends on the parameter name of the Parse
method (which can have a custom prefix), but I think that’s ok.)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With