Happy & Alex - Предотвращение негативного влияния на общение анализатора и лексера
В настоящее время я пишу парсер для компилятора игрушечного языка, используя Happy & Alex. Так как требуется некоторая форма необязательного макета, я должен изменить состояние Алекса перед соответствием block
не-терминал. К сожалению, похоже, что токен предпросмотра, требуемый Happy, читается до того, как у меня появляется возможность изменить состояние Алекса.
Вот небольшой фрагмент, демонстрирующий проблему:
funcDef : header localDefs block
^ I have to change alex's state
before the underlying lexer
starts reading the block tokens.
Есть ли общий подход к этой проблеме?
1 ответ
Я предполагаю, что вы используете многопоточный лексер (так что Happy и Алекс работают в одной и той же монаде). Уловка, которую я использовал, сталкиваясь с подобной проблемой, заключается в создании пустого производственного правила, которое вы добавляете в свое правило.
changeAlexState :: { () }
: {- empty -} {%% \tok -> changeAlexState *> pushTok tok }
funcDef : header localDefs changeAlexState block
Затем вам нужно добавить в свою монаду какое-то состояние для поддержки pushTok :: Token -> P ()
(где P
ваша лексическая / разборчивая монада) и убедитесь, что вы всегда вставляете этот токен, когда лексизируете. Какие %%
делает задокументировано здесь.
n : t_1 ... t_n {%% <expr> }
... Тип
<expr>
то же самое [до сих порToken -> P a
], но в этом случае токен предпросмотра фактически отбрасывается, и новый токен считывается из входных данных. Это может быть полезно, когда вы хотите изменить следующий токен и продолжить анализ.
Я упоминал, что сделал нечто подобное не так давно. Вот мое "пустое" правило, вот пример его использования, здесь определена моя функция нажатия, и здесь я " выталкиваю " токены. Дайте мне знать, как это происходит!