3

하스켈을 다른 언어로 번역하는 라이브러리를 업그레이드 중입니다. 지금은 Meta.Parse을 사용하여 Haskell 모듈을 읽어 들이고 here과 같이 TemplateHaskell AST를 반환합니다.템플릿 Haskell AST의 재 연결하기

제가 파싱을 실행할 때, UInfixE와 UInfixP로 구문 분석 된 일련의 중온 연산자를 얻을 수 있습니다. 즉, 미해결 된 연관성이 있음을 의미합니다.

description of the associativity은 하스켈 컴파일러가 어떻게 이러한 문제를 해결하는지 이야기합니다.

내가 파싱에서 얻은 나무에 대해이 재결합을 수행 할 수있는 기능이 있습니까? 나는 이런 식으로 뭔가를 찾고 있어요 :

reassoc :: [Dec] -> [Dec] 

나는이 작업을 수행 대규모 AST 통과를 쓸 수 있지만,이 보일러 엄청난 양의 것처럼 보인다, 명확하게 기능은 이미 (어떤 형태로 존재 잘하면 TH와 함께 연주하는 형태로).

그런 것이 있습니까? 선언을 파싱하여 얻은 AST에서 해결되지 않은 중위 연산자를 제거하는 쉬운 방법이 있습니까?

편집 : 연산자의 이름이 주어지면 그 우선 순위와 연관성을 부여 할 수있는 함수조차도 매우 유용합니다.

답변

3

그런 함수가 존재하는지 모르겠지만 Scrap Your Boilerplate을 사용하여 직접 작성하여 모든 상용구 코드를 제거 할 수 있습니다. 특히, (선언 하향식 (top-down)을 통과 할 때)마다 UInfixE에 적용됩니다 함수를 작성하는 것은 간단하다

import Language.Haskell.TH 
import Data.Data 
import Data.Generics.Schemes 
import Data.Generics.Aliases 

fixity :: (Data a) 
     => (Exp -> Exp -> Exp -> Exp) --^a function that converts 
             -- UInfixE Exp Exp Exp to another Exp 
     -> a -> a 
fixity f = everywhere' (mkT expf) 
    where 
    expf (UInfixE l o r) = f l o r 
    expf e    = e 

fixityDec, Exp 및 기타 TH 포함 유형 Data을 가지고 아무것도에 적용 할 수 있습니다 데이터 유형.

어쨌든 나무가 모호하고 어쨌든 다시 연관되어야하기 때문에 아마 UInfixE의 순서는 신경 쓰지 않아도됩니다. 이것은 당신이 식을 다시 정리해야 할 어떤 트리 구조 구축 할 수 있도록한다

-- | Converts all `UInfixU` subtrees using given right-folding functions. 
-- 
-- For example if @fixityFold step right [email protected] finds 
-- @1 + 2 * 3/[email protected] somewhere, 
-- the corresponding subtree will be replaced by (abusing the notation) 
-- @result (step '1 '+ (step '2 '* (step '3 '/ (right '4))))@. 
fixityFold :: (Data a) 
      => (Exp -> Exp -> a -> a) 
      -> (Exp -> a) 
      -> (a -> Exp) 
      -> a -> a 
fixityFold step right result = everywhere' (mkT expf) 
    where 
    expf [email protected](UInfixE _ _ _) = result (foldrUInfixE exp right) 
    expf e     = e 
    foldrUInfixE (UInfixE l o r) rf = foldrUInfixE l 
             (\e -> step e o (foldrUInfixE r rf)) 
    foldrUInfixE exp    rf = rf exp 

이 방향으로 조금 더가는, 우리는 그것을 발견 UInfixE의 모든 나무를 통해 폴드 기능을 향상시킬 수 있습니다 적절한 우선 순위를 사용하여