What is the most idiomatic way to get some form of context to the yacc
parser in goyacc
, i.e. emulate the %param
command in traditional yacc
?
I need to parse to my .Parse
function some context (in this case including for instance where to build its parse tree).
The goyacc
.Parse
function is declared
func ($$rcvr *$$ParserImpl) Parse($$lex $$Lexer) int {
Things I've thought of:
$$ParserImpl
cannot be changed by the .y
file, so the obvious solution (to add fields to it) is right out, which is a pity.$$Lexer
is an interface, I could stuff the parser context into the Lexer implementation, then force type convert $$lex
to that implementation (assuming my parser always used the same lexer), but this seems pretty disgusting (for which read non-idiomatic). Moreover there is (seemingly) no way to put a user-generated line at the top of the Parse
function like c := yylex.(*lexer).c
, so in the many tens of places I want to refer to this variable, I have to use the rather ugly form yylex.(*lexer).c
rather than just c
.%param
in normal yacc
/ C (well, bison
anyway), but that doesn't exist in goyacc
..go
file with sed
or perl
for what are hopefully obvious reasons.What's the most idiomatic solution here? I keep thinking I must be missing something simple.
My own solution is to modify goyacc
(see this PR) which adds a %param
directive allowing one or more fields to be added to the $$ParserImpl
structure (accessible as $$rcvr
in code). This seems the most idiomatic route. This permits not only passing context in, but the ability for the user to add additional func()
s using $$ParserImpl
as a receiver.