On 3/3/2011 6:49 AM, Michael Meskes wrote:
On Wed, Mar 02, 2011 at 01:33:35PM -0600, Andy Colson wrote:
I thought Kris was going to work on this, but saw no progress, and I
was bored the other day, so I started working on it.

Here is a parse.pl, with some major refactoring.

I named it with a 2 so I could run it beside the original and diff em:

Thanks for all the work.

I am sure there are new bugs.  I have not run it on anything but
9.0.1.  Are there other .y files you might feed it? (something other
than backend/parser/gram.y?)

I ran it against several versions and it always gave the right output. So i
decided to just commit it to the archive so we can see if it breaks anything.
The old script is still in there so in case of a major problem that I cannot
foresee we can simply change the Makefile back to using parse.pl.

Michael


And here is check_rules. Much less change, but I did run it through perl tidy, so I'll bet most of the lines changed.

-Andy
#!/usr/bin/perl
# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/check_rules.pl,v 1.2 
2010/01/02 16:58:11 momjian Exp $
# test parser generater for ecpg
# call with backend parser as stdin
#
# Copyright (c) 2009-2010, PostgreSQL Global Development Group
#
# Written by Michael Meskes <mes...@postgresql.org>
#
# 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

use strict;
use warnings;
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";
}

my %replace_line = (
        'ExecuteStmtEXECUTEnameexecute_param_clause' =>
                'EXECUTE prepared_name execute_param_clause execute_rest',

        
'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause'
 =>
                'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name 
execute_param_clause',

        'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt' =>
                'PREPARE prepared_name prep_type_clause AS PreparableStmt'
);

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>) 
{
        if (/^%%/) 
        {
                $yaccmode++;
        }

        if ( $yaccmode != 1 ) 
        {
                next;
        }

        chomp;    # strip record separator

        next if ($_ eq '');

        # Make sure any braces are split
        s/{/ { /g;
        s/}/ } /g;

        # Any comments are split
        s|\/\*| /* |g;
        s|\*\/| */ |g;

        # Now split the line into individual fields
        my $n = ( @arr = split( ' ' ) );

        # Go through each field in turn
        for ( my $fieldIndexer = 0 ; $fieldIndexer < $n ; $fieldIndexer++ ) 
        {
                if ( $arr[$fieldIndexer] eq '*/' && $comment ) 
                {
                        $comment = 0;
                        next;
                }
                elsif ($comment) 
                {
                        next;
                }
                elsif ( $arr[$fieldIndexer] eq '/*' ) 
                {
                        # start of a multiline comment
                        $comment = 1;
                        next;
                }
                elsif ( $arr[$fieldIndexer] eq '//' ) 
                {
                        next;
                }
                elsif ( $arr[$fieldIndexer] eq '}' ) 
                {
                        $brace_indent--;
                        next;
                }
                elsif ( $arr[$fieldIndexer] eq '{' ) 
                {
                        $brace_indent++;
                        next;
                }

                if ( $brace_indent > 0 ) 
                {
                        next;
                }

                if ( $arr[$fieldIndexer] eq ';' || $arr[$fieldIndexer] eq '|' ) 
                {
                        $block = $non_term_id . $block;
                        if ( $replace_line{$block} ) 
                        {
                                $block = $non_term_id . $replace_line{$block};
                                $block =~ tr/ |//d;
                        }
                        $found{$block} = 1;
                        $cc++;
                        $block = '';
                }
                elsif ( ( $arr[$fieldIndexer] =~ '[A-Za-z0-9]+:' )
                        || $arr[ $fieldIndexer + 1 ] eq ':' )
                {
                        $non_term_id = $arr[$fieldIndexer];
                        $non_term_id =~ tr/://d;
                }
                else 
                {
                        $block = $block . $arr[$fieldIndexer];
                }
        }
}

close GRAM;
if ($verbose)
{
        print "$cc rules loaded\n";
}

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;

if ($verbose)
{
        print "$cc rules checked\n";
}

exit $ret;

-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to