为什么 *any* 在这个例子中不回溯?
Why does *any* not backtrack in this example?
我试图理解为什么在下面的例子中我没有在 f2 上得到匹配。将其与 f1 进行对比,它确实如预期的那样成功。
导入 'package:petitparser/petitparser.dart';
导入 '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
我很确定原因与 any 匹配右括号这一事实有关。但是当它然后寻找右括号并找不到它时,应该不是:
- 回溯最后一个字符
- 假设 any().star() 仅通过 'a'
成功
- 接受最后的参数并成功
另外,我展示了执行此操作的类似正则表达式。
正如您正确分析的那样,示例中的 any 解析器使用了右括号。包装 any 解析器的 star 解析器急切地消耗尽可能多的输入。
您描述的回溯不会由 PEG(解析表达式语法)自动完成。只有有序的选择会自动回溯。
要修复您的示例,有多种可能性。最直截了当的做法是不要让 any 匹配右括号:
id & char('(') & char(')').neg().star() & char(')')
或
id & char('(') & pattern('^)').star() & char(')')
或者您可以使用 starLazy 运算符。它的实现是使用 star 和 ordered choice 运算符。可以找到解释 here.
id & char('(') & any().starLazy(char(')')) & char(')')
我试图理解为什么在下面的例子中我没有在 f2 上得到匹配。将其与 f1 进行对比,它确实如预期的那样成功。
导入 'package:petitparser/petitparser.dart'; 导入 '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
我很确定原因与 any 匹配右括号这一事实有关。但是当它然后寻找右括号并找不到它时,应该不是:
- 回溯最后一个字符
- 假设 any().star() 仅通过 'a' 成功
- 接受最后的参数并成功
另外,我展示了执行此操作的类似正则表达式。
正如您正确分析的那样,示例中的 any 解析器使用了右括号。包装 any 解析器的 star 解析器急切地消耗尽可能多的输入。
您描述的回溯不会由 PEG(解析表达式语法)自动完成。只有有序的选择会自动回溯。
要修复您的示例,有多种可能性。最直截了当的做法是不要让 any 匹配右括号:
id & char('(') & char(')').neg().star() & char(')')
或
id & char('(') & pattern('^)').star() & char(')')
或者您可以使用 starLazy 运算符。它的实现是使用 star 和 ordered choice 运算符。可以找到解释 here.
id & char('(') & any().starLazy(char(')')) & char(')')