如何使用 lark ebnf 解析 ~{expr} 内部字符串
How to parse ~{expr} inside string with lark ebnf
我正在尝试为 dsl 编写 lark 语法,但遇到了以下字符串插值语法的问题:
" abc " <- normal string
" xyz~{expression}abc " <- string with interpolation
所以 ~{ 从字符串切换到表达式,然后 } 终止该表达式。我认为这很接近:
string : "\"" (string_interp|not_string_interp)* "\""
string_interp: "~{" expression "}"
not_string_interp: /([^~][^{])+/
但是正则表达式只会匹配偶数个字符,如果 ~{ 跨越偶数边界,它将被遗漏。
not_string_interp: /(.?|([^~][^{])+)/
这是我所能得到的,但似乎仍然不对。我可以使用前瞻吗?我还想保持 %ignore WS 开启,因为它可以大大降低噪音,所以解决这个问题的解决方案会很棒!
谢谢
测试用例:
""
"a"
"~{1}"
" ~{1} "
"a bc~{1}c d"
"a b~{1}c d"
Here is a solution to your problem 使用正后视。
(?<=~{)[^}]+
它查找表达式 ~{
的开头并捕获右大括号 }
之前的所有内容
我认为可以。遗憾的是,任何 ~ 后面没有 { 都会拆分字符串,但我可以稍后重建它们。我被规则的同等优先级和正则表达式的贪婪所愚弄。
/[^"~]+/
任何不是 ~ 或 "(常规字符串)的东西
"~{" expression "}"
正常表达式
/~(?!{)/
处理 ~ 不带 {.采用 ?!因为我们不能消耗下一个字符(它可能是 " 或另一个 ~)
from lark import Lark
print (Lark(r"""
string: "\"" string_thing* "\""
string_thing: /[^"~]+/
| "~{" expression "}"
| /~(?!{)/
expression: /[^}]+/
""", start='string', ambiguity="explicit").parse(
# '"a"'
'"a~b{}c}d~{1}g"'
# '"~abc~"'
# '"~{1}~~{1}~~~{1}"'
).pretty())
我正在尝试为 dsl 编写 lark 语法,但遇到了以下字符串插值语法的问题:
" abc " <- normal string
" xyz~{expression}abc " <- string with interpolation
所以 ~{ 从字符串切换到表达式,然后 } 终止该表达式。我认为这很接近:
string : "\"" (string_interp|not_string_interp)* "\""
string_interp: "~{" expression "}"
not_string_interp: /([^~][^{])+/
但是正则表达式只会匹配偶数个字符,如果 ~{ 跨越偶数边界,它将被遗漏。
not_string_interp: /(.?|([^~][^{])+)/
这是我所能得到的,但似乎仍然不对。我可以使用前瞻吗?我还想保持 %ignore WS 开启,因为它可以大大降低噪音,所以解决这个问题的解决方案会很棒!
谢谢
测试用例:
""
"a"
"~{1}"
" ~{1} "
"a bc~{1}c d"
"a b~{1}c d"
Here is a solution to your problem 使用正后视。
(?<=~{)[^}]+
它查找表达式 ~{
的开头并捕获右大括号 }
我认为可以。遗憾的是,任何 ~ 后面没有 { 都会拆分字符串,但我可以稍后重建它们。我被规则的同等优先级和正则表达式的贪婪所愚弄。
/[^"~]+/
任何不是 ~ 或 "(常规字符串)的东西
"~{" expression "}"
正常表达式
/~(?!{)/
处理 ~ 不带 {.采用 ?!因为我们不能消耗下一个字符(它可能是 " 或另一个 ~)
from lark import Lark
print (Lark(r"""
string: "\"" string_thing* "\""
string_thing: /[^"~]+/
| "~{" expression "}"
| /~(?!{)/
expression: /[^}]+/
""", start='string', ambiguity="explicit").parse(
# '"a"'
'"a~b{}c}d~{1}g"'
# '"~abc~"'
# '"~{1}~~{1}~~~{1}"'
).pretty())