为什么* any *在此示例中没有回溯?

时间:2015-08-23 12:40:38

标签: dart petitparser

我试图理解为什么在下面的示例中我没有得到f2上的匹配。与f1形成对比,后者确实按预期成功。

    import' package:petitparser / petitparser.dart&#39 ;;     import' package:petitparser / debug.dart';

main() {
  showIt(p, s, [tag = '']) {
    var result = p.parse(s);
    print('''($tag): $result ${result.message}, ${result.position} in:
$s
123456789123456789
''');
  }
  final id = letter() & word().star();
  final f1 = id & char('(') & letter().star() & char(')');
  final f2 = id & char('(') & any().star() & char(')');
  showIt(f1, 'foo(a)', 'as expected');
  showIt(f2, 'foo(a)', 'why any not matching a?');
  final re1 = new RegExp(r'[a-zA-Z]\w*\(\w*\)');
  final re2 = new RegExp(r'[a-zA-Z]\w*\(.*\)');
  print('foo(a)'.contains(re1));
  print('foo(a)'.contains(re2));
}

输出:

(as expected): Success[1:7]: [f, [o, o], (, [a], )] null, 6 in:
foo(a)
123456789123456789

(why any not matching a?): Failure[1:7]: ")" expected ")" expected, 6 in:
foo(a)
123456789123456789

true
true

我很确定这个原因与任何匹配关闭paren的事实有关。但是当它找到关闭的paren并且无法找到它时,不应该这样:

  • 回溯最后一个字符
  • 假设 any()。star()成功完成了' a'
  • 接受最终的paren并成功

另外相反,我展示了这样做的类似的正则表达式。

1 个答案:

答案 0 :(得分:2)

正确分析后,示例中的任何解析器都会使用右括号。包含任何解析器的 star 解析器正在急切地消耗尽可能多的输入。

您描述的回溯不是由PEG自动完成的(解析表达式语法)。只有有序选择会自动回溯。

要修复您的示例,有多种可能性。大多数海峡前锋不是让任何匹配右括号:

id & char('(') & char(')').neg().star() & char(')')

id & char('(') & pattern('^)').star() & char(')')

或者,您可以使用 starLazy 运算符。它的实现是使用 star 有序选择运算符。可以找到解释here

id & char('(') & any().starLazy(char(')')) & char(')')