Я нашел решение: Определите строки внутри ${}
, сначала сопоставьте их. Затем сопоставьте все {}
.
Код:
// whole `${...}`
def("expr", string(r"$") & ref("block_brace"));
// strings
def("dart_str_single", char("'") & (string(r"\'") | char("'").neg()).star() & char("'"));
def("dart_str_double", char('"') & (string(r'\"') | char('"').neg()).star() & char('"'));
def("dart_str_triple_single", string("'''") & string("'''").neg().star() & string("'''"));
def("dart_str_triple_double", string('"""') & string('"""').neg().star() & string('"""'));
// (...)
def("block_parenthesis", char('(') & (
ref("dart_str_triple_single")
| ref("dart_str_triple_double")
| ref("dart_str_single")
| ref("dart_str_double")
| ref("block_parenthesis")
| ref("block_brace")
| char(')').neg()
).star() & char(')'));
// {...}
def("block_brace", char('{') & (
ref("dart_str_triple_single")
| ref("dart_str_triple_double")
| ref("dart_str_single")
| ref("dart_str_double")
| ref("block_parenthesis")
| ref("block_brace")
| char('}').neg()
).star() & char('}'));
Код испытания:
var x4 = grammar["expr"];
var yyy4 = x4.parse(r"""${
users.where((u) => u.name != 'Jeff}}}}}}}}')
.where((u) {
return u.name != '{{{John';
})
.map((u) => u.name).toList()
}""");
print(yyy4.value);
Он печатает:
[$, [{, [
, , , , , , , u, s, e, r, s, ., w, h, e, r, e,
[(, [[(, [u],)], , =, >, , u, ., n, a, m, e, , !, =, ,
[', [J, e, f, f, }, }, }, }, }, }, }, }], ']],)],
, , , , , , , ., w, h, e, r, e, [(, [[(, [u],)], , [{,
[, , , , , , , , , r, e, t, u, r, n, , u, ., n, a, m, e, , !, =, ,
[', [{, {, {, J, o, h, n], '], ;, , , , , , , ], }]],)],
, , , , , , , ., m, a, p, [(, [[(, [u],)], , =, >, , u, ., n, a, m, e],)],
., t, o, L, i, s, t, [(, [],)],
, , , , , , ], }]]
который я думаю, что это правильно, но я до сих пор ищет простое решение.
Update:
Он не может справиться с таким сложным кодом:
"""${
users.where((u) => u.name != 'Jeff}}}}}}}}')
.where((u) {
return u.name != '{{{John${
users.where((u) => u.name != 'Jeff}}}}}}}}')
.where((u) {
return u.name != '{{{John';
})
.map((u) => u.name).toList()
}';
})
.map((u) => u.name).toList()
}"""
Это ${}
внутри строки, которая внутри ${}
. Есть ли другой случай, кроме этого?
Спасибо, Лукас. Не могли бы вы привести мне пример, что мое решение не может справиться правильно? – Freewind
Я думаю, что выражения, содержащие комментарии, обрабатываются неправильно. –