【发布时间】:2016-08-12 02:16:41
【问题描述】:
我正在为John Tromp's Binary Lambda Calculus 写一个简单的翻译器到 De Bruijn Notation Lambda Calculus,这样我就可以了解他的 Lambda 文件在他的2012 "Most Functional" International Obfuscated C Code winner 中是如何工作的
这里是翻译前的语言示例primes.blc:
00010001100110010100011010000000010110000010010001010111110111101001000110100001110011010000000000101101110011100111111101111000000001111100110111000000101100000110110
我在 Bruijn.pl 的 primes.txt 文件保存部分之前的注释行中遇到了嵌套正则表达式的问题:
#!/usr/bin/env perl
#use strict;
use warnings;
use IO::File;
use Cwd; my $originalCwd = getcwd()."/";
#primes.blc as argument for test conversion
#______________________________________________________________________open file
my ($name) = @ARGV;
$FILE = new IO::File;
$FILE->open("< ".$originalCwd."primes.blc") || die("Could not open file!");
#$FILE->open("< ".$name) || die("Could not open file!");
while (<$FILE>){ $field .= $_; }
$FILE->close;
#______________________________________________________________________Translate
$field =~ s/(00|01|(1+0))/$1 /gsm;
$field =~ s/00 /\\ /gsm;
$field =~ s/01 /(a /gsm;
$field =~ s/(1+)0 /length($1)." "/gsme;
$RecursParenthesesRegex = m/\(([^()]+|(??{$RecursParenthesesRegex}))*\)/;
#$field =~ 1 while s/(\(a){1}(([\s\\]+?(\d+|$RecursParenthesesRegex)){2})/\($2\)/sm;
#______________________________________________________________________save file
#$fh = new IO::File "> ".$name;
$fh = new IO::File "> ".$originalCwd."primes.txt";
if (defined $fh) { print $fh $field; $fh->close; }
翻译后的文件primes.txt应该是什么:
\ (\ (1 (1 ((\ (1 1) \ \ \ ((1 \ \ 1) (\ (((4 4) 1) (\ (1 1) \ (2 (1 1)))) \ \ \ \ ((1 3) (2 (6 4)))))) \ \ \ (4 (1 3))))) \ \ ((1 \ \ 2) 2))
当前注释掉的行转换为几乎可读的格式,如下所示:
\ (a \ (a 1 (a 1 (a (a \ (a 1 1 \ \ \ (a (a 1 \ \ 1 (a \ (a (a (a 4 4 1 (a \ (a 1 1 \ (a 2 (a 1 1 \ \ \ \ (a (a 1 3 (a 2 (a 6 4 \ \ \ (a 4 (a 1 3 \ \ (a (a 1 \ \ 2 2
这需要找到(a 的最内层抽象以及数字或匹配括号中的 2 及其所有内容,并插入尾随 ) 并删除 a 一直到最外层的应用程序。
【问题讨论】:
-
与其注释掉
use strict,不如让你的代码在严格打开的情况下通过。您还有一堆不需要 Time::HiRes。请只显示minimal reproducible example。 -
或许,
$RecursParenthesesRegex = m/(?<rec>\((?>[^()]++|(?&rec))*\))/; -
@simbabque 它是由我的模板 perl 文件制作的,我的错我会编辑帖子。
-
@MJSuriya:如果 OP 为您在源代码中添加行号,则意味着其他所有想要运行代码的人都必须删除它们。第 22 行是以
$field =~ 1 while开头的那一行 -
您为什么使用
IO::File而不仅仅是open?并且当它们对模式没有影响时,请不要使用正则表达式/m和/s修饰符。你的代码已经够复杂了
标签: regex perl recursion nested