Автор выбрал запутанный пример. Если вы поделитесь источником, где вы взяли этот пример, я мог бы дать лучший ответ, но я бы сказал, что в этом случае нет практической двусмысленности. Если вы видите Aa
, вы можете знать, что первая лексема должна быть «Aa», потому что ничто в алфавите не начинается с «a».
Для более простого примера рассмотрим алфавит {A, a, Aa} и строку «AAaAaaA»
Вы можете сделать это следующим образом:
(A) (A) (a) (A) (a) (a) (A)
(A) (Aa) (A) (a) (a) (A)
(A) (A) (a) (Aa) (a) (A)
(A) (Aa) (Aa) (A)
Чаще всего это решается выбором самой длинной лексемы, которая соответствует в каждом случае, что дало бы последний токенизацию.
Теперь давайте вернемся к вашему примеру, но давайте немного изменим строку: «AababAe».
Вы можете токенизировать строку следующими способами:
(Aa) (bab) (A) <error>
(A) <error>
В одной ветке у вас ошибка. В одной ветке вы этого не сделаете. Как вы заметили, токенизатор должен выбрать первый. Оба имеют ошибки, хотя. Дело в том, что здесь есть явный выбор, чтобы предпочесть самый длинный допустимый токенизация. Ничто в алфавите не заставляет вас делать этот выбор. Это также верно, чтобы выбрать самый короткий вариант соответствия. Это было бы непрактично, но это правильный выбор.