cRec.balance = newBalance; //
writeCustomer(cFile, &cRec); //
} //
Fclose(cFile); // = 24*60) yyerror("Time is too large");
printf("%d minutes past midnight\n", $1);
exit(0);
}
;
spec: hour ':' minute
{ $$ = $1 + $3;
}
| hour ':' minute ampm
{ if ($1>11*60) yyerrorf "Hour out of range");
$$ = $1 + $3 + $4;
}
| hour ampm
{if ($1>11*60) yyerror("Hour out of range");
$$ = $1 + $2;
}
;
hour: hour_num
{if ($1>23) yyerror("Hour out of range");
$$ = $1 * 60;
};
minute: DIGIT DIGIT
{$$ = $1*10 + $2;
if ($$> 59) yyerrorf "minute out of range") ,
};
ampm: AM {$$ = AM_MINS;}
| PM {$$ = PM_MINS;)
;
hour num: DIGIT {$$ = $1;)
| DIGIT DIGIT {$$ = $1*10 + $2;}
;
$_ = shift;
/"(\d\d?)(am|pm)$/ && doTime($1, 0, $2, 12);
/"(\d\d?):(\d\d)(am|pm)$/ && doTime($1, $2, $3, 12);
/"(\d\d?):(\d\d)$/ && doTime($1, $2, 0, 24);
die "Invalid time $_\n";
#
# doTime(hour, min, ampm, maxHour)
#
sub doTime($$$$) {
my ($hour, $min, $offset, $maxHour) = @_;
die "Invalid hour: $hour" if ($hour>= $maxHour);
$hour += 12 if ($offset eq "pm")
print $hour*60 + $min, " minutes past midnight\n";
exit(0);
}
Лента содержит информацию, которую необходимо передать.
Известна скорость ходьбы человека.
Известно расстояние между компьютерами.
Временем, необходимым для переноса информации на ленту и с ленты, можно пренебречь.
Потери данных при хранении на ленте примерно равны их потерям при передаче по каналу связи.
my @consts;
my $name = ;
die "Invalid format missing name" unless defined($name);
chomp $name;
# Read in the rest of the file
while () {
chomp;
s/"\s*//; s/\s*$//;
die "Invalid line: $_" unless /"(\w+)$/;
push @consts, $_;
}
# Now generate the file
open(HDR, ">$name.h") or die "Can't open $name.h: $!";
open(SRC, ">$name.c") or die "Can't open $name.c: $!";
my $uc_name = uc($name);
print HDR "/* File generated automatically do not edit */\n";
print HDR "extern const char *$ {ucjiame)_name[];";
print HDR "typedef enum {\n"; print HDR join",\n", @consts;
print HDR "\n) $uc_name;\n\n";
print SRC "* File generated automatically do not
edit */\n";
print SRC "const char *$ {uc name}_name[] = {\n \"";
print SRC join "\",\n \"", @consts;
print SRC "\"\n};\n";
close(SRC);
close(HDR);
Используя принцип DRY, мы не будет вырезать и вклеивать этот вновь написанный файл в нашу программу. Вместо этого мы «включим» его данный плоский файл является главным источником этих констант. Поэтому нам понадобится файл сборки для восстановления заголовка при изменении файла. Следующий фрагмент содержится в системе отладки в исходном дереве (имеется на web-сайте).
etest.c etest.h: etest.inc enumerated.pl
perl enumerated.pl etest.inc
my $dir = shift or die "Missing directory" ,
for my Sfile (glob(u$dir/*.pr)) {
open(IP, "$file") or die "Opening $file: $!";
undef $/; # Turn off input record separator -
my Scontent = ; # read whole file as one string.
close(IP);
if (Scontent Гrusestrict/m) {
rename Sfile, "$file.bak" or die "Renaming $file: $!"; open(OP, ">$file") or die "Creating $file: $!";
# Put 'use strict' on first line that
# doesn't start #
Scontent =" sr(V.#)/\nuse strict;\n\n/m',
print OP Scontent; close(OP);
print "Updated $file\n";
)
else {
print "Sfile already strict\n":
)
}
my lang = shift or die "Missing language";
$lang .= "_cg.pm";
require or die "Couldn't load $lang";
# Read and parse the file
my $name;
while () {
chomp;
if (/^ \s*$/) {CG::blankLine();)
elsif ((/^ \#(.*)/) {CG::comment($1);}
elsif ((/^M\s*(.+)/) {CG::startMsg($1); $name = $1;}
elsif ((/^E/) {CG::endMsg($name);}
elsif (/^F\s*(\w+)\s+(\w+)$/) {CG::simpleType($1,$2);}
elsif (/^F\s*(\w+)\s+(\w+)\[(\d+)\]$/) {CG::arrayType $1,$2,$3);}
else {
die "Invalid line: $ ";
}
}
Написание языковой серверной части не составит труда: создайте модуль, который реализует шесть точек входа. Вот генератор текста на языке С:
#!/usr/bin/perl w
package CG;
use strict;
# Code generator for 'C' (see cg_base.pl)
sub blankLine() {print "\n"; }
sub comment() {print "/*$_[0] */\n"; }
sub startMsg() {print "typedef struct {\n"; }
sub endMsg() {print "} $_[0];\n\n"; }
sub arrayType() {
my ($name, $type, $size) = @_;
print " $type $name\[$size];\n":
}
sub simpleType{) {
my ($name, $type) = @_;
print " $type $пате;\п";
}
1;
А вот генератор текста на языке Pascal:
#!/usr/bin/perl w
package CG;
use strict;
# Code generator for 'Pascal' (see cg_base.pl)