加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式 perl

发布时间:2020-12-14 01:26:31 所属栏目:百科 来源:网络整理
导读:字符串操作符 .用于连接字符串 use warning 开启per内置的警告信息,或者用-w参数 use diagnostics 查看更多编译信息或者用-Mdiagnostics参数 读到文件结尾end-of-line时,返回undef标志,用defined函数是否是undef状态。 标量都是单数(singular),列表与数


字符串操作符
.用于连接字符串
use warning 开启per内置的警告信息,或者用-w参数
use diagnostics 查看更多编译信息或者用-Mdiagnostics参数

读到文件结尾end-of-line时,返回undef标志,用defined函数是否是undef状态。
标量都是单数(singular),列表与数组代表复数(plural)
列表(list)指的是标量的有序集合,而数组(array)则是存储列表的变量
或者说列表指的是数据,而数组指的是变量

$rocks[$#rocks] $rocks[-1]等效 都指最后一个

("aaa","bbb","ccc","ddd")
qw(aaa,bbb,ccc,ddd)两等效

Perl允许使用任何标点符号作为定界符,常用的有:
qw! aaa bbb ccc ddd !
qw/ aaa bbb ccc ddd /
qw# aaa bbb ccc ddd #

@arrayname 引用整个数组
push-pop操作数组尾和shift-unshift操作数组首
splice
@array = qw(aaa,ddd,eee);
@removed = splice @array,2;
#@removed变成qw(ccc,ddd)
#@array变成qw(aaa,bbb)

foreach(1..10){
print "this num is $_!n"# $_ 默认变量
}

state来声明为当前子程序的持有性私有变量,并且多次调用这个子程序期间保留该变量的值。

chomp;#不加参数,默认用默认参数$_

@ARGV #命令行默认参数

6个特殊文件句柄是Perl保留的,STDIN,STDOUT,STDERR,DATA,ARGV,ARGVOUT

数组用方括号,哈希用花括号
$hash{ 'index1' } = 'index1value';

哈希函数
$reverhash = revers %hash
my @k = keys %hash;
my @v = values %hash;
while(($key,$value) = each %hash)
{}
exists/delete

%ENV
print "PATH is $ENV{PATH}n"

正则表达式
$_ = "yabba dabba doo";
if( /abba/ )
{..}

Unicode属性,Unicode字符能够理解自身含义,它们包含字节组合之外,还附带着属性信息。
if(/q{Space}/){}
if(/q{Digit}/){}

元字符
点号(.)是能匹配任意一个字符的通配符,换行符除外。
/3.14159/这个模式中点号就不是表示通配的元字符
星号(*)正是用来匹配前面的条目零次或任意多次的
/abbt*bbb/匹配abbtbbb abbttbbb
/aaa.*bbb因此会匹配任意字符零次到无限多次
加号(+)也是量词,会匹配前一个条目一次以上
问号(?),前面条目可出现一次或不出现
模式分组
/fred*/匹配freddddd
/(fred)*/ 匹配fredfred
反向引用来引用圆括号中的模式所柳丁的文字,这个行为我们称为捕获组,
比如12表示相应顺序的捕获组
$_ = "abb";
if(/(.)1/){}#匹配 ‘bb'
/y(.)(.)21/ #匹配’abba'
“aa11bb"
111是指111,而不是1或11, Perl尽可能往多的原则靠
if(/(.)g{1}11/)指1解决反引用与直接量部分的二义性
if(/(.)111/)指111
if(/(.)(.)g{-1}11/相对自己的位置来找编号
择一匹配
/fred(|t)+barney/
字符集,指的是一组可能出现的字符,通过写在方括号([])内表示。
[abcwxyx]匹配7个字符内任意一个
[00-177] 将匹配任意一个7位的ASCII字符
[^def]会匹配这三个字符以外的任何字符^ 脱字符

字符集的简写
比如表示任意一个数字的字符集的简写是d
s简写能匹配任意空白符,所以效果上大抵等同于Unicode属性p{Space}
Perl5.6之前,s仅能匹配5个 换页符,水平制表符,换行符,回车符,空格
h只匹配水平空白符
v只匹配垂直空白符
R简写能匹配任意一种断行符
w能匹配的字符并不是严格意义上的单词字符
[^d],[^w],[^s] 非数字,非单词或者非空白符
[D],[W],[S] 大写版本表示否定意义

[dD],表示任何数字或非数字,也就是匹配任意字符(包含换行符),而点号不匹配换行符

正则表达式进行匹配
用m//进行匹配
/i进行大小写无关的匹配
/s匹配任意字符 点号无法匹配换行符,对单行点号就适用了
$_ = "I saw Barneyndown at the bowling alleynwith frednlast night.n"
if(/Barney.*Fred/s){}没有/s修饰符,匹配会失败。
/x加入空白符
/-?[0-9]+.?[0-9]*/
/ -? [0-9]+ .? [0-9]* /x#这样便于阅读,理解,但原来的空白和制表本身需要用空格和t
组合选项修饰符
if(/barney.*fred/is){}

三种字符解释方式:ASCII(/a),Unicode(/u)和locale(l),locale经常会引发问题。

锚位,可以让模式仅在字符串指定位置匹配。
A锚位匹配字符串的绝对开头,如果开头位置不匹配,是不会顺移到下一个位置继续尝试的。
m{Ahttps?://}i#判断字符串是否以https开头
m{.pngz}i#匹配以.png结尾的

字符串的绝对末尾,强调后面再无任何其他东西。 Z允许后面出现换行符
while(<STDIN>){
print if /.pngZ/;
}

while(<STDIN>){
chomp;
print "$_n" if /.pngz/;
}

可以用$锚位和/m修饰符表示对多行内容进行匹配。
/fred$/m
单词锚位
/bfredb/可匹配fred,但无法匹配frederick,alfred,manfredss。b是单词边界锚位,也称为”整词匹配“

绑定操作符=~
默认情况下模式匹配的操作对象是$_,绑定操作符(=~) 告诉perl用右边的模式来匹配左边的字符串。

模式中的内插
my $what = "larry";
while(<>){#每次读一行输入
if(/A($what)/){#模式的锚位被定在字符串的开头
print "We saw $what in beginning of $_";
}
}
除非while循环的条件表达式中只有整行输入操作符(<STDIN>),否则输入行不会被 PERL自动存入$_.

捕获变量
捕获组会把匹配圆括号中模式的字符串保存到相应的地方$1,$2,$3

$_ = "Hello there,neighbor";
if(/(S+) (S+),(S+)/){
print "word were $1 $2 $3n";
}
运行结果是:words were Hello there neighbor.
捕获变量的存续期, 它们能戚到下次成功匹配为止。失败的匹配不会改动上次成功匹配时捕获的内容。

不捕获模式:用?:修饰的圆括号不会将捕获部分的匹配字符串放到捕获变量中
if(/(?:bronto)?saurs (steak|burger){
print "Fred wants a $1n";
}

命名捕获
my $names = 'Fred or Barney';
if( $names =~ m/(?<name1>w+) (?:and|or) (?<name2>w+/){
say "i saw $+{name1} and $+{name2}";
}

自动捕获变量:$&,$`,$'免费但影响运行速度
字符串里实际匹配模式的部分会被自动在存进$&里
if( "Hello there,neighbor" =~ /s(w+),/){
print "That actually matched '$&'.n";
}
$1保存there
$&保存there,
匹配区段之前的内容会存到$`里,匹配区段之后的内容则会存到$'里

用/p修饰符则可用${^PREMATCH},${^MATCH}和${^POSTMATCH}表示。

用正则表达式处理文本
用s///进行替换
$_ = "He's out bowling with Barney tonight.";
s/Barney/Fred/;#把Barney替换为Fred
print "$_n";

s/Barney/Fred/g;#/g 全局替换
my @filelds = split /separator/,$string;
my @fields = split /:/,"abc:def:g:h";#得到("abc","def","g","h")

join函数功能与split相反
my $result = join $glue,@pieces;
my $x = join ":",4,6,8,10,12;# $x为"4:6:8:10:12"

$_ = "Hello there,neighbor";
my($first,$second,$third) = /(S+) (S+),(S+)/;
print "$second is my $thirdn";

贪婪量词
/fred.+barney/#要求能匹配的字符串越长越好
非贪婪量词
/fred.+?barney/#要求能匹配的字符串越短越好

if(flag){...}#flag为真时才执行
unless(flag){...}#flag为假时才执行

while(flag){...}#flag为真时才执行
until(flag){...}#flag为假时才执行

last操作符能立即中止循环的执行,相当C语言中的"break"
next相当continue
redo操作符返回到当前循环块的顶端,而不经过任何条件测试,也不会进入下一次循环迭代。

LINE:while(<>){
foreach(split){
last LINE if /__END__/;
...
}
}

die "Oops! A file called '$filename' already exist.n"
if -e $filename;


PERL 模块
perldoc CGI 打开模块文档
perl自带cpan命令查看所有模块: $cpan -a

模块使用MakeMaker
$perl Makefile.PL
$make install

使用Module::Build
$perl Build.PL
$./Build install

perl自带的path::class模块则提供了更友好的操作界面:
my $dir=dir( qw(Users fred lib) );
my $subdir= $dir ->subdir( 'perl5' );# Users/fred/lib/perl5

DateTime处理日期和时间的模块

chdir操作符来改变当前的工作目录

my @all_files = <*>;
my @all_files = glob "*";

Perl里面,可以使用unlink操作符,并指定要删除的文件列表。
rename函数
chmod函数类似unix的chmod命令
chmod 0755,'fred','barney';

字符串与排序
$where = index($big,$small);
$big = "Howdy world!";
$where = index($big,"wor");# $where is 6

my $part = substr($string,$initial_position,$length);
省略第三参数将取到字符串结尾
$initial_position 负数表示从后数起
substr($string,-20) =~ s/fred/barney/g;# 将后面20字符所有fred换成barney

sprintf函数与printf有相同的参数
my $date_tag = sprintf "%4d/%02d",$yr,$mo;

hex('DEA')
oct('0377')

智能匹配
use 5.010001
say "I found Fred in the name!" if $name ~~ /Fred/;
等价以下:
my $flag = 0;
foreach my $key (keys %names ){
next unless $key =~ /Fred/;
$flag = $key;
last;
}
print "I found Fred in the name!" if $flag;

given-when类似switch

given ( $ARGV[0] ){
when ( 'Fred' ){say 'Name is Fred' }
when ( /fred/i ){say 'Name has fred in it' }
defalut{say 'ss'}
}

进程管理
system 'date'; # perl调用unix的date命令。
exec

捕获错误
eval { $barney = $fred / $dino };
eval只是一个表达式,末尾加”;"
捕获到错误eval将返回undef,如果没有错误发生,$@就是空的
exit操作符会立即终止程度运行。

异常机制
die抛出异常
eval {
...;
die "An unexpected exception message" if $unexpected;
die "Bad denominator" if $dino == 0;
$barney = $fred / $dino;
}
if( $@ =~ /unexpected/ ){
...;
}
elsif( $@ =~ /denominator/ ){
...;
}

{
local $@;#不干扰高层错误
...
}

foreach( 1..1000){
push @odd_numbers,$_ if $_ % 2;
}
等价
my @odd_numbers = grep { $_ % 2 } 1..1000;

my @matching_lines = grep /bfredb/i,<$fh>;
my $line_count = @matching_lines;

my $line_count = grep /bfredb/i,<$fh>;

<!ELEMENT NXRMClientConfiguration (LocationArray,Log)>
<!ATTLIST NXRMClientConfiguration SchemaVersion CDATA #REQUIRED>
<!ATTLIST NXRMClientConfiguration SN CDATA #REQUIRED>
<!ATTLIST NXRMClientConfiguration Name CDATA #REQUIRED>
<!ATTLIST NXRMClientConfiguration UpdateDate CDATA #REQUIRED>
<!ELEMENT LocationArray (Location+)>
<!ELEMENT Location (#PCDATA)>
<!ATTLIST Location Name CDATA #Default>
<!ATTLIST Location Desc CDATA #REQUIRED>
<!ELEMENT Log (#PCDATA)>
<!ATTLIST Log MaxLogSize CDATA #REQUIRED>

#!/usr/bin/perl -w

#this sub function parser sub elment
#usage:
#$result = [];$subelement = "(A | (B,(C | (D,E))) | F)";
#Subelementparser($result,$subelement);
#return $result = AB,CB,D,EF
sub Subelementparser{
my($res,$temp)=@_;
my($prematch,$match,$postmatch);
my(@items);

$temp =~ s/s*//g;# delete space
$temp =~ s/^((.*))$/$1/e;#delete outside bracket

unless($temp =~ /(/){#case inside bracket
if($temp =~ /|/){
@items = split(/|/,$temp);
foreach (@items){
push @$res,$_;
}
}
else{
push @$res,$temp;
}
}
else{#case:there exist is one or more bracket
$temp =~ m/((.*))/;
$prematch = ${^PREMATCH};
$match = ${^MATCH};
$postmatch = ${^POSTMATCH};

$flag = "false";
if($prematch =~ /,/){
$flag = "true";
}

if($flag =~ /true/){#case: B,(D|E)
my($tempres) = [];
Subelementparser($tempres,$match);
foreach (@$tempres){
push @$res,"${prematch}$_";# $prematch = "B,"
}
}
else{
@items = split(/|/,$prematch);
foreach (@items){
push @$res,"$_";
}
if($match =~ /./){
Subelementparser($res,$match);
}
}

@items = split(/|/,$postmatch);
foreach (@items){
if(/./){
push @$res,$_;
}
}
}
}

sub ProcElement {
my($cname,$expan)=@_;
my($cinterdef,$cimpheader,$cimpcpp);
my($construc,$parser);
my($mem);
my($headerfile,$class_name);

my($subelements) = [];
Subelementparser($subelements,$expan);

# here start generate .h file without attribute part and } end part
$cinterdef = "// <!ELEMENT ${cname} ${expan}>n";
$cinterdef .= "class I$cnamen{npublic:n";
$cinterdef .= "tvirtual bool WriteToXML(const std::string& XMLPath) = 0;n";
$cinterdef .= "tvirtual bool ReadFromXML(const std::string& XMLPath) = 0;n";
$cinterdef .= "tvirtual void Reset(void) = 0;n";
$cinterdef .= "tvirtual void Release(void) = 0;nn";

$construc = "";

$cimpheader = "class $cname : public I$cnamen{npublic:n";
$cimpheader .= "t$cname(void);n";
$cimpheader .= "t$cname(const Node& node);n";
$cimpheader .= "t~$cname(void);n";
$cimpheader .= "tbool WriteToXML(const std::string& XMLPath);n";
$cimpheader .= "tbool ReadFromXML(const std::string& XMLPath);n";
$cimpheader .= "tvoid Reset(void);n";
$cimpheader .= "tvoid Release(void);nn";

$cimpcpp = "${cname}::${cname}() : m_node(Node())n{ntm_node.SetNodeName("${cname}");n}nn";
$cimpcpp .= "${cname}::${cname}(const Node& node) : m_node(node)n{ntm_node.SetNodeName("${cname}");n}nn";
$cimpcpp .= "${cname}::~${cname}(void)n{n}nn";
$cimpcpp .= "bool ${cname}::WriteToXML(const std::string& XMLPath)n{ntreturn m_node.Print(XMLPath);n}nn";
$cimpcpp .= "bool ${cname}::ReadFromXML(const std::string& XMLPath)n{ntm_node = Node(XMLPath);ntreturn true;n}nn";
$cimpcpp .= "void ${cname}::Reset(void)n{ntm_node = Node();ntm_node.SetNodeName("${cname}");n}nn";
$cimpcpp .= "void ${cname}::Release(void)n{ntdelete this;n}nn";

foreach (@$subelements){
@subclass = split(/,/,$_);
#$cdef .= "t$cname(";
#$flag = "false";
foreach $mem (@subclass){
if($mem =~ /[?*+]/){
$mem =~ s/[*+?]//g;
$cinterdef .= "t//Element $memn";
$cinterdef .= "tvirtual unsigned int GetElem${mem}(void) = 0;n";
$cinterdef .= "tvirtual I${mem}* GetElem${mem}At(unsigned int index) = 0;n";
$cinterdef .= "tvirtual void AddElem${mem}(I${mem}* NewElem) = 0;n";
$cinterdef .= "tvirtual void AddElem${mem}At(unsigned int index,I${mem}* NewElem) = 0;n";
$cinterdef .= "tvirtual void RemoveElem${mem}At(unsigned int index) = 0;n";
$cinterdef .= "tvirtual void RemoveAllElem${mem}(void) = 0;nn";

$cimpheader .= "t//Element $memn";
$cimpheader .= "tunsigned int GetElem${mem}(void);n";
$cimpheader .= "tI${mem}* GetElem${mem}At(unsigned int index);n";
$cimpheader .= "tvoid AddElem${mem}(I${mem}* NewElem);n";
$cimpheader .= "tvoid AddElem${mem}At(unsigned int index,I${mem}* NewElem);n";
$cimpheader .= "tvoid RemoveElem${mem}At(unsigned int index);n";
$cimpheader .= "tvoid RemoveAllElem${mem}(void);nn";

$cimpcpp .= "//Element $memn";
$cimpcpp .= "unsigned int ${cname}::GetElem${mem}(void)n{ntreturn m_node.NumChilds();n}nn";
$cimpcpp .= "I${mem}* ${cname}::GetElem${mem}At(unsigned int index)n{n";
$cimpcpp .= "t${mem} *temp = NULL;ntunsigned int total = m_node.NumChilds();ntif(index < total)nt{n";
$cimpcpp .= "tttemp = new ${mem}(m_node.GetChildAt(index));nt}ntreturn temp;n}nn";
$cimpcpp .= "void ${cname}::AddElem${mem}(I${mem}* NewElem)n{ntm_node.AppendChild(static_cast<${mem}*>(NewElem)->m_node);n}nn";
$cimpcpp .= "void ${cname}::AddElem${mem}At(unsigned int index,I${mem}* NewElem)n{ntm_node.AppendChildAt(index,static_cast<${mem}*>(NewElem)->m_node);n}nn";
$cimpcpp .= "void ${cname}::RemoveElem${mem}At(unsigned int index)n{ntm_node.RemoveChildAt(index);n}nn";
$cimpcpp .= "void ${cname}::RemoveAllElem${mem}(void)n{ntm_node.RemoveChilds();n}nn";
}
elsif($mem =~ /#PCDATA/){
}
else{
$cinterdef .= "t//Element $memn";
$cinterdef .= "tvirtual I${mem}* GetElem${mem}(void) = 0;n";
$cinterdef .= "tvirtual void SetElem${mem}(I${mem}* ElemName) = 0;nn";

$cimpheader .= "t//Element $memn";
$cimpheader .= "tI${mem}* GetElem${mem}(void);n";
$cimpheader .= "tvoid SetElem${mem}(I${mem}* ElemName);nn";

$cimpcpp .= "//Element $memn";
$cimpcpp .= "I${mem}* ${cname}::GetElem${mem}(void)n{ntreturn new ${mem}(m_node.GetFirstChild());n}nn";
$cimpcpp .= "void ${cname}::SetElem${mem}(I${mem}* ElemName)n{ntm_node.AppendChild(static_cast<${mem}*>(ElemName)->m_node);n}nn";
}
}
}
my(%hash) = ();
undef %hash;
foreach (@$subelements){
@subclass = split(/,$_);
foreach $mem (@subclass){
if(/#PCDATA/){
#$cdef .= "tvoid addData( const std::string& data );n";
}
else{
unless(exists( $hash{ $mem} ))
{
#$cdef .= "tvoid addNode( $mem *the_$mem );n";

$mem =~ s/[*+?]//g;
$headerfile .= "#include "${mem}.h"n";
$class_name .= "class I${mem};n";
$hash{$mem} = 1;
}
}
}
}
if($rootflag =~ /false/)
{
$construc .= "nconst char* dtdData = "$tempdtd";nn";
#$cdef .= "tbool Validate() const;n";
#$cdef .= "t$cname(const std::string& XMLFile);n";
}
#$cdef .= "};nn";#wait for attribute

# here start generate .cpp file

undef %hash;
foreach (@$subelements){
$construc .= "${cname}::${cname}(";
@subclass = split(/,$_);
$flag = "false";
foreach $mem (@subclass){
if( $flag =~ /true/ ){
$construc .= ",";
}
if(/#PCDATA/){
$construc .= " const std::string& data";
$parser.= "void ${cname}::addData(const std::string& data)n{n";
$parser .= "tSetData(data);n}nn";
}
else{
$construc .= " $mem *the_$mem";
unless(exists( $hash{ $mem} ))
{
$parser.= "void ${cname}::addNode($mem *the_$mem)n{n";
$parser.= "tAppendChild(*the_$mem);n}nn";
$hash{$mem} = 1;
}
}
if( $flag =~ /false/ ){
$flag = "true";
}
}

if($rootflag =~ /false/)
{
$parser .= "bool ${cname}::Validate() constn{n";
$parser .= "treturn ValidateDTD(dtdData);n";
$parser .= "}nn";
$parser .= "${cname}::${cname}(const std::string& XMLFile):Node(XMLFile)n{n";
$parser .= "}nn";
$rootflag = "true";
}


$construc .= " ):Node()n{n";
$construc .= "tSetNodeName("${cname}");n";
foreach $mem (@subclass){
if(/#PCDATA/){
$construc .= "taddData(data);n";
}
else{
$construc .= "tAppendChild(*the_$mem);n";
}
}
$construc .= "}nn";
}

push(@classes,$cname);
$interfacefile{ $cname } = $cinterdef;
$implementheaderfile{ $cname } = $cimpheader;
$implementcppfile { $cname } = $cimpcpp;

#$constructors{ $name } = $construc;
#$parsersvec{ $name } = $parser;
$headerlist{ $cname } = $headerfile;
$classdeflist{ $cname } = $class_name;
}

sub ProcAttList {
my($name,$attribs)=@_;
my($attrib,$atype,$ctype,$condit,$options,$deft);
my(@options);
my($builder);
my($elemtype,$arrlen,$subparse,$req);

die "ATTLIST $name without ELEMENTn" if(!defined($interfacefile{ $name }));

# bin some whitespace
$attribs =~ s/^s*//;
$attribs =~ s/s*$//;

while(1){
if($attribs =~ /^(w+)s+(w+)s+#(w+)s*(.*)/){# basic; whatever type
$attrib=$1;
$atype=$2;
$condit=$3;
$attribs=$4;

$interfacefile{ $name} .= "t//Get/Set functions for attribute $attribn";
$interfacefile{ $name} .= "tvirtual std::string Get$attrib(void) = 0;n";
$interfacefile{ $name} .= "tvirtual void Set$attrib( const std::string& value ) = 0;n";

$implementheaderfile{ $name} .= "t//Get/Set functions for attribute $attribn";
$implementheaderfile{ $name} .= "tstd::string Get$attrib(void);n";
$implementheaderfile{ $name} .= "tvoid Set$attrib( const std::string& value );n";

$implementcppfile{ $name} .= "//Get/Set functions for attribute $attribn";
$implementcppfile{ $name} .= "std::string ${name}::Get$attrib(void)n{ntreturn m_node.GetAttribute("$attrib");n}nn";
$implementcppfile{ $name} .= "void ${name}::Set$attrib( const std::string& value )n{ntm_node.SetAttribute("$attrib",value);n}nn";

$builder .= "void ${name}::Set$attrib( const std::string& value ){ntSetAttribute("$attrib",value);n}nn";

#$attributparser{ $name } .= $builder;
}
else{
last;
}
}
}


# dtd on command line
$flag = "false";
$dtdf = undef();
my($curdir) = `pwd`;
chomp($curdir);
my($outdir) = undef();

my($cppfilename) = "xml_nxl";

$count = @ARGV;
if($count == 1){
if($ARGV[0] =~ m{.dtdz}i){
$dtdf = $ARGV[0];
}
else{
$flag = "true";
}
}
elsif($count == 3){
if($ARGV[0] =~ m{A-o}i){
$outdir = $ARGV[1];
$dtdf = $ARGV[2];
}
else{
$flag = "true";
}
}
else{
$flag = "true";
}

die "Usage: dtd2cpp.pl [switches] <document>
-o <directory> Outputdir - specify output directory
-h Help - Show Class Generator usage helpn" if ($flag =~ /true/);

if(defined($outdir)){
die "the directory ${outdir} don't exist!!!n" unless(-e ${outdir});
if($outdir =~ m{/z}){
mkdir "${outdir}/include",0700;
mkdir "${outdir}/src",0700;
}
else{
mkdir "${outdir}/include",0700;
}
}
else{
if($dtdf =~ /(.*)/(.*)/){
$outdir = $1;
mkdir "${outdir}/include",0700;
}
else{
$outdir = $curdir;
mkdir "${outdir}/include",0700;
}
}

# input filename
open(DTD,$dtdf) || die "can't read $dtdf: $!n";
$dtd=join('',<DTD>);
close(DTD);

$namespacename = "NxconInterface";
@classes=();

%interfacefile=();
%implementheaderfile=();
%implementcppfile=();

#%constructors=();
#%attributparser=();
#%parsersvec=();
#%headerlist=();
%classdeflist=();


$rootflag = "false";

sub GenerateTargetFile{
my($oriname)=@_;
my($intername) = ();
my($headername) = ();
my($cppname) = ();

# here generate interface header file
$intername = "I$oriname";
open (${intername},">${intername}.h") || die "Can't write ${intername}.h: $!n";
print ${intername} "// this is generated code,do not editn";
print ${intername} "#pragma oncenn";
print ${intername} "#include <string>nn";
#print ${name} "#include "nxl_xml_node.h"n";
print ${intername} $headerlist{ $oriname } if defined($headerlist{ $oriname });
print ${intername} "namespace ${namespacename}n{n";
#debug output message
print "${intername}n";
print ${intername} "$classdeflist{ $oriname }n" if defined($classdeflist{ $oriname });
print ${intername} $interfacefile{ $oriname } . "};nn";
print ${intername} "extern "C" ${intername}* ${intername}_CreateNewInstance(void);nn}n";
close(${intername});

# here generate implement header file
$headername = "$oriname";
open (${headername},">${headername}.h") || die "Can't write ${headername}.h: $!n";
print ${headername} "// this is generated code,do not editn";
print ${headername} "#pragma oncenn";
print ${headername} "#include "I${headername}.h"n";
print ${headername} "#include "nxl_xml_node.h"n";
print ${headername} "namespace ${namespacename}n{n";
print ${headername} $implementheaderfile{ $headername };
#print ${headername} "nprivate:ntNode m_node;n};nn}n";
print ${headername} "ntNode m_node;n};nn}n";
close(${headername});

$cppname = $oriname;
# here generate implement cpp file
open (${cppname},">${cppname}.cpp") || die "Can't write ${cppname}.cpp: $!n";
print ${cppname} "// this is generated code,do not editnnn";
print ${cppname} "#include "${cppname}.h"nn";
print ${cppname} "namespace ${namespacename}n{n";
#print ${name} $constructors{ ${name} } ;
#print ${name} $parsersvec{ ${name} } ;
#print ${name} $attributparser{ ${name} } if(defined($attributparser{ ${name} }));
print ${cppname} $implementcppfile{ ${cppname} };
print ${cppname} "nI${cppname}* I${cppname}_CreateNewInstance(void)n{ntreturn new ${cppname}();n}n";
print ${cppname} "};n";
close(${cppname});
use File::Copy ;
use strict ;
move("${curdir}/${intername}.h","${outdir}/include/${intername}.h")||warn "could not copy files :$!" ;
move("${curdir}/${headername}.h","${outdir}/include/${headername}.h")||warn "could not copy files :$!" ;
move("${curdir}/${cppname}.cpp","${outdir}/src/${cppname}.cpp")||warn "could not copy files :$!" ;
}
$tempdtd = $dtd;
$tempdtd =~ s/rn//g;

$dtd =~ s/n/''/ge;

# run thru the DTD
while(1){
$dtd =~ s/^(.*?)</</;
#$dtd =~ s/[*+?]//g;
if($dtd =~ /^<(.*?)>(.*)$/){
$elem=$1;
$dtd=$2;
if($elem =~ /^!s+(w+)s+(.*)/){
print "==>ELEMENT $1,$2n";
ProcElement($1,$2);
}
elsif($elem =~ /^!s+(w+)s+(.*)/){
#print "ATTLIST $1n";
ProcAttList($1,$2);
}
elsif($elem =~ /^!--.*--$/){
#print "commentn";
}
else {
print "2222222222111n";
warn "can't understand $elemn";
}
}
else{
print "parser overn" if defined($elem);
last;
}
}

# class declarations & code
for(@classes){
GenerateTargetFile($_);
}

# generate Makefile file
open(MAKEFILE,">Makefile") || die "Can't write Makefile: $!n";
print MAKEFILE "#
# ! Don't modify this file
# Modify Makefile.inc instead
#
ifeq ($(NLBUILDROOT),)
$(error NLBUILDROOT undefined.)
endif

ifeq ($(NLEXTERNALDIR),)
$(error NLEXTERNALDIR undefined.)
endif

#
# Following master make file can be included:
# - master.cxx.mak
# - master.csharp.mak
# - master.java.mak
#
$(info Include master makefile: $(NLBUILDROOT)/scripts/make/master.cxx.mak)
include $(NLBUILDROOT)/scripts/make/master.cxx.mak
";
close(MAKEFILE);
move("${curdir}/Makefile","${outdir}/Makefile")||warn "could not copy files :$!" ;

# generate Makefile.inc file
open(MAKEFILEINC,">Makefile.inc") || die "Can't write Makefile: $!n";
print MAKEFILEINC
"
##############################################################################
#
# The Makefile.inc will be used by master Makefile
# under NLBUILDROOT/scripts/make directory.
#
##############################################################################

#
# The name of the target
#
TARGET_NAME=nxxmlconfig
$(info Makefile.inc for project $(TARGET_NAME))


#
# VERSION
#
VERSION_PRODUCT= $(VERSION_PRODUCT_RMP)
VERSION_MAJOR= $(VERSION_MAJOR_RMP)
VERSION_MINOR= $(VERSION_MINOR_RMP)
VERSION_MAINTENANCE = $(VERSION_MAINTENANCE_RMP)
VERSION_PATCH= $(VERSION_PATCH_RMP)

#
# The type of target,could be one of following values:
# - exe: An executable file
# - lib: A static library (user/kernel mode)
# - dll: A dynamic link library (user/kernel mode)
# - sys: A kernel driver
#
TARGET_TYPE=dll

#
# The run mode of target
# - kernel
# - user
#
TARGET_MODE=user

# Make sure the sys target run at kernel mode
ifeq ($(TARGET_TYPE),sys)
ifeq ($(TARGET_MODE),user)
$(error A sys target must run at kernel mode.)
endif
endif


#
# Additional settings for EXE
#
ifeq ($(TARGET_TYPE),exe)

# Application type: CONSOLE or WIN32
# console: this is a console application
# win32: this is a win32 application
EXE_TYPE = console

#
# Do we need to elevate privilege?
# - Invoke
# - Administrator
#
EXE_PRIVILEGE = Invoke

#
# Is this a test app?
# - yes
# - no or empty
#
#EXE_TESTAPP = yes

endif

#
# Source file
#
SRC = ";
foreach (@classes){
print MAKEFILEINC "
src/$_.cpp";
}

print MAKEFILEINC "
src/nxl_xml_node.cpp

#
# Resource file
# If this variable is empty,a default rc file will be used automatically
#
RCSRC =


#
# Additional include directories
#
INCPATH +=
$(NLEXTERNALDIR)/libxml2-2.7.8.win32/include
$(NLEXTERNALDIR)/libxml2-2.7.8.win32/include/libxml
$(NLEXTERNALDIR)/boost/boost_1_55_0

#
# Additional library directories
#
LIBPATH +=
$(NLEXTERNALDIR)/libxml2-2.7.8.win32/lib
$(NLEXTERNALDIR)/boost/boost_1_55_0/libs/$(BINDIR)
$(NLBUILDROOT)/bin/$(BINDIR)


#
# Additional librarys
#
LIBS +=
libxml2

";
close(MAKEFILEINC);
move("${curdir}/Makefile.inc","${outdir}/Makefile.inc")||warn "could not copy files :$!" ;

# generate nxxmlconfig.def file
open(DEFFILE,">nxxmlconfig.def") || die "Can't write nxxmlconfig.def: $!n";
print DEFFILE "EXPORTSn";
foreach $tem(@classes){
print DEFFILE "tI${tem}_CreateNewInstancen";
}
close(DEFFILE);
move("${curdir}/nxxmlconfig.def","${outdir}/src/nxxmlconfig.def")||warn "could not copy files :$!" ;

# generate nxxmlconfig_helper.h file
open(HELPERFILE,">nxxmlconfig_helper.h") || die "Can't write nxxmlconfig_helper.h: $!n";
print HELPERFILE "#pragma oncenn";
foreach (@classes){
print HELPERFILE "#include "I$_.h"n";
}
close(HELPERFILE);
move("${curdir}/nxxmlconfig_helper.h","${outdir}/include/nxxmlconfig_helper.h")||warn "could not copy files :$!" ;

#testtest only for test need,copy main.cpp nxl_xml_node.cpp nxl_xml_node.h copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/nxl_xml_node.cpp","${outdir}/src/nxl_xml_node.cpp" ) || warn "could not copy files:$!"; copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/nxl_xml_node.h","${outdir}/include/nxl_xml_node.h" ) || warn "could not copy files:$!"; #testtest copy libxml dlls unless ( -e "${outdir}/debug_win_x86" ){ mkdir "${outdir}/debug_win_x86",0700; } copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/iconv.dll","${outdir}/debug_win_x86/iconv.dll" ) || warn "could not copy files:$!"; copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/zlib1.dll","${outdir}/debug_win_x86/zlib1.dll" ) || warn "could not copy files:$!"; copy("C:/Snow/Ruby/dev/ruby_starter_140507/common/libxml2.dll","${outdir}/debug_win_x86/libxml2.dll" ) || warn "could not copy files:$!";

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读