Commit 4ff90d99 authored by Michael Meskes's avatar Michael Meskes

Added new version of ecpg's parser test script which was written by Andy...

Added new version of ecpg's parser test script which was written by Andy Colson <andy@squeakycode.net>.
parent 4cd3fb6e
......@@ -6,130 +6,176 @@
# Copyright (c) 2009-2011, PostgreSQL Global Development Group
#
# Written by Michael Meskes <meskes@postgresql.org>
# Andy Colson <andy@squeakycode.net>
#
# 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) {
$path = $ARGV[0];
$parser = $ARGV[1];
}
use strict;
use warnings;
no warnings 'uninitialized';
$[ = 1; # set array base to 1
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";
}
if ($path eq '') { $path = "."; }
$filename = $path . "/ecpg.addons";
my %replace_line = (
'ExecuteStmtEXECUTEnameexecute_param_clause' =>
'EXECUTE prepared_name execute_param_clause execute_rest',
if ($parser eq '') { $parser = "../../../backend/parser/gram.y"; }
'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause' =>
'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause',
$replace_line{'ExecuteStmtEXECUTEnameexecute_param_clause'} = 'EXECUTE prepared_name execute_param_clause execute_rest';
$replace_line{'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause'} = 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause';
$replace_line{'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt'} = 'PREPARE prepared_name prep_type_clause AS PreparableStmt';
'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' =>
'PREPARE prepared_name prep_type_clause AS PreparableStmt'
);
$block = '';
$ret = 0;
$yaccmod = 0;
$brace_indent = 0;
my $block = '';
my $yaccmode = 0;
my $brace_indent = 0;
my (@arr, %found);
my $comment = 0;
my $non_term_id = '';
my $cc = 0;
open GRAM, $parser or die $!;
while (<GRAM>) {
chomp; # strip record separator
while (<GRAM>)
{
if (/^%%/)
{
$yaccmode++;
}
if (/^%%/) {
$yaccmode++;
if ( $yaccmode != 1 )
{
next;
}
if ($yaccmode != 1) {
next;
}
chomp; # strip record separator
$S = $_;
$prec = 0;
next if ($_ eq '');
# Make sure any braces are split
$S =~ s/{/ { /g;
$S =~ s/}/ } /g;
s/{/ { /g;
s/}/ } /g;
# Any comments are split
$S =~ s#[/][*]# /* #g;
$S =~ s#[*][/]# */ #g;
s|\/\*| /* |g;
s|\*\/| */ |g;
# Now split the line into individual fields
$n = (@arr = split(' ', $S));
my $n = ( @arr = split( ' ' ) );
# Go through each field in turn
for ($fieldIndexer = 1; $fieldIndexer <= $n; $fieldIndexer++) {
if ($arr[$fieldIndexer] eq '*/' && $comment) {
$comment = 0;
next;
for ( my $fieldIndexer = 0 ; $fieldIndexer < $n ; $fieldIndexer++ )
{
if ( $arr[$fieldIndexer] eq '*/' && $comment )
{
$comment = 0;
next;
}
elsif ($comment) {
next;
elsif ($comment)
{
next;
}
elsif ($arr[$fieldIndexer] eq '/*') {
# start of a multiline comment
$comment = 1;
next;
elsif ( $arr[$fieldIndexer] eq '/*' )
{
# start of a multiline comment
$comment = 1;
next;
}
elsif ($arr[$fieldIndexer] eq '//') {
next;
elsif ( $arr[$fieldIndexer] eq '//' )
{
next;
}
elsif ($arr[$fieldIndexer] eq '}') {
$brace_indent--;
next;
elsif ( $arr[$fieldIndexer] eq '}' )
{
$brace_indent--;
next;
}
elsif ($arr[$fieldIndexer] eq '{') {
$brace_indent++;
next;
elsif ( $arr[$fieldIndexer] eq '{' )
{
$brace_indent++;
next;
}
if ($brace_indent > 0) {
next;
if ( $brace_indent > 0 )
{
next;
}
if ($arr[$fieldIndexer] eq ';' || $arr[$fieldIndexer] eq '|') {
if ( $arr[$fieldIndexer] eq ';' || $arr[$fieldIndexer] eq '|' )
{
$block = $non_term_id . $block;
if ($replace_line{$block}) {
$block = &generate_block($replace_line{$block});
if ( $replace_line{$block} )
{
$block = $non_term_id . $replace_line{$block};
$block =~ tr/ |//d;
}
$found{$block} = 'found';
$found{$block} = 1;
$cc++;
$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 =~ s/://g;
$non_term_id =~ tr/://d;
}
else {
else
{
$block = $block . $arr[$fieldIndexer];
}
}
}
close GRAM;
if ($verbose)
{
print "$cc rules loaded\n";
}
open ECPG, $filename or die $!;
line: while (<ECPG>) {
chomp; # strip record separator
@Fld = split(' ', $_, -1);
my $ret = 0;
$cc = 0;
if (!/^ECPG:/) {
next line;
}
open ECPG, $filename or die $!;
while (<ECPG>)
{
if ( !/^ECPG:/ )
{
next;
}
if ($found{$Fld[2]} ne 'found') {
printf $Fld[2] . " is not used for building parser!\n";
$ret = 1;
}
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;
if ($verbose)
{
print "$cc rules checked\n";
}
exit $ret;
sub generate_block {
local($line) = @_;
$block = $non_term_id . $line;
$block =~ s/ //g;
$s = "\\|", $block =~ s/$s//g;
return $block;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment