Golang中的问题yacc:语法错误:意外的$ end

时间:2019-02-20 05:42:21

标签: go compiler-construction yacc lex

亲切的问候。

我正在用golang学习yacc,并创建了以下文件:

%{

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
}

但是执行它时出现此错误:

  

语法错误:语法错误:意外的$ end,需要DB或OTHER_DB

我一直在使用以下代码测试此yacc文件:

package main

import (
    "fmt"
)

func main() {

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

可能是什么? yacc文件中还需要其他内容吗?

我正在尝试制作一个非常简单,功能齐全的示例,以使其更好地理解。

感谢您的宝贵时间。

1 个答案:

答案 0 :(得分:1)

当解析器需要知道下一个输入符号(“令牌”)是什么时,它将调用yyLexer的{​​{1}}方法。您的实现不会尝试读取令牌。相反,它只返回0:

Lex

因此,从解析器的角度来看,无论您实际上提供了什么输入,都将得到一个空的输入流。然后,它尝试解析此空输入,但是您的语法不允许这样做。唯一有效的输入以令牌func (f *mlex) Lex(lval *yySymType) int { yyErrorVerbose = true return 0 } DB开头,并且看不到其中任何一个。

因此它会产生错误消息,并详细说明问题所在。 (解析器用内部伪令牌OTHER_DB表示输入的结尾,以防使您感到困惑。)