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 ], но в этом случае токен предпросмотра фактически отбрасывается, и новый токен считывается из входных данных. Это может быть полезно, когда вы хотите изменить следующий токен и продолжить анализ.

Я упоминал, что сделал нечто подобное не так давно. Вот мое "пустое" правило, вот пример его использования, здесь определена моя функция нажатия, и здесь я " выталкиваю " токены. Дайте мне знать, как это происходит!

Другие вопросы по тегам