Haskell: كيفية إيقاف data.attoparsec.char8.sepby عندما تكون سلسلة الإدخال فارغة؟
-
27-09-2019 - |
سؤال
لقد كتبت رمز Haskell التالي
import Data.Attoparsec (Parser)
import qualified Data.Attoparsec.Char8 as A
import qualified Data.ByteString.Char8 as B
someWithSep sep p = A.sepBy p sep
من المفترض أن يعمل الرمز بهذه الطريقة:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89"
Done "" [123,45,67,89]
لكن بما أنني حددت بشكل ما كما هو الحال في الكود المكتوب أعلاه ، أحصل دائمًا على السلوك التالي:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89"
Partial _
ما لم أقدم إدخالًا تالفًا:
main*> A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89f"
Done "f" [123,45,67,89]
كيف يمكنني تصحيح هذا ؟
شكرا للرد
المحلول
ال Partial
لا يشير المنشئ إلى الفشل ، فقط أن التحليل قد يستمر إذا أردت ذلك. يجب أن تأخذ العنصر الجزئي وإطعامه بايت فارغ (حسب المستندات: http://hackage.haskell.org/packages/archive/attoparsec/0.8.1.0/doc/html/data-attoparsec-char8.html#t: Result) للحصول على النتيجة النهائية.
فقط لإظهار أنه يعمل:
> let A.Partial f = A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89" in f B.empty
Done "" [123,45,67,89]
بالطبع ، ربما ترغب في الحصول على بيان حالة في النهاية للتعامل مع الحالات الأخرى.
نصائح أخرى
Attoparsec يقبل المدخلات في قطع متعددة. واحد يعطي القطعة الأولى ل تحليل, ثم يعطي النتيجة من تحليل والقطعة الثانية تغذية, ثم يعطي هذه النتيجة والقطعة الثالثة ل تغذية مرة أخرى ، وهلم جرا.
تقوم بتغذية المحلل اللامبلي سلسلة فارغة لتمييز نهاية الإدخال:
A.feed (A.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89") B.empty
Done "" [123,45,67,89]
أو استخدم data.attoparsec.lazy ، حيث تتعامل السلسلة البطيئة مع نهاية الإدخال لك:
import qualified Data.Attoparsec.Lazy as L
import qualified Data.Attoparsec.Char8 as A
import qualified Data.ByteString.Lazy.Char8 as B
L.parse (someWithSep A.skipSpace A.decimal) $ B.pack "123 45 67 89"
Done "" [123,45,67,89]
(أنظر أيضا هذا السؤال المربع المربع ذي الصلة)