来自man perlre
:
“*”量词相当于“{0,}”,“+”量词相当于“{1,}”和“?”量词为“{0,1}”。 n和m限于小于建立perl时定义的预设限制的整数值。在最常见的平台上,这通常是32766。实际限制可以在代码生成的错误消息中看到,如下所示:
$_ **= $_ , / {$_} / for 2 .. 42;
哎呀,这很丑陋 - 难道不是我可以得到一些常数吗?
编辑:正如daxim指出的那样(以及perlretut提示),32767可能是一个神奇的硬编码。 Perl代码中的一点searching有很长的路要走,但我不确定如何进入下一步并实际找到实际设置的默认reg_infty或REG_INFTY的位置:
~/dev/perl-5.12.2
$ grep -ri 'reg_infty.*=' *
regexec.c: if (max != REG_INFTY && ST.count == max)
t/re/pat.t: $::reg_infty = $Config {reg_infty} // 32767;
t/re/pat.t: $::reg_infty_m = $::reg_infty - 1;
t/re/pat.t: $::reg_infty_p = $::reg_infty + 1;
t/re/pat.t: $::reg_infty_m = $::reg_infty_m; # Surpress warning.
编辑2:DVK当然是正确的:它在编译时是define
d,并且可能只能用REG_INFTY
覆盖。
答案 0 :(得分:8)
总结:我有三种方法可以想到找到极限:经验,“匹配Perl测试”和“理论”。
经验:
eval {$_ **= $_ , / {$_} / for 2 .. 129};
# To be truly portable, the above should ideally loop forever till $@ is true.
$@ =~ /bigger than (-?\d+) /;
print "LIMIT: $1\n"'
这似乎很明显,不需要解释。
匹配Perl测试:
Perl对正则表达式进行了一系列测试,其中一些(在pat.t
中)处理测试这个最大值。因此,您可以估算出在这些测试中计算出的最大值“足够好”并遵循测试的逻辑:
use Config;
$reg_infty = $Config {reg_infty} // 2 ** 15 - 1; # 32767
print "Test-based reg_infinity limit: $reg_infty\n";
以下是对测试中基于何处的解释。
理论:这是试图复制C代码使用的EXACT逻辑来生成此值。
这听起来更难,因为它受到两件事的影响:Perl构建配置和一堆带有分支逻辑的C #define
语句。我能够深入研究这个逻辑,但是在两个问题上停滞不前:#ifdefs
引用了一堆令牌,这些令牌实际上并没有在我能找到的Perl代码中的任何地方定义 - 我不知道如何从Perl中找出那些define
s值是什么,以及#ifdef
的最终默认值(假设我是对的,#define PERL_USHORT_MAX ((unsigned short)~(unsigned)0)
总是以默认值结束){通过删除产生全部数字的1位来获得实际限制 - 详情如下。
我也不确定如何从Perl访问short
中的字节数,无论用于构建perl
可执行文件的实现是什么。
所以,即使可以找到这两个问题的答案(我也不确定),结果逻辑肯定会比直接的“基于经验评估的”我更加“丑陋”和复杂。作为第一选择提供。
下面我将提供Perl代码中与此限制相关的各种逻辑部分的详细信息,以及我尝试获得与C逻辑匹配的“理论正确”解决方案。
好的,这是一些调查的一部分,你可以自己完成,因为我已经运行或者我将在稍后完成:
来自regcomp.c
:vFAIL2("Quantifier in {,} bigger than %d", REG_INFTY - 1);
因此,限制显然来自REG_INFTY
定义。该声明在:
/* XXX fix this description.
Impose a limit of REG_INFTY on various pattern matching operations
to limit stack growth and to avoid "infinite" recursions.
*/
/* The default size for REG_INFTY is I16_MAX, which is the same as
SHORT_MAX (see perl.h). Unfortunately I16 isn't necessarily 16 bits
(see handy.h). On the Cray C90, sizeof(short)==4 and hence I16_MAX is
((1<<31)-1), while on the Cray T90, sizeof(short)==8 and I16_MAX is
((1<<63)-1). To limit stack growth to reasonable sizes, supply a
smaller default.
--Andy Dougherty 11 June 1998
*/
#if SHORTSIZE > 2
# ifndef REG_INFTY
# define REG_INFTY ((1<<15)-1)
# endif
#endif
#ifndef REG_INFTY
# define REG_INFTY I16_MAX
#endif
请注意SHORTSIZE可以通过Config
覆盖 - 我会留下详细信息,但逻辑需要包含$Config{shortsize}
:)
来自handy.h(乍一看似乎不是Perl源码的一部分所以它看起来像是一个不确定的步骤):
#if defined(UINT8_MAX) && defined(INT16_MAX) && defined(INT32_MAX)
#define I16_MAX INT16_MAX
#else
#define I16_MAX PERL_SHORT_MAX
我找不到定义INT16_MAX
的任何位置:(
有人请帮忙!!!
PERL_SHORT_MAX在perl.h中定义:
#ifdef SHORT_MAX
# define PERL_SHORT_MAX ((short)SHORT_MAX)
#else
# ifdef MAXSHORT /* Often used in <values.h> */
# define PERL_SHORT_MAX ((short)MAXSHORT)
# else
# ifdef SHRT_MAX
# define PERL_SHORT_MAX ((short)SHRT_MAX)
# else
# define PERL_SHORT_MAX ((short) (PERL_USHORT_MAX >> 1))
# endif
# endif
#endif
到目前为止,我找不到任何定义SHORT_MAX,MAXSHORT或SHRT_MAX的地方。所以默认为((short) (PERL_USHORT_MAX >> 1))
,现在假定它是:)
在perl.h
中,PERL_USHORT_MAX的定义非常相似,我再也无法找到USHORT_MAX
/ MAXUSHORT
/ USHRT_MAX
的定义。
这似乎暗示它默认设置为:#define PERL_USHORT_MAX ((unsigned short)~(unsigned)0)
。如何从Perl端提取该值,我不知道 - 它基本上是通过按位否定短0得到的数字,所以如果无符号短是16字节,则PERL_USHORT_MAX
将是16个,{{1将是15个,例如2 ^ 15-1,例如32767.
此外,来自t/re/pat.t
(正则表达式测试):PERL_SHORT_MAX
(用于说明存储值中非默认编译的位置)。
所以,为了得到你的常数,你可以:
$::reg_infty = $Config {reg_infty} // 32767;