2009-11-27 11:00:40 +01:00
|
|
|
#!/usr/bin/perl
|
2010-09-20 22:08:53 +02:00
|
|
|
# src/interfaces/ecpg/preproc/check_rules.pl
|
2009-11-27 11:00:40 +01:00
|
|
|
# test parser generater for ecpg
|
|
|
|
# call with backend parser as stdin
|
|
|
|
#
|
2015-01-06 17:43:47 +01:00
|
|
|
# Copyright (c) 2009-2015, PostgreSQL Global Development Group
|
2009-11-27 11:00:40 +01:00
|
|
|
#
|
|
|
|
# Written by Michael Meskes <meskes@postgresql.org>
|
2012-07-05 03:47:49 +02:00
|
|
|
# Andy Colson <andy@squeakycode.net>
|
2009-11-27 11:00:40 +01:00
|
|
|
#
|
|
|
|
# Placed under the same license as PostgreSQL.
|
|
|
|
#
|
2011-03-08 11:27:32 +01:00
|
|
|
# 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
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
use strict;
|
|
|
|
use warnings;
|
|
|
|
no warnings 'uninitialized';
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
my $verbose = 0;
|
|
|
|
if ($ARGV[0] eq '-v')
|
|
|
|
{
|
|
|
|
$verbose = shift;
|
|
|
|
}
|
2012-07-05 03:47:49 +02:00
|
|
|
my $path = shift || '.';
|
2011-03-08 11:27:32 +01:00
|
|
|
my $parser = shift || '../../../backend/parser/gram.y';
|
|
|
|
|
|
|
|
my $filename = $path . "/ecpg.addons";
|
|
|
|
if ($verbose)
|
|
|
|
{
|
|
|
|
print "parser: $parser\n";
|
|
|
|
print "addons: $filename\n";
|
|
|
|
}
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
my %replace_line = (
|
|
|
|
'ExecuteStmtEXECUTEnameexecute_param_clause' =>
|
2012-07-05 03:47:49 +02:00
|
|
|
'EXECUTE prepared_name execute_param_clause execute_rest',
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2012-07-05 03:47:49 +02:00
|
|
|
'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause'
|
|
|
|
=> 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause',
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' =>
|
2012-07-05 03:47:49 +02:00
|
|
|
'PREPARE prepared_name prep_type_clause AS PreparableStmt');
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
my $block = '';
|
|
|
|
my $yaccmode = 0;
|
|
|
|
my $brace_indent = 0;
|
|
|
|
my (@arr, %found);
|
2012-07-05 03:47:49 +02:00
|
|
|
my $comment = 0;
|
2011-03-08 11:27:32 +01:00
|
|
|
my $non_term_id = '';
|
2012-07-05 03:47:49 +02:00
|
|
|
my $cc = 0;
|
2009-11-27 11:00:40 +01:00
|
|
|
|
|
|
|
open GRAM, $parser or die $!;
|
2012-07-05 03:47:49 +02:00
|
|
|
while (<GRAM>)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
if (/^%%/)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
$yaccmode++;
|
|
|
|
}
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2012-07-05 03:47:49 +02:00
|
|
|
if ($yaccmode != 1)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
next;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
chomp; # strip record separator
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
next if ($_ eq '');
|
2009-11-27 11:00:40 +01:00
|
|
|
|
|
|
|
# Make sure any braces are split
|
2011-03-08 11:27:32 +01:00
|
|
|
s/{/ { /g;
|
|
|
|
s/}/ } /g;
|
|
|
|
|
2009-11-27 11:00:40 +01:00
|
|
|
# Any comments are split
|
2011-03-08 11:27:32 +01:00
|
|
|
s|\/\*| /* |g;
|
|
|
|
s|\*\/| */ |g;
|
2009-11-27 11:00:40 +01:00
|
|
|
|
|
|
|
# Now split the line into individual fields
|
2012-07-05 03:47:49 +02:00
|
|
|
my $n = (@arr = split(' '));
|
2009-11-27 11:00:40 +01:00
|
|
|
|
|
|
|
# Go through each field in turn
|
2012-07-05 03:47:49 +02:00
|
|
|
for (my $fieldIndexer = 0; $fieldIndexer < $n; $fieldIndexer++)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
if ($arr[$fieldIndexer] eq '*/' && $comment)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
$comment = 0;
|
|
|
|
next;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
2012-07-05 03:47:49 +02:00
|
|
|
elsif ($comment)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
next;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
2012-07-05 03:47:49 +02:00
|
|
|
elsif ($arr[$fieldIndexer] eq '/*')
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
# start of a multiline comment
|
|
|
|
$comment = 1;
|
|
|
|
next;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
2012-07-05 03:47:49 +02:00
|
|
|
elsif ($arr[$fieldIndexer] eq '//')
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
next;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
2012-07-05 03:47:49 +02:00
|
|
|
elsif ($arr[$fieldIndexer] eq '}')
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
$brace_indent--;
|
|
|
|
next;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
2012-07-05 03:47:49 +02:00
|
|
|
elsif ($arr[$fieldIndexer] eq '{')
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
$brace_indent++;
|
|
|
|
next;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
|
|
|
|
2012-07-05 03:47:49 +02:00
|
|
|
if ($brace_indent > 0)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
next;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
|
|
|
|
2012-07-05 03:47:49 +02:00
|
|
|
if ($arr[$fieldIndexer] eq ';' || $arr[$fieldIndexer] eq '|')
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
2009-11-27 11:00:40 +01:00
|
|
|
$block = $non_term_id . $block;
|
2012-07-05 03:47:49 +02:00
|
|
|
if ($replace_line{$block})
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
$block = $non_term_id . $replace_line{$block};
|
|
|
|
$block =~ tr/ |//d;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
2011-03-08 11:27:32 +01:00
|
|
|
$found{$block} = 1;
|
|
|
|
$cc++;
|
2009-11-27 11:00:40 +01:00
|
|
|
$block = '';
|
|
|
|
}
|
2012-07-05 03:47:49 +02:00
|
|
|
elsif (($arr[$fieldIndexer] =~ '[A-Za-z0-9]+:')
|
|
|
|
|| $arr[ $fieldIndexer + 1 ] eq ':')
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
2009-11-27 11:00:40 +01:00
|
|
|
$non_term_id = $arr[$fieldIndexer];
|
2011-03-08 11:27:32 +01:00
|
|
|
$non_term_id =~ tr/://d;
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
2012-07-05 03:47:49 +02:00
|
|
|
else
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
2009-11-27 11:00:40 +01:00
|
|
|
$block = $block . $arr[$fieldIndexer];
|
|
|
|
}
|
|
|
|
}
|
2010-11-23 21:27:50 +01:00
|
|
|
}
|
2009-11-27 11:00:40 +01:00
|
|
|
|
|
|
|
close GRAM;
|
2011-03-08 11:27:32 +01:00
|
|
|
if ($verbose)
|
|
|
|
{
|
|
|
|
print "$cc rules loaded\n";
|
|
|
|
}
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
my $ret = 0;
|
|
|
|
$cc = 0;
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
open ECPG, $filename or die $!;
|
2012-07-05 03:47:49 +02:00
|
|
|
while (<ECPG>)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
2012-07-05 03:47:49 +02:00
|
|
|
if (!/^ECPG:/)
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
next;
|
|
|
|
}
|
2009-11-27 11:00:40 +01:00
|
|
|
|
2012-07-05 03:47:49 +02:00
|
|
|
my @Fld = split(' ', $_, 3);
|
2011-03-08 11:27:32 +01:00
|
|
|
$cc++;
|
2012-07-05 03:47:49 +02:00
|
|
|
if (not exists $found{ $Fld[1] })
|
2011-03-08 11:27:32 +01:00
|
|
|
{
|
|
|
|
print $Fld[1], " is not used for building parser!\n";
|
|
|
|
$ret = 1;
|
|
|
|
}
|
2009-11-27 11:00:40 +01:00
|
|
|
}
|
|
|
|
close ECPG;
|
|
|
|
|
2011-03-08 11:27:32 +01:00
|
|
|
if ($verbose)
|
|
|
|
{
|
|
|
|
print "$cc rules checked\n";
|
|
|
|
}
|
|
|
|
|
2009-11-27 11:00:40 +01:00
|
|
|
exit $ret;
|