2017-06-04 18 views
6

Tôi mới sử dụng F # và có vấn đề khá khó chịu. Tôi muốn phân tích ngữ pháp sau:Trình phân tích cú pháp tích phân lambda đơn giản với FParsec

Application := Expression Expression 
Expression := "(" "lambda" Name "." Application ")" 
      | Name 
Name  := [a-z]+ 

Điều đó sẽ phù hợp với những thứ như (lambda x. (lambda y. x y)) z(lambda x. x) y.

Vấn đề của tôi là hai nguyên tắc phụ thuộc vào nhau:

let popen = pchar '(' 
let pclose = pchar ')' 
let pname = many1 letter |>> Seq.toArray |>> System.String |>> NameNode 
let plambda = pstring "lambda" 
let pdot = pchar '.' 
let phead = plambda >>. pname .>> pdot 
let pexpression = 
     popen >>. pname .>>. papplication .>> pclose |>> ExpressionNode 
    <|> pname 
let papplication = pexpression .>>. pexpression 

pexpression phụ thuộc vào papplication và vicebersa. Làm thế nào tôi có thể thoát khỏi sự phụ thuộc đó?

Trả lời

8

Trình phân tích cú pháp đệ quy có thể được triển khai qua createParserForwardedToRef. Hàm này trả về một cặp "trình xử lý" của trình phân tích cú pháp, do đó, để nói và một ô có thể thay đổi được để thực hiện trình phân tích cú pháp. Các "xử lý", một khi kêu gọi để thực sự phân tích cú pháp một cái gì đó, sẽ chuyển tiếp cuộc gọi đến việc thực hiện.

Sau khi mua cặp này, bạn có thể triển khai phần khác của đệ quy bằng cách sử dụng "xử lý", rồi tạo triển khai thực hiện của trình phân tích cú pháp được chuyển tiếp và gán nó cho ô có thể thay đổi.

let pexpression, pexpressionImpl = createParserForwardedToRef() 
let papplication = pexpression .>>. pexpression 
pexpressionImpl := 
     popen >>. pname .>>. papplication .>> pclose |>> ExpressionNode 
    <|> pname 
+0

Ah! Đó chỉ là những gì tôi cần. Cảm ơn :) – gosukiwi

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