mirror of
https://github.com/postgres/postgres.git
synced 2025-07-23 03:21:12 +03:00
Run pgindent, pgperltidy, and reformat-dat-files. This set of diffs is a bit larger than typical. We've updated to pg_bsd_indent 2.1.2, which properly indents variable declarations that have multi-line initialization expressions (the continuation lines are now indented one tab stop). We've also updated to perltidy version 20230309 and changed some of its settings, which reduces its desire to add whitespace to lines to make assignments etc. line up. Going forward, that should make for fewer random-seeming changes to existing code. Discussion: https://postgr.es/m/20230428092545.qfb3y5wcu4cm75ur@alvherre.pgsql
91 lines
2.2 KiB
Perl
Executable File
91 lines
2.2 KiB
Perl
Executable File
#! /usr/bin/perl
|
|
|
|
#################################################################
|
|
#
|
|
# check_bison_recursion.pl -- check for right recursion in Bison grammars
|
|
#
|
|
# The standard way to parse list constructs in Bison grammars is via left
|
|
# recursion, wherein a nonterminal symbol has itself as the first symbol
|
|
# in one of its expansion rules. It is also possible to parse a list via
|
|
# right recursion, wherein a nonterminal symbol has itself as the last
|
|
# symbol of an expansion; but that's a bad way to write it because a long
|
|
# enough list will result in parser stack overflow. Since Bison doesn't
|
|
# have any built-in way to warn about use of right recursion, we use this
|
|
# script when we want to check for the problem.
|
|
#
|
|
# To use: run bison with the -v switch, then feed the produced y.output
|
|
# file to this script.
|
|
#
|
|
# Copyright (c) 2011-2023, PostgreSQL Global Development Group
|
|
#
|
|
# src/tools/check_bison_recursion.pl
|
|
#################################################################
|
|
|
|
use strict;
|
|
use warnings;
|
|
|
|
my $debug = 0;
|
|
|
|
# must retain this across input lines
|
|
my $cur_nonterminal;
|
|
|
|
# We parse the input and emit warnings on the fly.
|
|
my $in_grammar = 0;
|
|
|
|
while (<>)
|
|
{
|
|
my $rule_number;
|
|
my $rhs;
|
|
|
|
# We only care about the "Grammar" part of the input.
|
|
if (m/^Grammar$/)
|
|
{
|
|
$in_grammar = 1;
|
|
}
|
|
elsif (m/^Terminal/)
|
|
{
|
|
$in_grammar = 0;
|
|
}
|
|
elsif ($in_grammar)
|
|
{
|
|
if (m/^\s*(\d+)\s+(\S+):\s+(.*)$/)
|
|
{
|
|
|
|
# first rule for nonterminal
|
|
$rule_number = $1;
|
|
$cur_nonterminal = $2;
|
|
$rhs = $3;
|
|
}
|
|
elsif (m/^\s*(\d+)\s+\|\s+(.*)$/)
|
|
{
|
|
|
|
# additional rule for nonterminal
|
|
$rule_number = $1;
|
|
$rhs = $2;
|
|
}
|
|
}
|
|
|
|
# Process rule if we found one
|
|
if (defined $rule_number)
|
|
{
|
|
|
|
# deconstruct the RHS
|
|
$rhs =~ s|^/\* empty \*/$||;
|
|
my @rhs = split '\s', $rhs;
|
|
print "Rule $rule_number: $cur_nonterminal := @rhs\n" if $debug;
|
|
|
|
# We complain if the nonterminal appears as the last RHS element
|
|
# but not elsewhere, since "expr := expr + expr" is reasonable
|
|
my $lastrhs = pop @rhs;
|
|
if ( defined $lastrhs
|
|
&& $cur_nonterminal eq $lastrhs
|
|
&& !grep { $cur_nonterminal eq $_ } @rhs)
|
|
{
|
|
print
|
|
"Right recursion in rule $rule_number: $cur_nonterminal := $rhs\n";
|
|
}
|
|
}
|
|
}
|
|
|
|
exit 0;
|