小编msw*_*erg的帖子

Lexing/Parsing"here"文件

对于那些是lexing和解析专家的人......我试图在perl中编写一系列程序来解析IBM大型机z/OS JCL用于各种目的,但是我在方法论上遇到了障碍.我主要遵循Mark Jason Dominus在"高阶Perl"中提出的lexing/parsing意识形态,但有些事情我不知道该怎么做.

JCL具有所谓的内联数据,这与"此处"文档非常相似.我不太确定如何把它们变成令牌.

内联数据的布局如下:

//DDNAME   DD *
this is the inline data
this is some more inline data
/*
...
Run Code Online (Sandbox Code Playgroud)

通常,"DD"之后的"*"表示后续行是内联数据本身,由"/*"或下一个有效JCL记录(前两列中以"//"开头)终止.

更高级,内联数据可能如下所示:

//DDNAME   DD *,DLM=ZZ
//THIS LOOKS LIKE JCL BUT IT'S ACTUALLY DATA
//MORE DATA MASQUERADING AS JCL
ZZ
...
Run Code Online (Sandbox Code Playgroud)

有时,内联数据本身就是JCL(可能被抽到一个程序或内部读者,无论如何).

但这就是问题所在.在JCL中,记录是80个字节,长度固定.第72栏(第73-80栏)的所有内容都是"评论".同样,跟随有效JCL的空白之后的所有内容同样是评论.由于我希望在我的程序中操作JCL并将其吐出来,我想捕获注释以便我可以保留它们.

所以,这是内联数据中的内联注释的示例:

//DDNAME   DD *,DLM=ZZ THIS IS A COMMENT                                COL73DAT
data
...
ZZ
...more JCL
Run Code Online (Sandbox Code Playgroud)

我原本以为我可以让我最顶级的词法分析器拉入JCL系列并立即为cols 1-72创建一个非令牌,然后为第73列注释创建一个令牌(['COL73COMMENT',$ 1]),如果任何.然后,这将向下游传递给下一个迭代器/标记生成器,其中包含cols 1-72文本的字符串,后跟col73标记.

但是,从那里下游,我将如何获取内联数据?我原本认为最顶级的标记器可能会寻找"DD\*(,DLM =(\ S*))"(等),然后继续从进给迭代器中提取记录,直到它达到分隔符为止或有效的JCL启动器("//").

但是你可能会在这里看到问题...我不能拥有2个最顶级的标记符...要么寻找COL73注释的标记生成器必须是顶部,要么获取内联数据的标记生成器必须位于顶部.

我认为perl解析器有同样的挑战,因为看到了

<<DELIM

不一定是该行的结尾,其次是此处的文档数据.毕竟,你可以看到perl像:

my $this=$obj->ingest(<<DELIM)->reformat();
inline here document data
more data
DELIM
Run Code Online (Sandbox Code Playgroud)

令牌化器/解析器如何知道标记化") - …

perl parsing jcl

15
推荐指数
1
解决办法
610
查看次数

匿名哈希切片 - 语法?

我喜欢哈希切片并经常使用它们:

my %h;
@h{@keys}=@vals;
Run Code Online (Sandbox Code Playgroud)

工作出色!但有两件事总是让我烦恼.

首先,是否可以将上面的两行组合成一行代码?声明哈希并立即填充它会很好.

其次,是否可以对现有的匿名哈希进行切片...类似于:

my $slice=$anonh->{@fields}
Run Code Online (Sandbox Code Playgroud)

perl

9
推荐指数
2
解决办法
1209
查看次数

Perl OOP属性操作最佳实践

假设以下代码:

package Thing;
sub new {
    my $this=shift;
    bless {@_},$this;
}
sub name {
    my $this=shift;
    if (@_) {
        $this->{_name}=shift;
    }
    return $this->{_name};
}
Run Code Online (Sandbox Code Playgroud)

现在假设我们已经实例化了一个对象:

my $o=Thing->new();
$o->name('Harold');
Run Code Online (Sandbox Code Playgroud)

够好了.我们还可以使用以下任一方法更快地实例化相同的事情:

my $o=Thing->new(_name=>'Harold');  # poor form
my $o=Thing->new()->name('Harold');
Run Code Online (Sandbox Code Playgroud)

可以肯定的是,我允许在构造函数中传递属性,以允许"友好"类更完整地创建对象.它还可以允许克隆类型运算符使用以下代码:

my $o=Thing->new(%$otherthing);  # will clone attrs if not deeper than 1 level
Run Code Online (Sandbox Code Playgroud)

这一切都很好.我理解需要隐藏方法背后的属性以允许验证等.

$o->name;  # returns 'Harold'
$o->name('Fred'); # sets name to 'Fred' and returns 'Fred'
Run Code Online (Sandbox Code Playgroud)

但是这不允许基于自身轻松操纵属性,例如:

$o->{_name}=~s/old/ry/;  # name is now 'Harry', but this "exposes" the attribute
Run Code Online (Sandbox Code Playgroud)

一种替代方法是执行以下操作:

# Cumbersome, not syntactically …
Run Code Online (Sandbox Code Playgroud)

oop perl

7
推荐指数
1
解决办法
518
查看次数

在qw中保留白色空间

有没有办法在qw中保留一些空白?例如:

my @a=qw(1234 John Smith 123 Main St.);
Run Code Online (Sandbox Code Playgroud)

将生成一个包含6个元素的数组.有没有办法,哦,我不知道......逃离白色空间保留一些吗?就像是:

my @a=qw(1234 John\ Smith 123\ Main\ St.);
Run Code Online (Sandbox Code Playgroud)

返回3个元素:'1234','John Smith','123 Main St.'?

(仅供参考,我已尝试过以上内容,也有不同的报价组合,但都无济于事)

perl

5
推荐指数
2
解决办法
2520
查看次数

typeglob别名

好的,所以创建对数组的引用很容易......

my @a;
my $b=\@a;
#can now reference the same list of scalars from either @$b or @a
Run Code Online (Sandbox Code Playgroud)

但是我怎么能这样做呢?例如:

my $a=[1..4];
my @b;
#some magic happens here and now @b is an alias for @$a
@b=(6..10);
print "@$a\n";  #should print "6 7 8 9 10"
Run Code Online (Sandbox Code Playgroud)

我认为这会通过typeglobs发生,但那些只是躲避我.想法?

对哈希和数组做同样的事情也会很好.

编辑:这似乎工作,但它有点kludgy因为它只是将anon数组元素复制到"别名",然后重新指向数组:

my @b=@$a;
$a=\@b;
Run Code Online (Sandbox Code Playgroud)

有更好的想法吗?

perl

3
推荐指数
2
解决办法
2005
查看次数

@ISA vs use base vs use parent

穿过这个小金块......我想我已经弄清楚了,但看看是否有人可以放下更多的光.

我在PERL5LIB环境变量中有一个用于记录的模块.它在e:/Scripts/Log/Logger.pm.以下是摘录:

package Log::Logger;
...

package Log::NullLogger;
use base 'Log::Logger';
...

package Log::FileLogger;
use base 'Log::Logger';
...

package Log::DateFileLogger;
use base 'Log::FileLogger';
...

package LogTester;
use Data::Dump 'dump';
test() unless caller();
sub test {
    warn dump \%INC;
    ...
}
Run Code Online (Sandbox Code Playgroud)

我想对这个模块进行一些更改,所以我将其复制到e:/Test/Log/Log/Logger.pm并开始进行更改和测试...我添加了一个新类并更改了Log::Logger包中的继承例程...

package BasicFormatter;
...
Run Code Online (Sandbox Code Playgroud)

但我的测试很奇怪.一些新代码正在使用,有些则没有.转储%INC有:

"Log/Logger.pm" => "e:/Scripts/Log/Logger.pm"
Run Code Online (Sandbox Code Playgroud)

...... 旧模块!从我可以告诉,use base 'Log::Logger'走了出去,并重新加载Log/Logger.pmPERL5LIB,替换只有在它的包装(即package BasicFormatter由新模块来了,但其他所有的包都是从旧的模块).

我读到了use parent,当我替换我时use base,use parent …

perl

2
推荐指数
2
解决办法
613
查看次数

标签 统计

perl ×6

jcl ×1

oop ×1

parsing ×1