// rawBlock : openRawBlock content endRawBlock // openRawBlock : OPEN_RAW_BLOCK helperName param* hash? CLOSE_RAW_BLOCK // endRawBlock : OPEN_END_RAW_BLOCK helperName CLOSE_RAW_BLOCK func (p *parser) parseRawBlock() *ast.BlockStatement { // OPEN_RAW_BLOCK tok := p.shift() result := ast.NewBlockStatement(tok.Pos, tok.Line) // helperName param* hash? result.Expression = p.parseExpression(tok) openName := result.Expression.Canonical() // CLOSE_RAW_BLOCK tok = p.shift() if tok.Kind != lexer.TokenCloseRawBlock { errExpected(lexer.TokenCloseRawBlock, tok) } // content // @todo Is content mandatory in a raw block ? content := p.parseContent() program := ast.NewProgram(tok.Pos, tok.Line) program.AddStatement(content) result.Program = program // OPEN_END_RAW_BLOCK tok = p.shift() if tok.Kind != lexer.TokenOpenEndRawBlock { // should never happen as it is caught by lexer errExpected(lexer.TokenOpenEndRawBlock, tok) } // helperName endId := p.parseHelperName() closeName, ok := ast.HelperNameStr(endId) if !ok { errNode(endId, "Erroneous closing expression") } if openName != closeName { errNode(endId, fmt.Sprintf("%s doesn't match %s", openName, closeName)) } // CLOSE_RAW_BLOCK tok = p.shift() if tok.Kind != lexer.TokenCloseRawBlock { errExpected(lexer.TokenCloseRawBlock, tok) } return result }
// helperName param* hash? blockParams? func (p *parser) parseOpenBlockExpression(tok *lexer.Token) (*ast.BlockStatement, []string) { var blockParams []string result := ast.NewBlockStatement(tok.Pos, tok.Line) // helperName param* hash? result.Expression = p.parseExpression(tok) // blockParams? if p.isBlockParams() { blockParams = p.parseBlockParams() } // named returned values return result, blockParams }