2014-11-05 1 views
1

소스를 AST로 구문 분석하는 데 많은 Haskell 자습서가 있습니다. AST는 AST 평가를 다시 작성하지만 두 AST 간의 매핑은 작성하지 않습니다. HaskelltransformFoo2Bar을 구현하는 "정식"방법이 있습니까?하스켈에서 AST 변환하기

type FooIdentifier = String 
data Foo = Foo FooIdentifier [FooMethod] deriving (Show) 
data FooMethod = FooMethod FooIdentifier [FooExpression] deriving (Show) 
data FooExpression = FooAB FooIdentifier FooIdentifier | FooZ FooIdentifier deriving (Show) 

type BarIdentifier = String 
type BarLabel = String 
data Bar = Bar BarIdentifier [BarExpression] deriving (Show) 
data BarExpression = BarA BarIdentifier BarIdentifier 
        | BarB BarIdentifier BarIdentifier | BarZ BarIdentifier deriving (Show) 

-- 
-- transformFoo2Bar [Foo "foo" [FooMethod "foo1" [FooAB "a" "b", FooZ "z"], FooMethod "foo2" [FooZ "z"]]] 
--   
-- to evaluate to 
-- 
-- [Bar "foo_foo1" [BarA "a" "b", BarB "a" "b", BarZ "z"], Bar "foo_foo2" [BarZ "z"]] 
-- 

transformFoo2Bar :: [Foo] -> [Bar] 
transformFoo2Bar = undefined 

코드 컴파일과 유사하지만 컴파일 된 코드를 내보내는 대신 결과를 AST로 유지합니다.

또한 이러한 매핑 중 일부를 역 매핑으로 다시 사용할 수 있습니까?

감사

+2

저는 질문을 이해하지 못합니다 : 유형이 구조적으로 동등한 다른 AST로 AST를 변형하는 체계적인 방법이 있는지 묻고 싶습니까? – didierc

+1

질문이 매우 광범위하고 상황에 따라 매우 다르게 대답 될 것이므로 많은 답변을 얻지 못했다고 생각합니다. 실제로 광범위하게, 사실, 전체 규율은 물건을 물건으로 번역하는 데 전념합니다 .... 기능적인 프로그래밍. – jamshidh

+0

당신이 AST를 찾고 있지 않다고 생각합니다 -> AST - 구조를 기반으로 유형을 변환하는 방법을 찾고있는 것처럼 보입니다 - 그래서 원하는 것은 구조적 타이핑이나 해결 방법입니다 (맞다면). 이미 https://stackoverflow.com/questions/21071603/why-does-haskell-not-have-records-with-structural-typing에 대한 질문이 있습니다. 그리고 hackage에 대한 몇 가지 실험이 있습니다 : http : // hackage. haskell.org/package/shapely-data-0.0 - 거기에 좋은 것이 있는지 모르겠다. – Carsten

답변

1

이 작업을 수행하는 매우 uncanonical 방법은뿐만 아니라 FooExpression 구조적으로 유사하다는 주위에 너무

data BarExpression = BarB BarIdentifier | BarA BarIdentifier BarIdentifier deriving (Show) 

에 BarExpression의 정의를 변경하는 것뿐만 아니라, 같은 런타임이있다 대표.

그럼 당신은 Unsafe.Coerce.unsafeCoerce 사용할 수 있습니다 : 당신이 할 수

fe1 = FooA "a" 
fe2 = FooB "x" "y" 

fm1= FooMethod "meth1" [fe1,fe2] 

foo1 = Foo "foo" [fm1] 

ghci> unsafeCoerce foo1 :: Bar 
Bar "foo" [BarProc "meth1" [BarB "a",BarA "x" "y"]] 

<font size+=1000 color="red"><blink>

주의 할의 programmator :

</blink></font>

나는 영원한 영혼을 위험에 빠뜨릴 것이므로이 일을 전혀 권장하지 않으며, 당신이 그것을 보자 마자 뜻밖에도 아주 나쁜 방법으로 깨어날 것입니다 (만약 당신이 스왑하지 않으면 BarExpression이 예가 원인이되기 시작합니다 segfaults :-)하지만 의 경우 this 특정 사용 사례.

또는 이형 유형 중 하나를 제거 할 수 있습니다. 네가 할 수없는 이유가 있니?

+1

이 포인터를 이용해 주셔서 감사합니다. 나는 "자동화 된"변환을 찾고 있지 않으며 실제로 두 개의 AST가 질문에 표시된 것처럼 가까이 있지 않을 수도 있습니다. – gliptak

+1

나는 그다지 의심 스럽다 :-) 나는 그 경우에 어떻게 접근 할 것인가에 대한 대략적인 생각을 가지고있다. 그래서 더 건설적이고 표준적인 대답을 할 수있다. (이 상자에는 맞지 않을 것이다. 윤곽선). 당신은 질문을 좀 더 대표적인 코드 샘플로 업데이트 할 수 있습니까? 저는 두 개의 AST 유형 중 상응하는 '수준'(표현식, 문장, 메소드)이 얼마나 다른지에 특히 관심이 있습니다. 그것들은 여전히 ​​그들 사이의 동형 이성 (isomorphism)을 가지고 있는가, 아니면 다른 것보다 더 표현력이 강한가? – yatima2975