ฉันกำลังเขียน DSL โดยใช้ตัวแยกวิเคราะห์ของ Scala ฉันเพิ่งเปลี่ยนคลาสพื้นฐานจาก StandardTokenParsers เป็น JavaTokenParsers เพื่อใช้ประโยชน์จากฟีเจอร์ regex ที่ฉันคิดว่าฉันต้องการสำหรับปริศนาชิ้นสุดท้าย (ดู การแยกวิเคราะห์สตริงหลายบรรทัดที่ใช้ตัวคั่นโดยใช้ scala StandardTokenParser)
สิ่งที่ฉันพยายามทำคือแยกกลุ่มข้อความที่คั่นด้วยอักขระบางตัว ({{
และ }}
ในตัวอย่างนี้) บล็อกข้อความนี้สามารถขยายได้หลายบรรทัด สิ่งที่ฉันมีจนถึงตอนนี้คือ:
def docBlockRE = regex("""(?s)(?!}}).*""".r)
def docBlock: Parser[DocString] =
"{{" ~> docBlockRE <~ "}}" ^^ { case str => new DocString(str) }}
โดยที่ DocString
เป็นคลาสเคสใน DSL ของฉัน อย่างไรก็ตาม สิ่งนี้ไม่ได้ผล มันจะล้มเหลวถ้าฉันป้อนสิ่งต่อไปนี้:
{{
abc
}}
{{
abc
}}
ฉันไม่แน่ใจว่าทำไมสิ่งนี้ถึงล้มเหลว ถ้าฉันใส่ Deubg wrapper ไว้รอบๆ parser (http://jim-mcbeath.blogspot.com/2011/07/debugging-scala-parser-combinators.html) ฉันได้รับสิ่งต่อไปนี้:
docBlock.apply for token
at position 10.2 offset 165 returns [19.1] failure: `}}' expected but end of source found
ถ้าฉันลองใช้บล็อกตัวคั่นเดียวที่มีหลายบรรทัด:
{{
abc
def
}}
จากนั้นมันก็ล้มเหลวในการแยกวิเคราะห์ด้วย:
docBlock.apply for token
at position 10.2 offset 165 returns [16.1] failure: `}}' expected but end of source found
ถ้าฉันลบคำสั่ง DOTALL (?s)
ฉันสามารถแยกวิเคราะห์บล็อก บรรทัดเดียว ได้หลายบล็อก (ซึ่งไม่ได้ช่วยฉันมากนัก)
มีวิธีใดในการรวม regex หลายบรรทัดเข้ากับ lookahead เชิงลบหรือไม่?
ปัญหาอีกประการหนึ่งที่ฉันมีกับแนวทางนี้คือ ไม่ว่าฉันจะทำอะไรก็ตาม ตัวคั่นปิด ต้อง อยู่ในบรรทัดแยกจากข้อความ มิฉะนั้น ฉันจะได้รับข้อความแสดงข้อผิดพลาดแบบเดียวกับที่เห็นด้านบน มันเกือบจะเหมือนกับว่าการมองล่วงหน้าเชิงลบไม่ได้ผลอย่างที่ฉันคาดหวังไว้