2016-04-18 9 views
0

Ich erhalte einen Fehler bei der Übereinstimmung meines OCaml-Codes, und ich habe keine Ahnung, was das Problem sein könnte. Ich habe versucht, nur in einem Fall mit und gehen von dort aus, um herauszufinden, wo das Problem aufkommt, aber die Fehler, die ich erhalten ist:Übereinstimmungsfehler Ausgabe OCaml

Exception: Match_failure ("hw2.ml", 49, 0). 

Code:

let rec compileStack(il : instr list) (st : float list) = 
match (il,st) with 
[],[_] -> List.hd st 
|((Push f)::t),[_] -> compileStack t (f::st) 
|(Swap)::t, h2::h1::st -> compileStack t (h2::h1::st) 
|(Calculate op)::t, h1::h2::st -> 
    match op with 
    Plus -> compileStack t (h2+.h1::st) 
    | Minus -> compileStack t (h2-.h1::st) 
    | Times -> compileStack t (h2*.h1::st) 
    | Divide -> compileStack t (h2/.h1::st) ;;        

let execute (li : instr list) : float = 
    let stack = [] in 
    compileStack li stack;; 

Jeder möglicher Vorschlag sehr geschätzt werden, stecken geblieben hierauf seit 2 Stunden.

+1

wo ist die Linie 49? –

+2

Was sind Ihre Eingabedaten für den fehlgeschlagenen Test? Übrigens ist die Mustererkennung auf (il, st) nicht erschöpfend: Sie haben eine Menge Fälle übersehen. Dies scheint dein Problem zu sein. –

Antwort

2

Beim Kompilieren achten Sie auf die Ausgabe des Compilers. Wenn es etwas wie

Warning ...: this pattern-matching is not exhaustive. 

dann bedeutet, bedeutet es normalerweise, dass Sie einige Fälle ausgelassen haben. Der Compiler liefert übrigens ein Beispiel für verpasste Fälle.

Wenn Sie Ihr Problem betrachten, würde ich verschiedene Jobs in verschiedene Funktionen aufteilen - damit können Sie diese Fälle einfacher behandeln; Vergessen Sie auch nicht die Stack-Unterläufe, die auftreten, wenn im Stack nicht genügend Daten vorhanden sind, um Swaps oder binäre arithmetische Operationen durchzuführen. Siehe das Beispiel unten.

(* just type aliases for convenience *) 
type stack = float list 
type binop = float -> float -> float 

(* helper function to prevent nested pattern matching below *) 
let denote_operation (op : oper) : binop = 
    match op with 
    | Plus -> (+.) 
    | Minus -> (-.) 
    | Times -> (*.) 
    | Divide -> (/.) 

(* This function executes only 1 instruction and 
    returns 'stack option', which may signal stack underflow *) 
let execute_instruction (i : instr) (st : stack) : stack option = 
    match i with 
    | Push f -> Some (f :: st) 
    | Swap -> 
     (match st with 
      | y :: x :: st' -> Some (x :: y :: st') 
      | _ -> None) 
    | Calculate op -> 
     (match st with 
      | y :: x :: st' -> Some ((denote_operation op x y) :: st') 
      | _ -> None) 

(* this function deals with a bunch of instructions *) 
let rec execute_program (il : instr list) (st : stack) : stack option = 
    match il with 
    | [] -> Some st 
    | i :: il' -> 
     match (execute_instruction i st) with 
     | None -> None 
     | Some st' -> execute_program il' st'