【发布时间】:2019-01-19 12:12:46
【问题描述】:
我的代码在正则表达式插值上花费了大量时间。由于模式很少改变,我想缓存这些生成的正则表达式应该可以加快代码速度。但是我想不出一个正确的方法来缓存和使用缓存的正则表达式。
该代码用于解析一些算术表达式。由于允许用户定义新的运算符,解析器必须准备好将新的运算符添加到语法中。因此解析器使用一个表来记录这些新的运算符,并从表中动态生成正则表达式。
#! /usr/bin/env perl6
use v6.c;
# the parser may add new operators to this table on the fly.
my %operator-table = %(
1 => $['"+"', '"-"'],
2 => $['"*"', '"/"'],
# ...
);
# original code, runnable but slow.
grammar Operator {
token operator(Int $level) {
<{%operator-table{$level}.join('|')}>
}
# ...
}
# usage:
say Operator.parse(
'+',
rule => 'operator',
args => \(1)
);
# output:
# 「+」
这里有一些实验:
# try to cache the generated regexes but not work.
grammar CachedOperator {
my %cache-table = %();
method operator(Int $level) {
if (! %cache-table{$level}) {
%cache-table.append(
$level => rx { <{%operator-table{$level}.join('|')}> }
)
}
%cache-table{$level}
}
}
# test:
say CachedOperator.parse(
'+',
rule => 'operator',
args => \(1)
);
# output:
# Nil
# one more try
grammar CachedOperator_ {
my %cache-table = %();
token operator(Int $level) {
<create-operator($level)>
}
method create-operator(Int $level) {
if (! %cache-table{$level}) {
%cache-table.append(
$level => rx { <{%operator-table{$level}.join('|')}> }
)
}
%cache-table{$level}
}
}
# test:
say CachedOperator_.parse(
'+',
rule => 'operator',
args => \(1)
);
# compile error:
# P6opaque: no such attribute '$!pos' on type Match in a Regex when trying to get a value
【问题讨论】:
-
"# output: Nil" 见my SO answer about debugging grammars。 “# compile error: P6opaque: no such attribute '$!pos' on type Match in a Regex when trying to get a value” 我还没有理解您的代码或尝试运行它。但乍一看,您的代码似乎正在从语法中的方法返回正则表达式。但是the API is to return a Match object,是应用正则表达式的结果。也许我是误会了。我希望今晚晚些时候尝试运行它,也许我会更了解它。
-
@raiph 是的,我想返回一个正则表达式。好像我对语法有误解。