use strict;
my $errors = 0;
my $path;
sub error(@)
{
print STDERR @_;
$errors = 1;
}
if (@ARGV)
{
$path = $ARGV[0];
shift @ARGV;
}
else
{
$path = ".";
}
$, = ' ';
$\ = "\n";
my %keyword_categories;
$keyword_categories{'unreserved_keyword'} = 'UNRESERVED_KEYWORD';
$keyword_categories{'col_name_keyword'} = 'COL_NAME_KEYWORD';
$keyword_categories{'type_func_name_keyword'} = 'TYPE_FUNC_NAME_KEYWORD';
$keyword_categories{'reserved_keyword'} = 'RESERVED_KEYWORD';
my $gram_filename = "$path/src/common/backend/parser/gram.y";
open(GRAM, $gram_filename) || die("Could not open : $gram_filename");
my ($S, $s, $k, $n, $kcat);
my $comment;
my @arr;
my %keywords;
line: while (<GRAM>)
{
chomp;
$S = $_;
$s = '{', $S =~ s/$s/ { /g;
$s = '}', $S =~ s/$s/ } /g;
$s = '[/][*]', $S =~ s
$s = '[*][/]', $S =~ s
if (!($kcat))
{
foreach $k (keys %keyword_categories)
{
if ($S =~ m/^($k):/)
{
$kcat = $k;
next line;
}
}
next line;
}
$n = (@arr = split(' ', $S));
for (my $fieldIndexer = 0; $fieldIndexer < $n; $fieldIndexer++)
{
if ($arr[$fieldIndexer] eq '*/' && $comment)
{
$comment = 0;
next;
}
elsif ($comment)
{
next;
}
elsif ($arr[$fieldIndexer] eq '/*')
{
$comment = 1;
next;
}
elsif ($arr[$fieldIndexer] eq '//')
{
next line;
}
if ($arr[$fieldIndexer] eq ';')
{
$kcat = '';
next;
}
if ($arr[$fieldIndexer] eq '|')
{
next;
}
push @{ $keywords{$kcat} }, $arr[$fieldIndexer];
}
}
close GRAM;
my ($prevkword, $kword, $bare_kword);
foreach $kcat (keys %keyword_categories)
{
$prevkword = '';
foreach $kword (@{ $keywords{$kcat} })
{
$bare_kword = $kword;
$bare_kword =~ s/_P$//;
if ($bare_kword le $prevkword)
{
error
"'$bare_kword' after '$prevkword' in $kcat list is misplaced";
$errors = 1;
}
$prevkword = $bare_kword;
}
}
my %kwhashes;
while (my ($kcat, $kcat_id) = each(%keyword_categories))
{
@arr = @{ $keywords{$kcat} };
my $hash;
foreach my $item (@arr) { $hash->{$item} = 1 }
$kwhashes{$kcat_id} = $hash;
}
my $kwlist_filename = "$path/src/include/parser/kwlist.h";
open(KWLIST, $kwlist_filename) || die("Could not open : $kwlist_filename");
my $prevkwstring = '';
my $bare_kwname;
my %kwhash;
kwlist_line: while (<KWLIST>)
{
my ($line) = $_;
if ($line =~ /^PG_KEYWORD\(\"(.*)\", (.*), (.*)\)/)
{
my ($kwstring) = $1;
my ($kwname) = $2;
my ($kwcat_id) = $3;
if ($kwstring le $prevkwstring)
{
error
"'$kwstring' after '$prevkwstring' in kwlist.h is misplaced";
}
$prevkwstring = $kwstring;
if ($kwstring !~ /^[a-z_]*$/)
{
error
"'$kwstring' is not a valid keyword string, must be all lower-case ASCII chars";
}
if ($kwname !~ /^[A-Z_]*$/)
{
error
"'$kwname' is not a valid keyword name, must be all upper-case ASCII chars";
}
$bare_kwname = $kwname;
$bare_kwname =~ s/_P$//;
if ($bare_kwname ne uc($kwstring))
{
error
"keyword name '$kwname' doesn't match keyword string '$kwstring'";
}
%kwhash = %{ $kwhashes{$kwcat_id} };
if (!(%kwhash))
{
}
else
{
if (!($kwhash{$kwname}))
{
error "'$kwname' not present in $kwcat_id section of gram.y";
}
else
{
delete $kwhashes{$kwcat_id}->{$kwname};
}
}
}
}
close KWLIST;
while (my ($kwcat, $kwcat_id) = each(%keyword_categories))
{
%kwhash = %{ $kwhashes{$kwcat_id} };
for my $kw (keys %kwhash)
{
error "'$kw' found in gram.y $kwcat category, but not in kwlist.h";
}
}
exit $errors;