Tôi đang cố gắng phân tích các loại đơn giản chuẩn (theo nghĩa lambda) bằng FParsec, nhưng tôi gặp khó khăn khi chuyển từ kiểu Lex/Yacc sang FParsec, đặc biệt với sự tôn trọng để định nghĩa đệ quy.Phân tích các loại đơn giản trong FParsec
Ví dụ về các loại Tôi cố gắng để phân tích cú pháp là:
- o
- o -> o
- (o -> o -> o) -> o
Và đây là nỗ lực của tôi:
type SType =
| Atom
| Arrow of SType * SType
let ws = spaces
let stype, styperef = createParserForwardedToRef()
let atom = pchar 'o' .>> ws |>> (fun _ -> Atom)
let arrow = pipe2 (stype .>> (pstring "->" .>> ws))
stype
(fun t1 t2 -> Arrow (t1,t2))
let arr = parse {
let! t1 = stype
do! ws
let! _ = pstring "->"
let! t2 = stype
do! ws
return Arrow (t1,t2)
}
styperef := choice [ pchar '(' >>. stype .>> pchar ')';
arr;
atom ]
let _ = run stype "o -> o"`
Khi tôi tải ứng dụng này vào tương tác ve dòng cuối cùng gây ra một tràn ngăn xếp (trớ trêu thay khá khó để tìm kiếm những ngày này). Tôi có thể tưởng tượng lý do tại sao, cho rằng có các tham chiếu đệ quy, nhưng tôi đã nghĩ rằng một trong những lookahead mã thông báo sẽ có ngăn chặn sau sự lựa chọn đầu tiên (bracketed) trong stype
. Do đó, tôi giả định rằng nó phải chọn arr
, trong đó chọn stype
, v.v. Nhưng làm thế nào để ngăn chặn vòng lặp này?
Tôi quan tâm đến nhận xét về việc sử dụng thành ngữ của thư viện cũng như các chỉnh sửa đối với giải pháp đã cố gắng của tôi.
Điều này có thể muốn bạn muốn: http://stackoverflow.com/questions/6186230/recursive-grammars-in-fparsec –
Cảm ơn, tôi đã đọc câu hỏi/trả lời đó, nhưng tôi hoàn toàn không thể hiểu cách trả lời câu hỏi của mình. Tôi sẽ có một cái nhìn khác mặc dù. – rneatherway