Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing result of a golang yacc generated parser

Tags:

parsing

go

yacc

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...)

like image 643
Emil H Avatar asked Apr 24 '16 11:04

Emil H


1 Answers

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.)

like image 193
Roland Illig Avatar answered Sep 28 '22 11:09

Roland Illig