这种语法有歧义,还是图书馆的错?
Is this grammar ambiguous, or is it the library's fault?
我正在使用 rust-peg parsing expression grammar library, but the principles should be generally understandable. I'm using the library to create a parser for go based on the spec。我在获取要解析的 if 语句时遇到问题,我已将问题提炼为一个简单的示例。
sep
= ( " " / "\n" )*
expression
= "x" sep block
/ "x"
if_stmt
= "if" sep expression sep block
block
= "{" ( sep stmt )* "}"
stmt
= if_stmt
/ expression
pub file
= ( sep stmt )*
这个语法应该(在我看来)解析一种非常简单的语言,它包含两种类型的语句:If 语句和表达式语句。表达式可以是 x
,或 x
后跟一个块。 if 语句是 if
后跟一个表达式,再后跟一个块。这是我的语法无法解析的示例输入:
x {}
if x {
}
这无法解析,因为 if 语句行中 x
之后的大括号被解释为作为 "x" sep block
规则一部分的块,而不是作为 "x" sep block
规则一部分的块if_stmt
规则。不幸的是,这个解析库不会回溯并尝试在失败时将这部分行重新解析为 if 语句块。我已经意识到,如果我切换 expression
规则的顺序,使其首先尝试解析 "x"
,那么 if 语句就可以正常解析。这确实为行 x {}
带来了问题,因为行开头的 x
只是作为普通的 "x" 进行解析,并且它在尝试解析之前退出表达式规则解析 {}
。
这些限制是否使库无法解析这样的语法?我应该找另一个,还是只写我自己的解析器? (我真的不想那样做)
编辑
我试验了 go 语法,发现将结构文字("x" sep block
示例)放在 if 语句条件中是不合法的。因此,我能够按照 attdona 的建议消除语法歧义。
尝试消除语法歧义:
simple_expr
= "x"
block_expr
= "x" sep block
expression
= simple_expr
/ block_expr
if_stmt
= "if" sep simple_expr sep block
我不知道rust-peg,希望这对解决你的语法解析有帮助。
我正在使用 rust-peg parsing expression grammar library, but the principles should be generally understandable. I'm using the library to create a parser for go based on the spec。我在获取要解析的 if 语句时遇到问题,我已将问题提炼为一个简单的示例。
sep
= ( " " / "\n" )*
expression
= "x" sep block
/ "x"
if_stmt
= "if" sep expression sep block
block
= "{" ( sep stmt )* "}"
stmt
= if_stmt
/ expression
pub file
= ( sep stmt )*
这个语法应该(在我看来)解析一种非常简单的语言,它包含两种类型的语句:If 语句和表达式语句。表达式可以是 x
,或 x
后跟一个块。 if 语句是 if
后跟一个表达式,再后跟一个块。这是我的语法无法解析的示例输入:
x {}
if x {
}
这无法解析,因为 if 语句行中 x
之后的大括号被解释为作为 "x" sep block
规则一部分的块,而不是作为 "x" sep block
规则一部分的块if_stmt
规则。不幸的是,这个解析库不会回溯并尝试在失败时将这部分行重新解析为 if 语句块。我已经意识到,如果我切换 expression
规则的顺序,使其首先尝试解析 "x"
,那么 if 语句就可以正常解析。这确实为行 x {}
带来了问题,因为行开头的 x
只是作为普通的 "x" 进行解析,并且它在尝试解析之前退出表达式规则解析 {}
。
这些限制是否使库无法解析这样的语法?我应该找另一个,还是只写我自己的解析器? (我真的不想那样做)
编辑
我试验了 go 语法,发现将结构文字("x" sep block
示例)放在 if 语句条件中是不合法的。因此,我能够按照 attdona 的建议消除语法歧义。
尝试消除语法歧义:
simple_expr
= "x"
block_expr
= "x" sep block
expression
= simple_expr
/ block_expr
if_stmt
= "if" sep simple_expr sep block
我不知道rust-peg,希望这对解决你的语法解析有帮助。