2013-05-14 5 views
5

फॉलो-ऑन के रूप में: How do I test for exactly 2 characters with fparsec?पार्सर पहचानकर्ता और मुफ्त प्रारूप पाठ। क्या यह एफपीआरसीईसी के साथ किया जा सकता है?

मुझे एक स्ट्रिंग को पार्स करने की आवश्यकता है जिसमें पहचानकर्ताओं के जोड़े फ्रीफॉर्म टेक्स्ट के बाद होते हैं। मैं आसानी से एक पार्सर का निर्माण कर सकता हूं जो पहचानकर्ताओं को पाता है जो न्यूलाइन के रूप में होते हैं, इसके बाद एक स्थान के बाद दो अपरकेस वर्ण होते हैं। फ्रीफॉर्म टेक्स्ट, जो पिछले पहचानकर्ता से जुड़ा हुआ है, पहचानकर्ता के बाद सबकुछ है लेकिन अगले पहचानकर्ता को शामिल नहीं करता है।

उदाहरण के लिए

तो:

AB Now is the 
time for all good 
men. 
CD Four score and seven years ago EF our. 

दो पहचानकर्ता AB और CD और freeform पाठ के दो टुकड़े होते हैं

Now is the \ntime for all good men.
Four score and seven years ago EF our.

मेरे समस्या मैं कैसे निर्माण करने के लिए पता नहीं है है एक पार्सर जो फ्रीफॉर्म टेक्स्ट से मेल खाता है लेकिन पहचानकर्ताओं से मेल नहीं खाता है। क्या यह एक ऐसा मामला है जहां मुझे बैकट्रैक करने की ज़रूरत है?

क्या यह किया जा सकता है और यदि ऐसा है तो कैसे?

उत्तर

3

मुझे लगता है कि notFollowedBy वह है जिसे आप ढूंढ रहे हैं। यह चाल चलाना चाहिए:

// adapted from the other question 
let identifier = skipNewline >>. manyMinMaxSatisfy 2 2 CharParsers.isUpper 

let freeform = manyChars (notFollowedBy identifier >>. anyChar) 
4

तर्मिल ने सीधा समाधान पोस्ट किया।

यहाँ एक और संस्करण है, जो शुरुआत में एक नई पंक्ति की जरूरत नहीं है और जो केवल लाइनों के अंत में एक निम्न पहचानकर्ता के लिए जाँच करता है:

let id = manyMinMaxSatisfyL 2 2 isUpper "ID" .>> pchar ' ' 

let text = 
    stringsSepBy (restOfLine true) 
       ((notFollowedBy ((id >>%()) <|> skipNewline <|> eof)) >>% "\n") 

let parser = many (id .>>. text) 

यदि आप दूसरे के साथ प्रयोग किया पार्सर अनुकूलन करने के लिए करना चाहता था stringsSepBy Combinator, तो आपको निम्न संस्करण से बदलने सकता है:

let notFollowedByIdOrEmptyLineOrEof : Parser<string,_> = 
    fun stream -> 
     let cs = stream.Peek2() 
     let c0, c1 = cs.Char0, cs.Char1 
     if c0 = '\r' || c0 = '\n' || c0 = EOS 
      || (isUpper c0 && isUpper c1 && stream.Peek(2) = ' ') 
     then Reply(Error, NoErrorMessages) 
     else Reply("\n") 

let text2 = stringsSepBy (restOfLine true) 
         notFollowedByIdOrEmptyLineOrEof 
+0

हाय, आप इस प्रश्न पर टिप्पणी कृपया सकता है: https://bitbucket.org/fparsec/main/issue/29/portable-version-of- fparsec – Den

संबंधित मुद्दे