2013-06-22 5 views
2

Я хочу использовать PetitParserDart для синтаксического анализа встроенного выражения внутри строки дротика.Как использовать PetitParser для соответствия выражению внутри строки дротика?

Приготовьте некоторые объекты:

class User { 
    String name; 
} 
var user1 = new User()..name="Mike"; 
var user2 = new User()..name="Jeff"; 
var user3 = new User()..name="John}}}"; 
var users = [user1, user2, user3]; 

Длинная строка:

var s = """ 
Hello, this is an embed dart expression below: 
    ${ 
    users.where((u)=>u.name!='Jeff}}}}}}}}') 
      .where((u) { return u.name!='{{{John'}) 
      .map((u)=>u.name).toList() 
    } 
It's very complex. 
""" 

Вы можете видеть, что есть ${} внутри строки, и его содержание является очень сложным.

Я пытаюсь использовать такой код petitparser:

def("expr_in_string", string('${').ref('expr').char('}')); 
def("expr", ????); 

Но я не знаю, как определить expr правила. Он может содержать { или }, поэтому я не могу просто использовать anyIn('{}').neg().

Что мне делать? Я считаю, что это будет очень сложное правило.

ответ

1

Я не думаю, что вы можете правильно разобрать все возможные строки, не имея более или менее полной грамматики выражения Дарт. Вы можете либо написать приближение (как вы это сделали в своем ответе), либо попытаться использовать выражение выражения грамматики Дарт, которое поставляется с примерами. В любом случае результирующая грамматика сложна, потому что вещь, которую вы пытаетесь сопоставить, сложна.

+0

Спасибо, Лукас. Не могли бы вы привести мне пример, что мое решение не может справиться правильно? – Freewind

+0

Я думаю, что выражения, содержащие комментарии, обрабатываются неправильно. –

0

Существует грамматика для Дарта в src/dart/grammar.dart, похоже, что она сможет разобрать это.

+0

Я видел эту демонстрацию, но это очень сложно понять. – Freewind

+0

В зависимости от того, что вы хотите выполнить, вы можете посмотреть на analyzer_experimental в качестве альтернативы. –

0

Я нашел решение: Определите строки внутри ${}, сначала сопоставьте их. Затем сопоставьте все {}.

Код:

// 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() 
    }""" 

Это ${} внутри строки, которая внутри ${}. Есть ли другой случай, кроме этого?

 Смежные вопросы

  • Нет связанных вопросов^_^