我正在尝试为dsl编写过时的语法,但是在使用此字符串插值语法时遇到了麻烦:
" 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"
答案 0 :(得分:2)
我认为这样做。遗憾的是,任何〜后跟{的字符都不会分割字符串,但是我以后可以重构它们。规则的优先级和正则表达式的贪婪使我迷惑。
/[^"~]+/
不是〜或“(常规字符串)的任何内容
"~{" 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())
答案 1 :(得分:1)