) позволяет смешивать лексинг и разбор. Таким образом, вам вообще не понадобятся токены.
у лексер для протокола 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")
Я путаюсь в том, что первый метод может усложнить лексер - если\Answered
имел два значения в двух разных контекстах, лексер не испустил бы правильный токен. В качестве надуманного примера (такой ситуации не будет, потому что адреса электронной почты заключены в кавычки), как лексер будет иметь дело с адресом электронной почты, таким как \ [email protected]? Или формальный синтаксис предназначен для того, чтобы никогда не допустить возникновения такой неоднозначности?