Позиция отслеживания при сканировании токенов усложняет Parser

Я пишу парсер с двумя проходами, где сначала просматриваю текст в токенах (используя Alex), затем анализирую эти токены (используя Parsec). Все хорошо и хорошо, пока я не попытался добавить информацию о позиции в токены, чтобы я мог написать хорошее сообщение об ошибке.

Первоначально у меня было:

data Token = TAtom | TString String | TInt Integer | TFloat [...]

Кажется, я могу добавить элемент Position к каждому конструктору Token или создать новый тип, например data TokenWithPosition = T Token Position.

Я начал последний путь, но теперь у меня возникла проблема либо создать TokenWithPosition с поддельной позицией, когда я хочу описать токен в Parsec, либо мне нужно развернуть TokenWithPosition каждый Я хочу провести сравнение. Короче говоря, моя хорошая чистая грамматика переполнена кодом, необходимым для игнорирования информации о местоположении.

Итак, мой вопрос: есть ли чистый способ отслеживать информацию о местоположении без усложнения анализатора во втором проходе? Это похоже на то, что будет иметь стандартное решение.

Ответ 1

Вам нужно использовать функции из Text.Parsec.Prim (например, tokenPrim) для реализации ваших собственных "примитивных парсеров".

Эти примитивные парсеры будут обновлять внутреннее состояние Parsec с информацией о местоположении и возвращать чистый Token без позиции.