2012-11-12 1 views
2

나는 X 같은 것을 변환 모듈 작성하려고 해요 : true의 경우 다음 다른 3 ~ 5 문자열 여기내장되지 않은 유형을 Ocaml에서 문자열로 변환하는 방법은 무엇입니까?

에 INT = 지금까지

module Ast = 
struct 

type typ = Bool | Int 
type var = A | B | C | D | E | F 
type exp = Const of int * typ 
      | App of string * exp list 
      | If of exp * exp * exp 
      | And of exp * exp 
      | Or of exp * exp 
     | Id of var * typ * exp 


let rec toString (t) = 
    let formatDec1(va,ty,e) = ??? 
    match t with 
    Const(n, _) -> print_int n 
     | App(id, [e1; e2]) -> formatter(" "^id^" ", e1, e2) 
     | App(id, [e1]) -> formatter(" "^id^" ", e1, Const(0, Int)) 
     | App(id, _) -> formatter(" "^id^" ", Const(0, Int), Const(0, Int)) 
     | If(e1, e2, e3) -> formatIf(e1, e2, e3) 
     | And(e1, e2) -> formatter(" && ", e1, e2) 
     | Or(e1, e2) -> formatter(" || ", e1, e2) 
     | Id(va,ty,e) -> formatDecl(va,ty,e) 
end 

내가 아직이야 내가 가지고있는 코드입니다 초보자 OCaml에서 문자열을 온라인으로 변환에 대해 아무것도 찾을 수 없습니다. 감사!

+0

예를 들어 무엇이 결과입니까? – didierc

+0

은 "x : int = true이면 3 else 5"와 같습니다. 지금까지 가지고있는 toString 함수가 올바른 경로에 있는지 확실하지 않습니다. – otchkcom

+0

그것은 ast -> string – otchkcom

답변

5

ml 구문으로 기호식을 멋지게 인쇄하고 싶습니다. sexp를 다루는 라이브러리가 있지만, 사용하지는 않았고, 사용법에 대해서는 언급 할 수 없으며, 운동의 목적을 피할 수 있기 때문에 아마도 원하는 것이 아닙니다.

나는 당신이 이미 가지고있는 것과 가깝다고 생각하지만 코드에는 구문상의 오류가 있습니다. 격차 해소에 도움이되는 충고를 드리겠습니다. 당신이 함수 인수에 괄호를 사용할 필요가 없습니다

리콜 다음 OCaml의 구문에 대한 첫 번째

. 함수 정의의 일반 구문은 다음과 같습니다

let fun_name arg1 arg2 arg3 = function_body 

당신은 당신이 실제로 3 개 값의 튜플 자체 1 개 인수를 복용 함수를 정의하는

let fun_name (arg1,arg2,arg3) = ... 

를 작성하는 경우.

표현식 내에서 위의 경우처럼 최상위 값을 정의 할 때와 마찬가지로 let ... in 구조를 사용하여 로컬 값을 정의 할 수 있습니다. 이러한 값 정의가 상호 종속적이지 않으면 여러 값 정의 사이에서 and 키워드를 사용할 수 있습니다.예컨대

,

let x = 1 
and y = "a" in 
... 

2 개 값 x 및 후속 코드를 사용할 수있다 y를 정의하는 것이다. 코드에서

당신은 당신이 예에서주는 것과 같은 표현을 정의 할 수있는 약간의 상징적 인 표현 언어, 줄이 유형 :

"X : INT = 다음 경우는 true를 3 다른 5 "는 다음과 같습니다

Id("x", 
    Int, 
    (If (Const (1, Bool), 
     Const (3, Int), 
     Const (5, Int)))) 

는 사실, 당신은 반복적으로 그 값을 통과하고, 더 큰 문자열로 반환 된 문자열을 결합해야합니다. 또는 문자열 목록을 사용하고 끝에 문자열 연결을 수행 할 수 있습니다. 그 예를 보면, 당신은 아마이 어떻게 작동하는지 볼 수 있습니다

"x"^(":"^"int")^"="^("if"^("true")^"then"^("3")^("5")) 

