2015-05-03 5 views
0

В настоящее время я пишу переводчика для c ocaml. Мне был предоставлен makefile для исходного кода, содержащего абстрактный файл синтаксиса, основной файл и т. Д. Я пытаюсь реализовать арифметику, но я продолжаю получать эту ошибку (match_failure) при запуске тестового примера. Тестовый файл находится в файле .cf. Это содержимое файла "print_int ((9 + 6 + (11/11) +1 + (- 6)) * (- 1));" Может кто-то, пожалуйста, помогите мне понять, почему происходит ошибка?Почему я продолжаю получать match_failure?

Это мой код:

open Ast;; 
open Env;; 
open Store;; 

let allocateMem env = env;; (* TODO: implement this function *) 


let rec eval_expr (expr:expr) (ps:proc_state) (env:environment) (store:store) : int = match expr with 
     Add (e1, e2) -> 
     let r1 = eval_expr e1 ps env store in 
     let r2 = eval_expr e2 ps env store in 
     r1 + r2 
    | Sub (e1, e2) -> 
     let r1 = eval_expr e1 ps env store in 
     let r2 = eval_expr e2 ps env store in 
     r1 - r2 
    | Mul (e1, e2) -> 
     let r1 = eval_expr e1 ps env store in 
     let r2 = eval_expr e2 ps env store in 
     r1 * r2 
    | Div (e1, e2) -> 
     let r1 = eval_expr e1 ps env store in 
     let r2 = eval_expr e2 ps env store in 
     r1/r2 
    | Neg (e1) -> 
     let r1 = eval_expr e1 ps env store in 
     r1 * -1 
    | IntConst i -> i 
    | Id (e1) -> 
     let l = binding_of env e1 in 
     let Intval(i)= value_at(store,l) in 
     i;; 

;; 

(* eval_expr: expr -> proc_state -> env -> store -> value *) 
let rec eval_cond cond ps env store = match cond with 
    Equal (e1, e2) -> 
    let r1 = eval_expr e1 ps env store in 
    let r2 = eval_expr e2 ps env store in 
    r1 == r2 
(* TODO: add more *) 
;; 

type stmtEvalRes = Next | BreakOut | ContinueOn;; 

(* eval_stmt: stmt -> proc_state -> env -> store -> stmtEvalRes*proc_state *) 
let rec eval_stmt stmt ps env store = match stmt with 
| PrintInt e -> 
    let r = eval_expr e ps env store in 
    print_int r; (Next, ps, store) 
| PrintStr s -> 
    print_string (Str.global_replace (Str.regexp "\\\\n") "\n" s); 
    (* Escaping characters here because it's not done in the parser *) 
    (Next, ps, store) 
| List (stmt1::stmts) -> eval_stmt stmt1 ps env store 
    (* TODO: complete this case so that all statements in the list evaluated *) 
;; 
+0

Пожалуйста, разместите достаточно кода, чтобы воспроизвести ошибку. Также сообщайте о любых предупреждениях компилятора, которые вы получаете при компиляции кода. – sepp2k

+0

Я обновил его. Кроме того, я не получил никаких предупреждений. – user4789552

+0

Я не вижу, как это может быть правдой, если вы получаете сбой соответствия, если только вы явно не запретили предупреждения об исчерпании. Обратите внимание, что вы не получите никаких предупреждений, если вы запустите make, не изменяя код или не выполнив 'make clean', потому что он не будет компилировать любые файлы, которые не были изменены. – sepp2k

ответ

0

Согласно предупреждению, мы можем реконструировать, что expr типа, имеет следующий набор конструкторов: Add, Sub, Mul,Div, Neg, Id, At, Deref, AddressOf, Call, Pre, Post, то есть 11 филиалов, у вас есть только 7.

Я подозреваю, что исходный код, который вы получили в качестве задания, имели следующую реализацию:

let rec eval_expr (expr:expr) (ps:proc_state) (env:environment) (store:store) : int = match expr with 
     Add (e1, e2) -> 
     let r1 = eval_expr e1 ps env store in 
     let r2 = eval_expr e2 ps env store in 
     r1 + r2 
(* TODO: add more *) 

Это белый у, когда вы компилируете исходный код, вы получили предупреждение:

Warning 8: this pattern-matching is not exhaustive. 
Here is an example of a value that is not matched: 
(Sub (, _)|Mul (,)|Div (,)|Neg _|Id _|At (,)|Deref _|AddressOf _| Call (, _)|Pre _|Post _) " 

код, который вы показываете нам, это не код, который вы пытаетесь скомпилировать. Может быть, вы играете с ним в полном объеме.

Как указано в sepp2k, выражение тестирования не содержит выражения вызова, это означает, что с большой вероятностью вы компилируете и запускаете исходный код, то есть тот, который содержит только одну ветку Add, а не код, что вы написали. Вот почему вы получаете неудачу матча. (Но рано или поздно вам все равно нужно написать все 11 ветвей).

+0

Я уверен, что в данном выражении нет вызова. 'print_int' почти наверняка получает синтаксический анализ как выражение' PrintInt' (см. 'eval_stmnt'). – sepp2k

+0

yep, похоже, что вы правы – ivg

Смежные вопросы