Что ж, в Haskell есть 2 основных способа разбора чего-либо: комбинаторы разбора или генератор парсеров. Поскольку у вас уже есть BNF, я бы предложил последнее.
Хороший вариант — alex. Парсер GHC IIRC написан с использованием этого, так что вы будете в хорошей компании.
Далее у вас будет большой стек деклараций данных для анализа:
data JavaClass = {
className :: Name,
interfaces :: [Name],
contents :: [ClassContents],
...
}
data ClassContents = M Method
| F Field
| IC InnerClass
и для выражений и всего, что вам нужно. Наконец, вы объедините их во что-то вроде
data TopLevel = JC JavaClass
| WhateverOtherForms
| YouWillParse
Как только вы это сделаете, весь AST будет представлен как один TopLevel
или их список в зависимости от того, сколько классов/файлов вы анализируете.
Чтобы продолжить отсюда, зависит от того, что вы хотите сделать. Существует ряд библиотек, таких как syb
(выбросьте свой шаблон), которые позволяют вам писать очень краткие обходы дерева и модификации. lens
тоже вариант. Как минимум выезд Data.Traversable
и Data.Foldable
.
Чтобы изменить дерево, вы можете сделать что-то простое, например
ignoreInnerClasses :: JavaClass -> JavaClass
ignoreInnerContents c = c{contents = filter isClass $ contents c}
-- ^^^ that is called a record update
where isClass (IC _) = True
isClass _ = False
и тогда вы могли бы использовать что-то вроде syb
для записи
everywhere (mkT ignoreInnerClass) toplevel
который будет проходить все и применять ignoreInnerClass
ко всем JavaClasses
. Это можно сделать и в lens
, и во многих других библиотеках, но syb
очень легко читается.
person
Daniel Gratzer
schedule
10.09.2013
uuagc
препроцессор грамматик атрибутов иhoopl
универсальная библиотека для компонуемой оптимизации на основе решетки фактов. - person nponeccop   schedule 11.09.2013