为什么不简约解析这个?

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_namealias 应该存在。我究竟做错了什么?提前致谢。

你的语法有两个问题:

  1. Parsimonious 不会自动处理白色space,你必须照顾好它们(一些想法可以从https://github.com/erikrose/parsimonious/blob/master/parsimonious/grammar.py#L224中得到)

  2. 如 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+"
    """
)

一切都应该正确解析。