Для собственных интересов я пишу ANSI SQL Lexer. В частности, я пытаюсь соответствовать ISO / IEC 9075-2: 2003 (E). Я столкнулся с проблемой на стадии токена с некоторой двусмысленностью.
Секция лексических элементов определяет интервальную строку следующим образом:
<interval string> ::= <quote> <unquoted interval string> <quote>
<unquoted interval string> ::= [ <sign> ] { <year-month literal> | <day-time literal> }
<year-month literal> ::= <years value> [ <minus sign> <months value> ] | <months value>
<years value> ::= <datetime value>
<months value> ::= <datetime value>
<datetime value> ::= <unsigned integer>
<unsigned integer> ::= <digit>...
<digit> ::= 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9
Пример:
'30'
Это 30 лет <значение года> без опции
или это <значение месяца>?
Теоретически я мог бы написать:
ВЫБЕРИТЕ «30»
Я создал токен YearsValue и токен MonthsValue (классы). Тем не менее, неоднозначность является проблемой, она соответствует обоим. Я не вижу ничего конкретно касающегося нескольких совпадений в части 1 или части 2 ИСО / МЭК 9075.
Может ли кто-нибудь указать, где в спецификации это обрабатывается или это просто предполагается слева направо?
Прежде чем кто-либо спросит, я делаю это, потому что хочу написать лексер SQL. Это не для школы, это просто кое-что, чтобы обучить меня. Я тоже не хочу использовать GOLD или ANTLR.