我正在使用Participle(Golang的软件包)编写用于游戏的解析器/词法分析器。它看起来像Bash命令,但更容易。 (https://github.com/alecthomas/participle)
这是分词用于lex和解析输入的代码。 (它们会在以后进行其他处理。)
type Parsed struct {
Pos lexer.Position
FirstBlock Block ` @@ `
Blocks []*BlockWithDelim ` @@* `
}
type Block struct {
Command string ` @Command `
Flags []*ArgFlag ` @@* `
Arguments []string ` @Argument* `
}
type BlockWithDelim struct {
Delimiter string ` @(";" | "|" | "\n" ) `
Block Block ` @@ `
}
type ArgFlag struct {
Flag string ` "-" "-"? @Flag `
Value *string ` ("=" @Argument)? `
}
var omegaLexer = lexer.Must(ebnf.New(strings.ReplaceAll(`
Command = alpha {alpha} .
Flag = Ident .
Argument = Ident | String | RawString .
String = "\"" { "\u0000"…"\uffff"-"\""-"\\" | "\\" "\u0000"…"\uffff" } "\"" .
RawString = "§" { "\u0000"…"\uffff" - "§" } "§" .
Ident = (alpha | "_" ) { alpha | digit | "_" } .
Comment = "#" { "\u0000"…"\uffff" - "\n" } .
Whitespace = " " | "\t" | "\r" .
alpha = "a"…"z" | "A"…"Z" .
digit = "0"…"9" .
`, "§", "`"))) //replace § with ` to make reading easier, due to no escapes allowed in raw strings
var omegaParser = participle.MustBuild(&Parsed{},
participle.Lexer(omegaLexer),
participle.Unquote("String", "RawString"),
participle.Elide("Whitespace", "Comment"))
问题是,它拒绝检测带有命令参数(带引号的字符串)的命令以外的任何命令。
# This works
echo "quoted string"
# This doesn't
echo hello
# Returns this error:
# <source>:1:6: unexpected token "hello"
此外,它无法识别直接放在struct标记中的字符串。例如:
help -bool
# <source>:1:6: no match found for -
execute once; then -do="thingy"
# <source>:1:13: no match found for ;
我不知道为什么我的代码无法正常工作。我试图尽可能地复制TOML示例。
以下是代码(带有导入和打包的内容):https://pastebin.com/QDLiGmnu