2013-03-05 2 views
3

Я пишу некоторые программы в Haskell, которые определенным образом управляют исходным кодом Haskell. Одна из вещей, которые я хотел бы сделать, - это извлечь все вхождения определенного типа (и, возможно, их позиции).Извлечь все вхождения определенного типа в Haskell

Я понял, что очень грубый метод с использованием регулярных выражений будет работать для простых типов данных. Например, в следующем графическом коде:

module Test where 
    import Picture 

    r1,r2,r3,r4 :: Region 
    r1 = Shape(Rectangle 2 2) 
    r2 = Shape(Ellipse 2 1.5) 
    r3 = Shape(RtTriangle 3 2) 
    r4 = Shape(Polygon [(-2.5, 2.5), (-3.0,0), (-1.7,-1.0), (-1.1,0.2),(-1.5,2.0)]) 

    p1,p2,p3,p4 :: Picture 
    p1 = Region Red r1 
    p2 = Region Green r2 
    p3 = Region Blue r3 
    p4 = Region Yellow r4 

    pic :: Picture 
    pic = foldl Over EmptyPic [p1,p2,p3,p4] 

я мог бы извлечь каждый номер, просто создавая регулярное выражение, которое выглядит для каждого экземпляра цифровых символов без каких-либо букв, окружающих их. Аналогично Если бы я хотел, чтобы найти все цвета, я мог бы жестко закодировать регулярное выражение, которое ищет для вхождения красного или зеленого или синего цвета ... и т.д.

Проблемы, как я вижу его с помощью этого метода являются:

  1. Если я когда-нибудь хочу, чтобы изменить тип я ищу, я должен жестко закодировать каждый возможный путь, что тип может проявляться

  2. Это не работает, если значение типа возвращается как результат вызов функции. Например, если p1 вместо чтения:

    p1 = область (GetColor 1) г1

где:

getColor :: Int -> Color 
getColor n 
    |n == 1 = Red 
    |otherwise = Green 

Есть более общий способ разбора файла Haskell так, чтобы извлекать все вхождения определенного типа и, если возможно, их позиции в тексте исходного файла?

+1

Я уверен, что вы можете что-то сделать с http://hackage.haskell.org/package/haskell-src – Bergi

+0

@Bergi Итак, похоже, что эта библиотека позволит мне преобразовать исходный код в абстрактное синтаксическое дерево, который я мог бы затем искать вхождениях определенного типа. Кажется, что не существует какого-либо способа сопоставления между структурой исходного текста и структурой AST (что мне нужно было бы узнать, где * каждое происхождение типа действительно было в источнике). Есть ли способ сохранить хотя бы номера строк или что-то еще? –

ответ

7

Вы можете использовать синтаксический анализатор, а именно haskell-src-exts, который сохраняет информацию о местоположении (номера строк и столбцов) в выходе AST.

+0

Это полезно, но из того, что я вижу, использование функции синтаксического анализа, например parseModule из haskell-src-ext, дает только минимальную информацию об источнике (т. Е. Номера строк и столбцов определений функций и определений типов функций. конструкторы или значения, упомянутые в функции. Я что-то упустил/Есть ли способ расширить это немного дальше, чтобы делать то, что я хочу? –

+0

> Он не дает информации о конструкторах или значениях, упомянутых выше - вы ищете статический анализ , который вам нужно будет делать/после/синтаксический анализ. Для этого нет библиотек, кроме того, что вы управляете АСТ, возвращаемым парсером. –

Смежные вопросы