Access golang yacc generated parsing result

I am trying to create a parser using the golang yacc tool . I found nex to make it easy to create a lexer to give a parser. My problem is that the generated parser has no method or field to give me access to the parsing result. I could just save the result of the analysis in a global variable, but that seems wrong.

Currently, I have added the following as an initial attempt at 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 recommended / best way to get the result from the parser?
(Since this is a bit like generator abuse ...)

+5
source share
2 answers

No, access to stack[1] does not work reliably. It does not contain any result, as soon as the stack should grow above 16, its original size. (See # 16163. )

The if after the yystack label creates a new stack and completely forgets about the one that was saved in yyParserImpl .


I did the following.

Add the result field to the lexer type:

 type ShellLexer struct { /* โ€ฆ */ result *ShellProgram } 

First expand the grammar with the following rule:

 start : program { shyylex.(*ShellLexer).result = $$ } 

(It depends on the parameter name of the Parse method (which may have its own prefix), but I think this is normal.)

+5
source

Alternative solution: use sed to insert an additional field into the generated parser. Then in your grammar action, assign a value.

 go tool yacc -o parser.go -p Filter parser.y sed -i '/type FilterParserImpl struct/a tree *treeNode' parser.go 

Generated Parser:

 type FilterParserImpl struct { tree *treeNode lval FilterSymType stack [FilterInitialStackSize]FilterSymType char int } 

Grammar action:

 filter { Filterrcvr.tree = $1 } 
+1
source

Source: https://habr.com/ru/post/1247809/


All Articles