【发布时间】:2019-10-17 19:20:33
【问题描述】:
我很难理解如何使用此 SQL 语法从解析器解析下面提供的 SQL 语句。我被困在 WHERE 令牌之后发现的“表参考”和“加入”构造。
BNF:http://www.contrib.andrew.cmu.edu/~shadow/sql/sql2bnf.aug92.txt
<table reference> ::=
<table name> [ <correlation specification> ]
| <derived table> <correlation specification>
| <joined table>
<joined table> ::=
<cross join>
| <qualified join>
| <left paren> <joined table> <right paren>
<cross join> ::=
<table reference> CROSS JOIN <table reference>
<qualified join> ::=
<table reference> [ NATURAL ] [ <join type> ] JOIN <table reference> [ <join specification> ]
<join type> ::=
INNER
| <outer join type> [ OUTER ]
| UNION
<outer join type> ::= LEFT | RIGHT | FULL
<join specification> ::= <join condition> | <named columns join>
<join condition> ::= ON <search condition>
<named columns join> ::= USING <left paren> <join column list> <right paren>
SQL:
SELECT p.Name, v.Name
FROM Production.Product p
JOIN Purchasing.ProductVendor pv
ON p.ProductID = pv.ProductID
JOIN Purchasing.Vendor v
ON pv.BusinessEntityID = v.BusinessEntityID
WHERE ProductSubcategoryID = 15
ORDER BY v.Name;
跳转到 FROM 子句。这里有一个 TableName,后面跟着两个 JOIN。
如果您查看“表参考”,您会看到其中包含“表名称”。这个我能理解。
<table reference> ::=
**<table name> [ <correlation specification> ]**
| <derived table> <correlation specification>
| <joined table>
但是要获得连接,解析器必须到达它不能到达的“连接表”,因为它已经准备好读取“表名”。
要达到连接,解析器必须达到“合格连接”,但它不能,因为 BNF 中没有重复。如果它以某种方式到达“连接表”元素,那么如果它会非常失望,因为下一次读取将再次是“表引用”,然后它会再次到达“合格连接”,然后......然后你会得到一个堆栈溢出。
<joined table> ::=
<cross join>
| <**qualified join>**
| <left paren> <joined table> <right paren>
**<qualified join>** ::=
<table reference> [ NATURAL ] [ <join type> ] JOIN <table reference> [ <join specification> ]
我在这里没有得到什么?我敢肯定它有一个技巧,但我只是没有看到它。
我希望你们中的一些人可以向我解释这对我来说不可能的语法是怎么回事。
如何构造一个比方说递归下降解析器来解决这个语法?
解析器需要遵循哪些步骤和/或规则?
【问题讨论】:
-
我对你在做什么不是很熟悉,但是......我正在阅读的是
<table name>表示其中只有一个一个表的查询,而<joined table>表示其中包含连接表的查询。但是你如何应用逻辑来事先识别这一点我不确定。 -
没错。您如何告诉递归体面的 paser 选择正确的路径?我的另一个问题是 BNF 如何支持嵌套连接?正确的解释可能很简单。
-
你为什么认为语法必须可以用递归下降解析器解析?
-
我不知道是否可以使用递归的体面解析器解析此语法?我自己正在尝试用这样的解析器来实现它。
-
我不太明白:这是您试图理解的经过验证的解析器,还是您自己构建解析器?换句话说,解决方案是更好地理解 BNF,还是解决方案是对 BNF 的更改,还是别的什么? @rici 提出了一个很好的观点——我认为你不能用串行方法解析 SQL,你可能需要从高层次识别组件并深入研究这些部分