Как правило, вы не хотите, чтобы лексический синтаксис распространялся в грамматике, потому что это просто детали.Например, лексер для языка программирования, такого как C, наверняка распознает числа, но вообще неуместно производить токены HEXNUMBER и DECIMALNUMBER, потому что это не важно для грамматики.
Я думаю, что вы хотитеэто самые абстрактные токены, которые позволяют вашей грамматике различать интересующие вас случаи относительно вашей цели.Вы можете быть посредником в этом путанице, вызванной в одной части грамматики, в выборе, который вы можете сделать в других частях.
Если ваша цель - просто прочитать значения флага, то на самом деле вам не нужночтобы различать их, достаточно использовать TknFlag без связанного содержимого.
Если ваша цель - обрабатывать значения флагов по отдельности, вам необходимо знать, есть ли у вас указания ANSWERED и / или DELETED.Как они пишутся лексически, не имеет значения;так что я бы пошел с вашим решением TknAnsptedFlag.Я бы выбросил TknSpace, потому что в любой последовательности флагов должны быть промежуточные пробелы (ваша спецификация так скажет), поэтому я бы попытался исключить использование любых механизмов подавления пробелов, которые вы предлагаете. Lxer
ИногдаЯ сталкиваюсь с ситуациями, когда существуют десятки подобных флагов.Тогда ваша грамматика начинает загромождаться, если у вас есть токен для каждого.Если грамматике не нужно знать конкретные флаги, то у вас должен быть TknFlag со связанным строковым значением.Если грамматика нуждается в небольшом подмножестве флагов для различения, но большинство из них - нет, то вам следует пойти на компромисс: иметь отдельные токены для тех флагов, которые имеют значение для грамматики, и перехватить весь TknFlag со связанной строкой для остальных.
Что касается сложности наличия двух разных интерпретаций: это один из тех компромиссов.Если у вас есть такая проблема, то ваши токены должны быть достаточно точными в обоих местах, где они нужны в грамматике, чтобы вы могли различать.Если «\» относится к токену где-то еще в грамматике, вы, безусловно, можете создать и TknBackSlash, и TknAnspted.Однако, если способ обработки чего-либо в одной части грамматики отличается от другого, вы часто можете обойти это, используя управляемый режимом лексер.Думайте о модах как о конечном автомате, у каждого из которых есть связанный (суб) лексер.Переходы между режимами инициируются токенами, которые являются сигналами (у вас должен быть токен FLAGS; это точно такой сигнал, что вы собираетесь собирать значения флагов).В режиме вы можете создавать токены, которые другие режимы не производят;таким образом, в одном режиме вы можете создавать жетоны "\", но в режиме вашего флага вам это не нужно.Поддержка режима довольно распространена в лексерах, потому что эта проблема встречается чаще, чем вы могли ожидать.Для примера см. Документацию Flex.
Тот факт, что вы задаете вопрос, показывает, что вы на правильном пути, чтобы сделать правильный выбор.Вам необходимо сбалансировать цель обслуживания по минимизации токенов (технически вы можете анализировать использование токена для любого символа ASCII!) С фундаментальной потребностью достаточно хорошо различать для ваших нужд.После того, как вы построите дюжину грамматик, этот компромисс покажется простым, но я думаю, что предоставленные мною эмпирические правила довольно хороши.