为什么不简约解析这个?
Why doesn't parsimonious parse this?
我似乎完全无法理解为什么无法解析。以下是我的简单语法(只是尝试理解 parsimonious,因此语法可能没有意义)。
from parsimonious.grammar import Grammar
from parsimonious.nodes import NodeVisitor
sql_grammar = Grammar(
"""
select_statement = "SELECT" ("ALL" / "DISTINCT")? object_alias_section
object_alias_section = object_name / alias
object_name = ~"[ 0-9]*"
alias = ~"[ A-Z]*"
"""
)
data = """SELECT A"""
tree = sql_grammar.parse(data)
print("tree:", tree, "\n")
A SELECT 10
解析,但由于某种原因,SELECT A
无法解析。我的理解是 object_name
或 alias
应该存在。我究竟做错了什么?提前致谢。
你的语法有两个问题:
Parsimonious 不会自动处理白色space,你必须照顾好它们(一些想法可以从https://github.com/erikrose/parsimonious/blob/master/parsimonious/grammar.py#L224中得到)
如 README.md /
运算符匹配第一个匹配选项,因此它首先尝试匹配 object_name
。因为有hanging unparsed space,被object_name
匹配,parsing finish。但是即使 space 被正确处理,object_name
也会匹配空字符串并且解析也会以错误结束。
为了修正你的语法,我建议修改如下:
sql_grammar = Grammar(
"""
select_statement = "SELECT" (ws ("ALL" / "DISTINCT"))? ws object_alias_section
object_alias_section = object_name / alias
object_name = ~"[ 0-9]+"
alias = ~"[ A-Z]+"
ws = ~"\s+"
"""
)
一切都应该正确解析。
我似乎完全无法理解为什么无法解析。以下是我的简单语法(只是尝试理解 parsimonious,因此语法可能没有意义)。
from parsimonious.grammar import Grammar
from parsimonious.nodes import NodeVisitor
sql_grammar = Grammar(
"""
select_statement = "SELECT" ("ALL" / "DISTINCT")? object_alias_section
object_alias_section = object_name / alias
object_name = ~"[ 0-9]*"
alias = ~"[ A-Z]*"
"""
)
data = """SELECT A"""
tree = sql_grammar.parse(data)
print("tree:", tree, "\n")
A SELECT 10
解析,但由于某种原因,SELECT A
无法解析。我的理解是 object_name
或 alias
应该存在。我究竟做错了什么?提前致谢。
你的语法有两个问题:
Parsimonious 不会自动处理白色space,你必须照顾好它们(一些想法可以从https://github.com/erikrose/parsimonious/blob/master/parsimonious/grammar.py#L224中得到)
如 README.md
/
运算符匹配第一个匹配选项,因此它首先尝试匹配object_name
。因为有hanging unparsed space,被object_name
匹配,parsing finish。但是即使 space 被正确处理,object_name
也会匹配空字符串并且解析也会以错误结束。
为了修正你的语法,我建议修改如下:
sql_grammar = Grammar(
"""
select_statement = "SELECT" (ws ("ALL" / "DISTINCT"))? ws object_alias_section
object_alias_section = object_name / alias
object_name = ~"[ 0-9]+"
alias = ~"[ A-Z]+"
ws = ~"\s+"
"""
)
一切都应该正确解析。