2013-05-06 2 views
0

내가 1 + 2와 같은 중위 식을 제공 OCaml의에서 프로그램을 작성, 접두사 표기법을 출력 like : 모든 값, 연산자 및 브래킷은 항상 적어도 하나의 공백으로 구분되어야합니다. 1+ 1은 틀린 1 + 1 ok입니다. ocamlp4 문법을 사용하고 싶지 않습니다. 여기 OCaml의 렉서/파서 규칙

코드입니다 :

open Genlex                                        

type tree = 
    | Leaf of string 
    | Node of tree * string * tree 

let my_lexer str = 
    let kwds = ["("; ")"; "+"; "-"; "*"; "/"] in 
    make_lexer kwds (Stream.of_string str) 

let make_tree_from_stream stream = 
    let op_parser operator_l higher_perm = 
    let rec aux left higher_perm = parser 
     [<'Kwd op when List.mem op operator_l; right = higher_perm; s >] 
     -> aux (Node (left, op, right)) higher_perm s 
     | [< >] 
     -> left 
    in 
     parser [< left = higher_perm; s >]  -> aux left higher_perm s 
    in 
    let rec high_perm l = op_parser ["*"; "/"] brackets l 
    and low_perm l = op_parser ["+"; "-"] high_perm l 
    and brackets = parser 
    | [< 'Kwd "("; e = low_perm; 'Kwd ")" >] -> e 
    | [< 'Ident n >]       -> Leaf n 
    | [< 'Int n >]        -> Leaf (string_of_int n) 
    in 
    low_perm stream 

let rec draw_tree = function 
    | Leaf n    -> Printf.printf "%s" n 
    | Node(fg, r, fd)  -> Printf.printf "(%s " (r); 
     draw_tree fg; 
     Printf.printf " "; 
     draw_tree fd; 
     Printf.printf ")" 

let() = 
    let line = read_line() in 
    draw_tree (make_tree_from_stream (my_lexer line)); Printf.printf "\n" 

플러스 당신이 코드에 대한 몇 가지 조언을하거나 음식물 스타일의 일부 오류를 발견하면 나는 당신이 그것을 알려 주시기 있다는 것을 알 수있을 것이다합니다. 감사 !

답변

1

Genlex은 OCaml의 어휘 규칙을 존중하며 특히 언급 한 위치의 공백을 무시하는 기성의 렉서를 제공합니다. 나는 당신이 원하는 것만 구현할 수 있다고 생각하지 않는다. (유연한 솔루션으로 설계된 것이 아니라, 프로토 타입을 작동시키는 빠른 방법이다.) token 유형을 정의하고, 당신이 원하는대로 당신은 다음 구문 분석 할 수있는 token Stream.t,에 char Stream.t를 렉스 : 당신이 쓰기 스트림 파서을 유지하려면

, 당신은 그것을 위해 자신의 렉서를 작성할 수 있습니다. 그렇지 않으면 Camlp4를 사용하지 않으려는 경우 menhir (더 나은 ocamlyacc)과 같은 LR 파서 생성기를 사용해 볼 수 있습니다.

+0

글쎄 ocamlp4 문법을 사용하고 싶지는 않습니다. 왜냐하면 정말 무서운 것이기 때문입니다. 나는 ocaml의 문법/철학에 대해 정말 새롭다. 자신의 렉서를 작성할 수 있다고 말하면 make_lexer를 사용하지 말고 내 자신의 함수를 작성해야합니다. 도와 줘서 고맙다 ! – axzwl

+0

예, 공백을 세밀하게 처리하려면 고유 한 렉서 기능을 작성해야합니다. Genlex는 그러한 함수의 유일한 인스턴스입니다. 하지만 손으로 ​​작성하는 대신 파서 생성기를 사용하는 것을 고려해 보셨습니까? – gasche

+0

예 나는 그것을 고려해 보았지만 ocamlp4의 스트림에 익숙해지기를 원했기 때문에 나는 단지 내 자신의 파서를 썼고 좋은 훈련이되어야한다는 것을 명심했다. – axzwl