Где мне провести черту между лексером и парсером?

Я пишу лексер для протокола 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? Или формальный синтаксис никогда не допускает возникновения такой двусмысленности?

11
задан duck9 19 March 2011 в 13:03
поделиться