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

问题描述 投票:0回答:1

亲切的问候。

我在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文件中的其他内容吗?

我试图做一个非常简单,功能齐全的例子来理解它。

谢谢你的时间。

go compiler-construction yacc lex
1个回答
1
投票

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

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

因此,从解析器的角度来看,它被赋予一个空的输入流,无论您实际提供什么输入。然后它尝试解析这个空输入,但你的语法不允许它。唯一有效的输入以令牌DBOTHER_DB开头,并且它没有看到这些东西。

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

© www.soinside.com 2019 - 2024. All rights reserved.