"panic: unexpected token XXX" 的 golang 分词恐慌
golang participle panic with "panic: unexpected token XXX"
正在学习participle,一个基于golang的解析器。完成教程后,我决定创建一个简单的数组解析器,这是我的构造。
首先,我需要一个 AST 来表示这个数组。为了简单起见,我只解析不带引号的字符串数组。 ({value1, value_two, value_3_here}
, e.t.)
type SimpleArray struct {
Arr []Values `"{" @@* "}"`
}
type Values struct {
Str string `@Ident`
}
现在我为输入字符串创建一个词法分析器
var Lexer = stateful.MustSimple([]stateful.Rule{
{`Ident`, `[a-zA-Z][a-zA-Z_\d]*`, nil},
{`punct`, `[}{,]`, nil},
{`whitespace`, `\s+`, nil},
})
下面是我的主要功能,带有一个简单的测试用例s := "{key, value}"
func main() {
var parser = participle.MustBuild(&SimpleArray{},
participle.Lexer(Lexer),
)
b := &SimpleArray{}
s := "{key, value}"
err := parser.ParseString("", s, b)
if err != nil {panic(err)}
repr.Println(b, repr.Indent(" "), repr.OmitEmpty(true))
}
但是我很恐慌。
panic: 1:2: unexpected token "key"
我认为 Values
结构中的 @Ident
会捕获“键”,但它不是,为什么呢?我该如何解决这个问题?
谢谢!
我发现有两个问题,第一个是规则定义语法错误,第二个是规则本身的错误。
解析器无法解析任何内容,因为解析器仍需要获取 {
标记才能开始第一个规则 SimpleArray
。第一个 {
标记没有被词法分析器通过的原因是规则的名称 punct
应该大写 Punct
。小写规则中的标记(如 whitespace
)由词法分析器读取,但不会传递给解析器。
此外,还有一个问题就是无法解析逗号。您需要修改规则以允许具有分隔逗号的其他项目。
更改以下内容:
type SimpleArray struct {
Arr []Values `"{" @@* "}"`
}
至:
type SimpleArray struct {
Arr []Values `"{" (@@ ("," @@)*)? "}"`
}
新规则解释:
"{"
解析 {
(...)?
使列表成为可选的(如果这是你真正想要的,如果不是删除这部分)
@@ ("," @@)*
递归解析一个或多个项目,以逗号分隔
"}"
解析 }
正在学习participle,一个基于golang的解析器。完成教程后,我决定创建一个简单的数组解析器,这是我的构造。
首先,我需要一个 AST 来表示这个数组。为了简单起见,我只解析不带引号的字符串数组。 ({value1, value_two, value_3_here}
, e.t.)
type SimpleArray struct {
Arr []Values `"{" @@* "}"`
}
type Values struct {
Str string `@Ident`
}
现在我为输入字符串创建一个词法分析器
var Lexer = stateful.MustSimple([]stateful.Rule{
{`Ident`, `[a-zA-Z][a-zA-Z_\d]*`, nil},
{`punct`, `[}{,]`, nil},
{`whitespace`, `\s+`, nil},
})
下面是我的主要功能,带有一个简单的测试用例s := "{key, value}"
func main() {
var parser = participle.MustBuild(&SimpleArray{},
participle.Lexer(Lexer),
)
b := &SimpleArray{}
s := "{key, value}"
err := parser.ParseString("", s, b)
if err != nil {panic(err)}
repr.Println(b, repr.Indent(" "), repr.OmitEmpty(true))
}
但是我很恐慌。
panic: 1:2: unexpected token "key"
我认为 Values
结构中的 @Ident
会捕获“键”,但它不是,为什么呢?我该如何解决这个问题?
谢谢!
我发现有两个问题,第一个是规则定义语法错误,第二个是规则本身的错误。
解析器无法解析任何内容,因为解析器仍需要获取 {
标记才能开始第一个规则 SimpleArray
。第一个 {
标记没有被词法分析器通过的原因是规则的名称 punct
应该大写 Punct
。小写规则中的标记(如 whitespace
)由词法分析器读取,但不会传递给解析器。
此外,还有一个问题就是无法解析逗号。您需要修改规则以允许具有分隔逗号的其他项目。
更改以下内容:
type SimpleArray struct {
Arr []Values `"{" @@* "}"`
}
至:
type SimpleArray struct {
Arr []Values `"{" (@@ ("," @@)*)? "}"`
}
新规则解释:
"{"
解析{
(...)?
使列表成为可选的(如果这是你真正想要的,如果不是删除这部分)@@ ("," @@)*
递归解析一个或多个项目,以逗号分隔"}"
解析}