0
votes

A cordial greeting.

I'm learning yacc in golang and i created this file:

%{

package main

import (
    "fmt"
)

%}

%union{
    ex string
}

%token <ex> DB OTHER_DB

%% 
query:  other
        |
        db
        ;

db:     DB
        {
            fmt.Printf("\tDB: %s\n", $1 )
        }
        ;

other:  OTHER_DB
        {
            fmt.Printf("\tOTHER_DB: %s\n", $1 )
        }
        ;
%% 

type mlex struct {
    expr   string
    result int
}

func (f *mlex) Lex(lval *yySymType) int {
    yyErrorVerbose = true
    return 0
}

func (f *mlex) Error(s string) {
    fmt.Printf("syntax error: %s\n", s)
}

func Parse(expr string) int {
    m := &mlex{expr, 0}
    yyParse(m)
    return m.result
}

but when executing it I get this error:

syntax error: syntax error: unexpected $end, expecting DB or OTHER_DB

I have been testing this yacc file with this code:

package main

import (
    "fmt"
)

func main() {

    res := Parse("db")
    fmt.Println(res)
}

What could it be ? Will I need anything else in the yacc file?

I am trying to make a very simple, fully functional example to understand it well.

Thanks for your time.

1

1 Answers

1
votes

When your parser needs to know what the next input symbol ("token") is, it calls the yyLexer's Lex method. Your implementation of that makes no attempt to read a token. Instead, it just returns 0:

func (f *mlex) Lex(lval *yySymType) int {
    yyErrorVerbose = true
    return 0
}

So from the parser's perspective, it is being given an empty input stream, regardless of what input you might actually have provided. It then attempts to parse this empty input, but your grammar doesn't permit it. The only valid inputs start with the tokens DB or OTHER_DB, and it doesn't see either of those things.

So it produces the error message, detailing exactly what its problem is. (The parser represents the end of input with the internal pseudo-token $end, in case that was confusing you.)