亲切的问候。
我在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文件中的其他内容吗?
我试图做一个非常简单,功能齐全的例子来理解它。
谢谢你的时间。
当你的解析器需要知道下一个输入符号(“token”)是什么时,它会调用yyLexer
的Lex
方法。您的实现不会尝试读取令牌。相反,它只返回0:
func (f *mlex) Lex(lval *yySymType) int {
yyErrorVerbose = true
return 0
}
因此,从解析器的角度来看,它被赋予一个空的输入流,无论您实际提供什么输入。然后它尝试解析这个空输入,但你的语法不允许它。唯一有效的输入以令牌DB
或OTHER_DB
开头,并且它没有看到这些东西。
因此它会生成错误消息,详细说明其问题所在。 (解析器使用内部伪令牌$end
表示输入的结尾,以防您感到困惑。)