1
0
mirror of https://github.com/postgres/postgres.git synced 2025-05-21 15:54:08 +03:00

Added new version of ecpg's parser test script which was written by Andy Colson <andy@squeakycode.net>.

This commit is contained in:
Michael Meskes 2011-03-08 11:27:32 +01:00
parent 4cd3fb6e12
commit 4ff90d9945

204
src/interfaces/ecpg/preproc/check_rules.pl Executable file → Normal file
View File

@ -6,130 +6,176 @@
# Copyright (c) 2009-2011, PostgreSQL Global Development Group # Copyright (c) 2009-2011, PostgreSQL Global Development Group
# #
# Written by Michael Meskes <meskes@postgresql.org> # Written by Michael Meskes <meskes@postgresql.org>
# Andy Colson <andy@squeakycode.net>
# #
# Placed under the same license as PostgreSQL. # Placed under the same license as PostgreSQL.
# #
# Command line: [-v] [path only to ecpg.addons] [full filename of gram.y]
# -v enables verbose mode... show's some stats... thought it might be interesting
#
# This script loads rule names from gram.y and sets $found{rule} = 1 for each.
# Then it checks to make sure each rule in ecpg.addons was found in gram.y
if (@ARGV) { use strict;
$path = $ARGV[0]; use warnings;
$parser = $ARGV[1]; no warnings 'uninitialized';
my $verbose = 0;
if ($ARGV[0] eq '-v')
{
$verbose = shift;
}
my $path = shift || '.';
my $parser = shift || '../../../backend/parser/gram.y';
my $filename = $path . "/ecpg.addons";
if ($verbose)
{
print "parser: $parser\n";
print "addons: $filename\n";
} }
$[ = 1; # set array base to 1 my %replace_line = (
'ExecuteStmtEXECUTEnameexecute_param_clause' =>
'EXECUTE prepared_name execute_param_clause execute_rest',
if ($path eq '') { $path = "."; } 'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause' =>
$filename = $path . "/ecpg.addons"; 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause',
if ($parser eq '') { $parser = "../../../backend/parser/gram.y"; } 'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' =>
'PREPARE prepared_name prep_type_clause AS PreparableStmt'
);
$replace_line{'ExecuteStmtEXECUTEnameexecute_param_clause'} = 'EXECUTE prepared_name execute_param_clause execute_rest'; my $block = '';
$replace_line{'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause'} = 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause'; my $yaccmode = 0;
$replace_line{'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt'} = 'PREPARE prepared_name prep_type_clause AS PreparableStmt'; my $brace_indent = 0;
my (@arr, %found);
$block = ''; my $comment = 0;
$ret = 0; my $non_term_id = '';
$yaccmod = 0; my $cc = 0;
$brace_indent = 0;
open GRAM, $parser or die $!; open GRAM, $parser or die $!;
while (<GRAM>) { while (<GRAM>)
chomp; # strip record separator {
if (/^%%/)
if (/^%%/) { {
$yaccmode++; $yaccmode++;
} }
if ($yaccmode != 1) { if ( $yaccmode != 1 )
next; {
} next;
}
$S = $_; chomp; # strip record separator
$prec = 0;
next if ($_ eq '');
# Make sure any braces are split # Make sure any braces are split
$S =~ s/{/ { /g; s/{/ { /g;
$S =~ s/}/ } /g; s/}/ } /g;
# Any comments are split # Any comments are split
$S =~ s#[/][*]# /* #g; s|\/\*| /* |g;
$S =~ s#[*][/]# */ #g; s|\*\/| */ |g;
# Now split the line into individual fields # Now split the line into individual fields
$n = (@arr = split(' ', $S)); my $n = ( @arr = split( ' ' ) );
# Go through each field in turn # Go through each field in turn
for ($fieldIndexer = 1; $fieldIndexer <= $n; $fieldIndexer++) { for ( my $fieldIndexer = 0 ; $fieldIndexer < $n ; $fieldIndexer++ )
if ($arr[$fieldIndexer] eq '*/' && $comment) { {
$comment = 0; if ( $arr[$fieldIndexer] eq '*/' && $comment )
next; {
$comment = 0;
next;
} }
elsif ($comment) { elsif ($comment)
next; {
next;
} }
elsif ($arr[$fieldIndexer] eq '/*') { elsif ( $arr[$fieldIndexer] eq '/*' )
# start of a multiline comment {
$comment = 1; # start of a multiline comment
next; $comment = 1;
next;
} }
elsif ($arr[$fieldIndexer] eq '//') { elsif ( $arr[$fieldIndexer] eq '//' )
next; {
next;
} }
elsif ($arr[$fieldIndexer] eq '}') { elsif ( $arr[$fieldIndexer] eq '}' )
$brace_indent--; {
next; $brace_indent--;
next;
} }
elsif ($arr[$fieldIndexer] eq '{') { elsif ( $arr[$fieldIndexer] eq '{' )
$brace_indent++; {
next; $brace_indent++;
next;
} }
if ($brace_indent > 0) { if ( $brace_indent > 0 )
next; {
next;
} }
if ($arr[$fieldIndexer] eq ';' || $arr[$fieldIndexer] eq '|') { if ( $arr[$fieldIndexer] eq ';' || $arr[$fieldIndexer] eq '|' )
{
$block = $non_term_id . $block; $block = $non_term_id . $block;
if ($replace_line{$block}) { if ( $replace_line{$block} )
$block = &generate_block($replace_line{$block}); {
$block = $non_term_id . $replace_line{$block};
$block =~ tr/ |//d;
} }
$found{$block} = 'found'; $found{$block} = 1;
$cc++;
$block = ''; $block = '';
} }
elsif (($arr[$fieldIndexer] =~ '[A-Za-z0-9]+:') || $arr[$fieldIndexer + 1] eq ':') { elsif ( ( $arr[$fieldIndexer] =~ '[A-Za-z0-9]+:' )
|| $arr[ $fieldIndexer + 1 ] eq ':' )
{
$non_term_id = $arr[$fieldIndexer]; $non_term_id = $arr[$fieldIndexer];
$non_term_id =~ s/://g; $non_term_id =~ tr/://d;
} }
else { else
{
$block = $block . $arr[$fieldIndexer]; $block = $block . $arr[$fieldIndexer];
} }
} }
} }
close GRAM; close GRAM;
if ($verbose)
open ECPG, $filename or die $!; {
print "$cc rules loaded\n";
line: while (<ECPG>) {
chomp; # strip record separator
@Fld = split(' ', $_, -1);
if (!/^ECPG:/) {
next line;
}
if ($found{$Fld[2]} ne 'found') {
printf $Fld[2] . " is not used for building parser!\n";
$ret = 1;
}
} }
my $ret = 0;
$cc = 0;
open ECPG, $filename or die $!;
while (<ECPG>)
{
if ( !/^ECPG:/ )
{
next;
}
my @Fld = split( ' ', $_, 3 );
$cc++;
if ( not exists $found{ $Fld[1] } )
{
print $Fld[1], " is not used for building parser!\n";
$ret = 1;
}
}
close ECPG; close ECPG;
if ($verbose)
{
print "$cc rules checked\n";
}
exit $ret; exit $ret;
sub generate_block {
local($line) = @_;
$block = $non_term_id . $line;
$block =~ s/ //g;
$s = "\\|", $block =~ s/$s//g;
return $block;
}