Saya sedang menulis DSL menggunakan kombinator parser Scala. Saya baru-baru ini mengubah kelas dasar saya dari StandardTokenParsers menjadi JavaTokenParsers untuk memanfaatkan fitur regex yang menurut saya saya perlukan untuk satu bagian terakhir dari teka-teki. (lihat Mengurai string multiline yang dibatasi menggunakan scala StandardTokenParser)
Apa yang saya coba lakukan adalah mengekstrak blok teks yang dibatasi oleh beberapa karakter ({{
dan }}
dalam contoh ini). Blok teks ini dapat mencakup beberapa baris. Apa yang saya miliki sejauh ini adalah:
def docBlockRE = regex("""(?s)(?!}}).*""".r)
def docBlock: Parser[DocString] =
"{{" ~> docBlockRE <~ "}}" ^^ { case str => new DocString(str) }}
di mana DocString
adalah kelas kasus di DSL saya. Namun, ini tidak berhasil. Gagal jika saya memberinya makan sebagai berikut:
{{
abc
}}
{{
abc
}}
Saya tidak yakin mengapa ini gagal. Jika saya memasang pembungkus Deubg, miliki pembungkus debug di sekitar parser (http://jim-mcbeath.blogspot.com/2011/07/debugging-scala-parser-combinators.html) Saya mendapatkan yang berikut:
docBlock.apply for token
at position 10.2 offset 165 returns [19.1] failure: `}}' expected but end of source found
Jika saya mencoba satu blok yang dibatasi dengan banyak baris:
{{
abc
def
}}
maka itu juga gagal diurai dengan:
docBlock.apply for token
at position 10.2 offset 165 returns [16.1] failure: `}}' expected but end of source found
Jika saya menghapus direktif DOTALL (?s)
maka saya dapat mengurai beberapa blok baris tunggal (yang tidak banyak membantu saya).
Apakah ada cara untuk menggabungkan ekspresi reguler multi-baris dengan pandangan ke depan negatif?
Satu masalah lain yang saya hadapi dengan pendekatan ini adalah, apa pun yang saya lakukan, pembatas penutup harus berada pada baris terpisah dari teks. Kalau tidak, saya mendapatkan pesan kesalahan yang sama seperti yang saya lihat di atas. Sepertinya pandangan negatif ke depan tidak berjalan sesuai harapan saya.