당신은 위의 다른 서브 표현 패턴을 볼 수 있습니다. 나는 그것들을 나타내는 괄호를 사용했다. 당신의 toString 함수에서

3 개 정의 값있다 :

  • formatter (유형 string * exp * exp의 3- 튜플 촬영 기능)
  • formatDec1 (유형 exp * exp * exp의 3- 튜플을 가지고 다른 함수)
  • formatIf

(같은 formatDec1로) 당신은 keywor를 사용 함수가 재귀적임을 나타내는 toString 함수 정의에 d rec이 있어야합니다. 제 의견으로는 위의 3 가지 함수가 필요하지 않습니다 (처음 할당의 일부입니까, 아니면 직접 정의 했습니까?). toString 함수와 문자열 연결 만 있습니다.

exp 유형의 팔은 매우 일반적입니다. 임의의 개수의 응용 프로그램을 정의 할 수 있으므로 문자열 변환 코드는 이러한 가능성을 고려해야합니다. 목록 기능 (fold_left이 마음에 듭니다)을 사용하여 처리 할 수 ​​있습니다.

+0

감사합니다. 매우 도움이되었습니다. 하지만 한 가지 더 질문이 있습니다. 패턴 일치를 사용하여 비 기본 유형을 문자열로 변환하려면 "x"-> "x"를 사용할 수 없습니다. 왜냐하면 어떤 기호 가든 x가 될 것이기 때문입니다. – otchkcom

+1

예를 들어 보겠습니다. 'and (e1, e2) toString'의 팔은 아마도 'And (e1, e2) -> toString e1^"&&"^ toString e2'와 같아야합니다. 그것은 가장 쉬운 방법입니다. – didierc

2

유형 (또는 인쇄 가능한 유형의 레코드 또는 제품으로 만들어진 집계 유형)에 대한 고유 한 인쇄 루틴을 구현해야합니다.

인쇄 할 인수 외에 인쇄 기능을 허용하는 Printf 모듈의 변환 지정 %a을 사용할 수 있습니다.

대화 형 ocaml 최상위 레벨 인터프리터를 사용하는 경우 #install_printertoplevel directive을 사용할 수 있습니다.

코드에서 (예 : And(e1, e2) 패턴의 경우)을 재귀 적으로 호출하려고합니다.

문자열로 인쇄하려면 Printf.sprintf 또는 Format.sprintf 및 친구를 사용하십시오. 두 PrintfFormat 모듈 (등, 문자열, 버퍼에, 채널로 인쇄 ..) 당신에게 다른 능력을 제공

+0

고마워요.하지만 방금 전 모든 것을 문자열로 변환해야한다는 것을 알았습니다. 이것은 완전히 다른 주제입니다. 미안합니다. – otchkcom

+0

나는 Printf.sprintf ("% a")를 시도했지만 그것은 (unit -> '_a -> string) ->'_a -> string이다. 나는 단위 같은 것을 만난 적이 없다. 예를 들어 주시겠습니까? printf를 처음 사용합니다. – otchkcom

+0

'% a'는 두 개의 인자를 필요로합니다 (첫번째 인자는 함수입니다). 'Printf' 또는'Format' 모듈 문서를 읽으십시오. –

4

자동 인쇄 기능을 생성 할 수 있습니다 deriving라는 이름의 프로젝트가있다. 나는 그것을 사용하지 않았지만 그것은 좋아 보인다.

기본 OCaml 컴파일러에 추가 된 것을 보니 아주 멋지다. 그것은 Haskell에서 아주 잘 작동합니다 (이것은 "파생"이라는 이름이 나오는 곳입니다).

+0

고마워요.하지만 방금 전 모든 것을 문자열로 변환해야한다는 것을 알았습니다. 이것은 완전히 다른 주제입니다. 미안합니다. – otchkcom

+0

파생 프로젝트는 방금 살펴본 문서에 따라 값에서 문자열을 생성 할 수도 있습니다. (반면에, 프로젝트가 최신 OCaml을 위해 업데이트되었는지는 잘 모르겠습니다.) –

+1

4.00.1에서 파생 된 부분이 나에게 적합합니다. 섹스 플립 (sexplib)도 잊지 말자. – rgrinberg

관련 문제