File: make_blockmatch.pl

package info (click to toggle)
ftnchek 3.3.1-5
  • links: PTS
  • area: main
  • in suites: bullseye, buster, jessie, jessie-kfreebsd, stretch
  • size: 8,484 kB
  • ctags: 5,960
  • sloc: ansic: 21,908; fortran: 5,748; yacc: 4,071; sh: 3,035; makefile: 896; lisp: 322; f90: 118; perl: 76
file content (127 lines) | stat: -rwxr-xr-x 3,750 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#!/usr/bin/perl

# $Id: make_blockmatch.pl.in,v 1.3 2001/05/27 14:28:48 moniot Rel $

#  Script to generate block_match.h file from tokdefs.h.  The result is
#  the contents of an array to map from block-closing tokens to the
#  required block-opening tokens.  It is used by fortran.y in pop_block
#  routine to check proper balancing of structured control forms.

%block_opener = (
      'ELSE' => 'IF',
      'ENDIF' => 'IF',
      'ENDDO' => 'DO',
      'CASE' => 'SELECTCASE',
      'ENDSELECT' => 'SELECTCASE',
      'ENDSUBROUTINE' => 'SUBROUTINE',
      'ENDFUNCTION' => 'FUNCTION',
      'ENDPROGRAM' => 'PROGRAM',
      'ENDBLOCKDATA' => 'BLOCKDATA'
);


		# Read the token definitions.  Find the defs corresponding
		# to block oeners and closers, and save them in hashes.

open(TOKDEFS,"tokdefs.h") || die "Can't open tokdefs.h: $!";

$min_block_token = -1;
$max_block_token = -1;
foreach (<TOKDEFS>) {
    if( /^\#\s*define\s+tok_(\S*)\s*(\d+)/ ) {
	$name = $1;
	$number = $2;

	if( grep(/^$name$/,values(%block_opener) ) ) {
	    $opener_number{$name} = $number;
	}
	if( grep(/^$name$/,keys(%block_opener) ) ) {
	    $closer_name{$number} = $name;
	}
				# keep track of min and max block tokens
	if( $opener_number{$name} || $closer_name{$number} ) {
	    if( $min_block_token == -1 ) { $min_block_token = $number; }
	    if( $max_block_token == -1 ) { $max_block_token = $number; }
	    if( $number < $min_block_token ) { $min_block_token = $number; }
	    if( $number > $max_block_token ) { $max_block_token = $number; }
	}
    }
}

close(TOKDEFS);

		# Make sure tokdefs.h was parsed OK.  All the token names
		# in the %block_opener table above must be defined.

foreach ( (keys %block_opener) ) {
    $key = $_;
    if( ! grep(/^$key$/, values(%closer_name) ) ) {
	not_found($key);
    }
}

foreach ( (values %block_opener) ) {
    $val = $_;
    if( ! defined($opener_number{$val}) )  {
	not_found($val);
    }
}

		# Find range of token values used to index array

$min_closer = (sort keys %closer_name)[0];
$max_closer = (reverse sort keys %closer_name)[0];

		# Print initializer for the C lookup table that gives
		# matching opener for any closer.  This initializer is
		# to be included like so:
		#   int block_opener[] = {
		#   #include "blockmatch.h"
		#   };
		# It also defines range and offset of index values.
		# Look up a value as
		#   matching_token = block_opener[closer_token-MIN_CLOSER]

print <<END_OF_TEXT;
/* DO NOT EDIT
     File automatically generated by make_blockmatch.pl from tokdefs.h
*/
#define MIN_CLOSER $min_closer
#define MAX_CLOSER $max_closer
#define MIN_BLOCK_TOKEN $min_block_token
#define MAX_BLOCK_TOKEN $max_block_token
END_OF_TEXT

for($i=$min_closer; $i <= $max_closer; $i++) {
    if( ($i-$min_closer) % 10 == 0) {
	print "\n";		# newline every 10 values
    }
		# Put matching token number in the array at each closing
		# token.  If array position is not for a closer, put a zero.
    if( defined($closer_name{$i}) ) {
	print "$opener_number{$block_opener{$closer_name{$i}}},";
    }
    else {
	print "0,";
    }
}
print "\n";

		# This error should not occur unless the user has touched
		# fortran.y and re-made fortran.h and tokdefs.h with a
		# different parser generator
sub not_found {
print STDERR <<END_ERROR_MESSAGE;

  ===> ERROR: tok_$_[0] not found in tokdefs.h <===

This probably means that the regular expression in the first foreach
of $0 is not correct for the tokdefs.h file produced
using the local parser generator.  Please send a copy of the tokdefs.h
file, along with information identifying the operating system and the
name and version number of the parser generator (probably yacc) to
the ftnchek maintainer listed in README.
END_ERROR_MESSAGE

exit(1);
}