2016-11-06 39 views
0

我很努力地理解这个SQL语法如何用来解析下面从解析器提供的SQL语句。我被困在WHERE标记之后的'Table reference'和'join'构造中。Stuck在连接子句中解析SQL Select语句(包括BNF语法)

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 caluse。这里有一个TableName,后面跟着两个JOIN。

如果你看'表引用',那么你会发现它包含'表名'。这我可以理解。

<table reference> ::= 
     **<table name> [ <correlation specification> ]** 
    | <derived table> <correlation specification> 
    | <joined table> 

但要获得参加解析器必须达到“加盟表”,它不能因为这一切准备好读“表名”。

要到达连接,解析器必须达到'合格连接',但它不能因为BNF中没有重复。如果它以某种方式到达'Join table'元素,那么如果再次读取'Table reference',然后再次到达'Qualifed join',那么将会非常失望,并且....然后你会发生堆栈溢出。

<joined table> ::= 
     <cross join> 
    | <**qualified join>** 
    | <left paren> <joined table> <right paren> 

**<qualified join>** ::= 
     <table reference> [ NATURAL ] [ <join type> ] JOIN <table reference> [ <join specification> ] 

我不在这里?我确信有一个窍门,但我只是没有看到它。

我希望你们的一些杰出人物能向我解释这件事对我来说是怎样的语法。

如何构建一个让我们说一个递归体面的解析器来解决这个语法?

解析器需要遵循哪些步骤和/或规则?

最好的问候, 布赖恩·安德森

+0

我不是很熟悉你在做什么,但是我正在阅读的是'

'代表一个查询,其中只有一个_表,而<<连接表>代表一个查询在其中加入表格。但是,如何预先应用逻辑来识别这一点,我不确定。 –

+0

准确。你如何告诉recursiv体面的paser选择正确的路径?对我来说另一个问题是BNF如何支持嵌套连接?正确的解释可能很简单。 –

+0

为什么你认为语法必须可以用递归下降解析器进行解析? – rici

回答

1

即语法不是LL(1),这是你需要建立一个递归下降解析器什么。我怀疑SQL是否有LL(1)语法,特别是如果有一个语法可以生成正确的分析树。幸运的是,这并不重要,因为有更强大的解析技术。

很可能您可以使用该语法使用像bison/yacc这样的工具来构建LALR(1)解析器。或者参见sqlite source code,其中包括称为“lemon”的LALR(1)语法和LALR(1)解析器生成器。

+0

谢谢。这正是我需要的信息。我认为我需要将我的知识延伸到RDP/LL(1)之外。我会阅读解析器,我会检查你的链接。 –

+0

你知道把LALR(1)BNF转换成LL(1)BNF的技巧吗? –

+1

@brian通常,这种转换是不可能的,因为LR语法集是LL语法的严格超集。有一些可以尝试的机械转换,但它们在玩具语法上比在SQL等现实生活中遇到的问题更好。即使它们生成的LL语法不能保证,分析树也不会被保留下来,所以你最终会遇到一个不同的问题。最好的技巧,恕我直言,是找到一个解析器生成器,与您的编码语言一起工作,并学习如何使用它。 – rici