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