मैं एफ # का उपयोग कर एक रिकर्सिव डेटा स्ट्रक्चर में स्ट्रिंग को पार्स करना चाहता हूं। इस सवाल में मैं एक सरलीकृत उदाहरण पेश करने जा रहा हूं जो कि मैं जो करना चाहता हूं उसके मूल में कटौती करता हूं।एक रिकर्सिव डेटा स्ट्रक्चर में पार्सिंग
मैं रिकॉर्ड प्रकार के लिए नेस्टेड वर्ग कोष्ठक की एक स्ट्रिंग पार्स करने के लिए करना चाहते हैं:
type Bracket = | Bracket of Bracket option
तो:
- "[]" ->
Bracket None
- "[[]] "->
Bracket (Some (Bracket None))
- " [[[]]] "->
Bracket (Some (Bracket (Some (Bracket None))))
मैं FParsec लाइब्रेरी में पार्सर संयोजकों का उपयोग करके ऐसा करना चाहता हूं। यहाँ मैं अब तक है:
let tryP parser =
parser |>> Some
<|>
preturn None
/// Parses up to nesting level of 3
let parseBrakets : Parser<_> =
let mostInnerLevelBracket =
pchar '['
.>> pchar ']'
|>> fun _ -> Bracket None
let secondLevelBracket =
pchar '['
>>. tryP mostInnerLevelBracket
.>> pchar ']'
|>> Bracket
let firstLevelBracket =
pchar '['
>>. tryP secondLevelBracket
.>> pchar ']'
|>> Bracket
firstLevelBracket
मैं भी कुछ Expecto परीक्षण: बेशक कैसे संभाल करने के लिए नहीं मिल पाता की मनमानी के स्तर का
open Expecto
[<Tests>]
let parserTests =
[ "[]", Bracket None
"[[]]", Bracket (Some (Bracket None))
"[[[]]]", Bracket (Some (Bracket (Some (Bracket None)))) ]
|> List.map(fun (str, expected) ->
str
|> sprintf "Trying to parse %s"
|> testCase
<| fun _ ->
match run parseBrakets str with
| Success (x, _,_) -> Expect.equal x expected "These should have been equal"
| Failure (m, _,_) -> failwithf "Expected a match: %s" m
)
|> testList "Bracket tests"
let tests =
[ parserTests ]
|> testList "Tests"
runTests defaultConfig tests
समस्या है - केवल उपरोक्त कोड अप के लिए काम करता 3 स्तर तक। कोड मैं तरह लिखने के लिए होता है:
let rec pNestedBracket =
pchar '['
>>. tryP pNestedBracket
.>> pchar ']'
|>> Bracket
लेकिन एफ # इस अनुमति नहीं है।
क्या मैं इसे हल करने के तरीके से गलत पेड़ को पूरी तरह से भौंक रहा हूं (मैं समझता हूं कि इस विशेष समस्या को हल करने के आसान तरीके हैं)?
धन्यवाद थॉमस - एक बार मुझे इसके माध्यम से काम करने का मौका मिलने के बाद उत्तर के रूप में चिह्नित किया जाएगा। – Lawrence