게시판 인덱스

 
 FAQFAQ   검색검색   멤버리스트멤버리스트   사용자 그룹사용자 그룹   사용자 등록하기사용자 등록하기 
 개인 정보개인 정보   비공개 메시지를 확인하려면 로그인하십시오비공개 메시지를 확인하려면 로그인하십시오   로그인로그인 

프로젝트 3번 main + interpreter

 
글 쓰기   답변 달기     게시판 인덱스 -> 4190.210 Principles of Programming (Fall 2014)
이전 주제 보기 :: 다음 주제 보기  
글쓴이 메시지
오평석



가입: 2014년 10월 17일
올린 글: 8

올리기올려짐: 2014년12월21일 0:07    주제: 프로젝트 3번 main + interpreter 인용과 함께 답변

테스트해보기 편하게 기존의 main에 인터프리터를 넣었습니다.
사용법은 ./main [filename] [input1] [input2] [input3] ... 입니다.

read 해야하는 만큼 인풋이 들어오지 않으면 익셉션이 뜹니다.
만약 인풋이 없는 exp라면 아예 전달하지 않으면 됩니다.

바꾼건 얼마 안되서 특별히 잘못된 건 없어보이는데,
뭔가 잘못된 점이 있으면 알려주세요 Smile

코드:

let filename =
  if Array.length Sys.argv < 2
  then (prerr_endline "Usage: ./main filename.exp";
        exit (-1))
  else Sys.argv.(1)

let file_channel = open_in filename
let lexbuf = Lexing.from_channel file_channel
let e = Exp_parser.main Exp_lexer.token lexbuf
let _ = close_in file_channel

let _ = print_endline "========== exp print =========="
let _ = T.pprint_exp e

let _ = print_endline "========== check_exp result =========="
let check_exp_result = T.check_exp e
let _ = print_endline (string_of_bool check_exp_result)
let _ = if check_exp_result then () else exit 0

let _ = print_endline "========== transform result =========="
let c = T.transform e
let _ = T.pprint_cmd c

let _ = print_endline "========== check_cmd result =========="
let check_cmd_result = T.check_cmd c
let _ = print_endline (string_of_bool check_cmd_result)
let _ = if check_cmd_result then () else exit 0

let _ = print_endline "========== transform succeeded =========="


(* use the given interpreter code *)
let rec exp_repeat (iter:int) (e:T.exp) (inputs:int list) : int * (int list) =
  if iter = 0
  then (0,inputs)
  else
    let (r1,i1) = exp_eval_rec e inputs in
    let (r2,i2) = exp_repeat (iter-1) e i1 in
    (r1+r2, i2)

and exp_eval_rec (e:T.exp) (inputs:int list) : int * (int list) =
  match e with
  | T.Num i -> (i,inputs)
  | T.Add (e1,e2) ->
    let (r1,i1) = exp_eval_rec e1 inputs in
    let (r2,i2) = exp_eval_rec e2 i1 in
    (r1+r2,i2)
  | T.Minus e1 ->
    let (r1,i1) = exp_eval_rec e1 inputs in
    (-r1,i1)
  | T.Read -> (List.hd inputs,List.tl inputs)
  | T.If (e1,e2,e3) ->
    let (r1,i1) = exp_eval_rec e1 inputs in
    if r1 = 0
    then exp_eval_rec e3 i1
    else exp_eval_rec e2 i1
  | T.Repeat (e1,e2) ->
    let (r1,i1) = exp_eval_rec e1 inputs in
    exp_repeat r1 e2 i1

let exp_eval (e:T.exp) (inputs:int list) : int = fst (exp_eval_rec e inputs)

let rec cmd_eval_rec
    (c:T.cmd list) (idx:int) (inputs:int list) (m:T.var->int) (tg:T.tag->int)
    : int =
  match List.nth c idx with
  | T.HasNum (x,i) ->
    let new_m = fun k -> if k = x then i else m k in
    cmd_eval_rec c (idx+1) inputs new_m tg
  | T.HasVar (x,y) ->
    let new_m = fun k -> if k = x then m y else m k in
    cmd_eval_rec c (idx+1) inputs new_m tg
  | T.HasSum (x,y,z) ->
    let new_m = fun k -> if k = x then m y + m z else m k in
    cmd_eval_rec c (idx+1) inputs new_m tg
  | T.HasSub (x,y,z) ->
    let new_m = fun k -> if k = x then m y - m z else m k in
    cmd_eval_rec c (idx+1) inputs new_m tg
  | T.HasRead x ->
    let new_m = fun k -> if k = x then (List.hd inputs) else m k in
    cmd_eval_rec c (idx+1) (List.tl inputs) new_m tg
  | T.Say x -> m x
  | T.Goto (t,x) ->
    if m x = 0
    then cmd_eval_rec c (idx+1) inputs m tg
    else cmd_eval_rec c (tg t) inputs m tg
  | T.Tag _ -> failwith "cmd_eval_rec:tag"
  | T.Seq _ -> failwith "cmd_eval_rec:seq"

let rec make_cl_rec (c:T.cmd) (tg:T.tag->int) (idx:int)
    : T.cmd list * (T.tag->int) * int =
  match c with
  | T.HasNum _
  | T.HasVar _
  | T.HasSum _
  | T.HasSub _
  | T.HasRead _
  | T.Say _
  | T.Goto _ -> ([c],tg,idx+1)
  | T.Tag (t,c') ->
    let new_tg = fun k -> if k = t then idx else tg k in
    make_cl_rec c' new_tg idx
  | T.Seq (c1,c2) ->
    let (cl1,tg1,idx1) = make_cl_rec c1 tg idx in
    let (cl2,tg2,idx2) = make_cl_rec c2 tg1 idx1 in
    (cl1@cl2,tg2,idx2)

exception NoBind
exception NoTagBind

let make_cl (c:T.cmd) : T.cmd list * (T.tag->int) =
  let (cl,tg,_) = make_cl_rec c (fun _ -> raise NoTagBind) 0 in
  (cl,tg)

let cmd_eval (c:T.cmd) (inputs:int list) : int =
  let (cl,tg) = make_cl c in
  cmd_eval_rec cl 0 inputs (fun _ -> raise NoBind) tg

let argvs_list = Array.to_list Sys.argv
let inputs_str =
   match argvs_list with
   | _::_::t -> t
   | _ -> exit(-1)
let inputs = List.map (fun x -> int_of_string x) inputs_str

let _ = print_endline "========== run exp =========="
let _ = print_int (exp_eval e inputs)
let _ = print_endline ""

let _ = print_endline "========== run cmd =========="
let _ = print_int (cmd_eval c inputs)
let _ = print_endline ""
위로
사용자 정보 보기 비밀 메시지 보내기
이전 글 표시:   
글 쓰기   답변 달기     게시판 인덱스 -> 4190.210 Principles of Programming (Fall 2014) 시간대: GMT + 9 시간(한국)
페이지 11

 
건너뛰기:  
새로운 주제를 올릴 수 없습니다
답글을 올릴 수 없습니다
주제를 수정할 수 없습니다
올린 글을 삭제할 수 없습니다
투표를 할 수 없습니다


Powered by phpBB 2.0.21-7 (Debian) © 2001, 2005 phpBB Group
Translated by kss & drssay