Что мне нужно добавить, чтобы использовать monadUserState с alex при разборе?
Я пытаюсь написать программу, которая будет понимать язык, на котором разрешены встроенные комментарии. Такие как:
/* Here's a comment
/* This comment is further embedded */ second comment is closed
Must close first comment */
Это следует признать как комментарий (и как таковой не останавливаться на первом */ он видит, если только он не видел только 1 комментарий, открывающийся ранее).
Это было бы легко исправить в C, я мог бы просто иметь счетчик, который увеличивается, когда он видит, что комментарий открывается, и уменьшается, когда он видит, что комментарий закрывается. Если счетчик равен 0, мы находимся в "разделе кода".
Тем не менее, без государства в Haskell, это немного сложнее.
Я прочитал о monadUserState, который предположительно позволяет отслеживать состояние для этого точного анализа. Тем не менее, я не могу найти много материалов для чтения, кроме как на странице учебника на alex.
Когда я пытаюсь скомпилировать это выдает ошибку
templates\wrappers.hs:213:16: Not in scope: `alexEOF`
Следует отметить, что я напрямую изменил "базовую" оболочку на "monadUserState", не меняя свой код (я не знаю, что добавить, чтобы использовать его). Это говорит о том, что это должно быть инициализировано в коде пользователя:
data AlexState = AlexState {
alex_pos :: !AlexPosn, -- position at current input location
alex_inp :: String, -- the current input
alex_chr :: !Char, -- the character before the input
alex_bytes :: [Byte], -- rest of the bytes for the current char
alex_scd :: !Int, -- the current startcode
alex_ust :: AlexUserState -- AlexUserState will be defined in the user program
}
Я немного неуклюжий новичок, и я совсем не уверен, что мне следует добавить сюда, чтобы он хотя бы компилировался... тогда я могу беспокоиться о логике этого.
1 ответ
Обновление: рабочий пример доступен здесь: http://lpaste.net/119212
Файл "tiger.x" (ссылка) в репозитории alex github содержит пример того, как отслеживать встроенные комментарии с помощью оболочки monadUserState.
Ну, к сожалению, этот пример не компилируется, но идеи должны работать.
По сути, эти строки выполняют встроенную обработку комментариев:
<0> "/*" { enterNewComment `andBegin` state_comment }
<state_comment> "/*" { embedComment }
<state_comment> "*/" { unembedComment }
<state_comment> . ;
<state_comment> \n { skip }
Что касается alexEOF
Идея состоит в том, чтобы добавить токен EOF в тип данных токена:
data Tokens = ... | EOF
и определить alexEOF
как:
alexEOF = return EOF
Посмотрите файл tests/tokens_monadUserState_bytestring.x в репозитории alex для примера этого.