Я изо всех сил пытаюсь понять, как эта грамматика SQL когда-либо может использоваться для разрешения приведенной ниже инструкции SQL из анализатора. Я застрял в «Табличной ссылке» и «Присоединиться» к строительству, найденному после того, как маркер WHERE.Застрял разбор SQL Выбор предложения в предложении join (включенная грамматика 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;
Перейти к ИЗ caluse. Здесь у вас есть одно TableName, за которым следуют два JOIN.
Если вы посмотрите на ссылку «Таблица», вы увидите, что это содержит «Имя таблицы». Это я могу понять.
<table reference> ::=
**<table name> [ <correlation specification> ]**
| <derived table> <correlation specification>
| <joined table>
Но чтобы получить присоединиться к анализатору должен достичь «присоединяемой таблицы», который он не может, потому что все готово прочитать «имя таблицы».
Для достижения согласования парсер должен достичь «Квалифицированного соединения», но это невозможно, потому что в BNF нет повторений. Если он каким-то образом достигнет элемента «Join table», то если бы он был очень разочарован, потому что следующее чтение будет снова «ссылкой на таблицу», а затем оно снова достигнет «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> ]
Что я не получу здесь? Я уверен, что есть трюк, но я просто этого не вижу.
Надеюсь, что некоторые из ваших блестящих парней могут объяснить мне, что происходит с этим для меня невозможным грамматикой.
Как можно построить рекурсивный достойный парсер для решения этой грамматики?
Какие шаги и/или правила должен выполнять парсер?
С наилучшими пожеланиями, Брайан Андерсен
Я не очень хорошо знаком с тем, что вы делаете, но ... то, что я читаю, состоит в том, что '
Точно. Как вы говорите рекурсивному порядочному paser, чтобы выбрать правильный путь? Другая проблема для меня также в том, как BNF поддерживает вложенные соединения? Вероятно, это просто с правильным объяснением. –
Почему вы считаете, что грамматика должна быть проанализирована с помощью рекурсивного парсера спуска? – rici
ответ
что грамматика не LL (1), которая является то, что вам нужно построить рекурсивного спуска парсер. Я сомневаюсь, что для SQL существует грамматика LL (1), и особенно если она есть, которая может генерировать правильное дерево разбора. К счастью, это не имеет значения, поскольку существуют более мощные технологии синтаксического анализа.
Скорее всего, вы можете использовать эту грамматику для создания парсера LALR (1) с помощью инструмента, такого как bison/yacc. Или посмотрите на sqlite source code, который включает в себя как грамматику LALR (1), так и генератор парсер LALR (1) под названием «лимон».
источник
2016-11-07 01:47:14 rici
Спасибо. Это именно то, что мне нужно. Я думаю, мне нужно расширить свои знания за пределами RDP/LL (1). Я буду читать на парсерах, и я проверю вашу ссылку. –
Ты знаешь об трюке, чтобы преобразовать LALR (1) BNF в LL (1) BNF? –
@brian В общем, преобразование невозможно, потому что множество LR-грамматик является строгим надмножеством грамматик LL. Есть некоторые механические преобразования, которые можно попробовать, но они лучше работают на игрушечных грамматиках, чем реальные проблемы, такие как SQL. Даже если они производят грамматику LL, что не гарантируется, дерево разбора не сохраняется, поэтому у вас возникает другая проблема. Лучший трюк, IMHO, - найти генератор парсера, который работает с вашим языком кодирования, и научиться его использовать. – rici
Смежные вопросы