2016-11-06 155 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