2016-06-07 57 views
5

Tôi có tình huống sau đây:Thông tư chức năng cuộc gọi khi đánh giá các nút AST cho thông dịch viên

let private runStatement (vars : Map<identifier, value>) stmt = 
    match stmt with 
    | Assignment (id, expr) -> runAssignment vars id expr 
    | Print exprs -> runPrint vars exprs 
    | Read id -> runRead vars id 
    | If (cond, stmts) -> runIf vars cond stmts 

let rec private runStatements vars stmts = 
    match stmts with 
    | stmt::rest -> 
     let newVars = runStatement vars stmt 
     runStatements newVars rest 
    | [] -> vars 

let private runIf vars conditionalValue statements = 
    match conditionalValue with 
    | Boolean v when v -> runStatements vars statements 
    | Boolean v -> vars 
    | _ -> failwith "Not a boolean expression in if statement" 

Như bạn thấy, chức năng runStatement gọi runIf, và runIf cuộc gọi runStatement, bởi vì một if-tuyên bố được hình thành bởi một số chung báo cáo, và một tuyên bố chung có thể là một tuyên bố nếu.

Làm cách nào để giải quyết tình huống này?

PS .: Tôi có các tình huống tương tự với các chức năng khác như runWhile, runIfElse và cetera.

+2

Hãy luôn bao gồm tất cả các mã (loại, chức năng, 'báo cáo open') cần thiết để làm ví dụ biên dịch. Điều đó cho phép người khác tập trung vào việc cung cấp giải pháp mà không cần phải sửa mã. – TeaDrivenDev

+2

Truyền các chức năng vào làm đối số thay vì ghép nối với chúng. –

+0

Lưu ý: Tôi lấy nó là một phần của dự án biên dịch của bạn vì bạn đã sử dụng thẻ 'compiler-construction'. Bạn nên thả 'run' từ các tên hàm bởi vì mọi người sử dụng để làm việc với các trình phân tích cú pháp mong đợi tên của hàm giống như tên mà chúng đang phân tích cú pháp. Vì vậy, đối với điều này, các thuật ngữ là 'statement',' statements', và 'if'. Tôi biết bạn sẽ nhận được một lỗi nếu bạn đặt tên một hàm 'if' vì vậy những gì tôi sẽ làm là đặt tên nó là' ifParser', nhưng không sử dụng chạy và điều đó dẫn tôi tin rằng đó là một hàm có thể được gọi từ chính chương trình và trong khi đó là có thể không phải là tùy chỉnh. –

Trả lời

8

Sử dụng 'và' từ khóa

let rec runx() = 
    printf "runx" 
    runy() 
and runy() = 
    printf "runy" 
    runx() 

runx() |> ignore 

in

runxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxrunyrunxruny 
+0

Phillip, bạn nói đúng, đây là giải pháp cho câu hỏi của tôi. - Như một lưu ý: Sau khi xem xét mã của tôi, tôi đã nhận thấy rằng ngôn ngữ của tôi đã để lại đệ quy và đó là lý do tại sao tôi phải đối mặt với loại vấn đề này. Tôi sẽ cấu trúc lại ngôn ngữ của mình để loại bỏ đệ quy trái này. (Tôi đang nói nó bởi vì nó có thể giúp người khác). – Gabriel

Các vấn đề liên quan