Я пишу lexer для протокола IMAP для образовательных целей, и я в тупике, где я должен рисовать линию между lexer и parser. Возьмите этот пример ответа сервера IMAP:
* FLAGS (\Answered \Deleted)
Этот ответ определяется в формальном синтаксисе следующим образом:
mailbox-data = "FLAGS" SP flag-list
flag-list = "(" [flag *(SP flag)] ")"
flag = "\Answered" / "\Deleted"
Поскольку они указаны как строковые литералы (иначе говоря, "терминальные" токены), было бы более правильным для lexer испускать уникальный токен для каждого, например:
(TknAnsweredFlag)
(TknSpace)
(TknDeletedFlag)
Или было бы правильно исправить что-то вроде этого:
(TknBackSlash)
(TknString "Answered")
(TknSpace)
(TknBackSlash)
(TknString "Deleted")
Моя путаница в том, что прежний метод мог перекомпилировать lexer - если \Answered
имел два значения в двух разных контекстах, лексер не выдавал бы правильный токен. Как надуманный пример (эта ситуация не будет возникать, потому что адреса электронной почты заключены в кавычки), как лексер справится с адресом электронной почты, например \[email protected]? Или формальный синтаксис, призванный никогда не допускать возникновения такой двусмысленности?