1#!/usr/bin/perl 2# Copyright 2008 The Go Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style 4# license that can be found in the LICENSE file. 5 6# Modified version of RE2's make_perl_groups.pl. 7 8# Generate table entries giving character ranges 9# for POSIX/Perl character classes. Rather than 10# figure out what the definition is, it is easier to ask 11# Perl about each letter from 0-128 and write down 12# its answer. 13 14use strict; 15use warnings; 16 17my @posixclasses = ( 18 "[:alnum:]", 19 "[:alpha:]", 20 "[:ascii:]", 21 "[:blank:]", 22 "[:cntrl:]", 23 "[:digit:]", 24 "[:graph:]", 25 "[:lower:]", 26 "[:print:]", 27 "[:punct:]", 28 "[:space:]", 29 "[:upper:]", 30 "[:word:]", 31 "[:xdigit:]", 32); 33 34my @perlclasses = ( 35 "\\d", 36 "\\s", 37 "\\w", 38); 39 40my %overrides = ( 41 # Prior to Perl 5.18, \s did not match vertical tab. 42 # RE2 preserves that original behaviour. 43 "\\s:11" => 0, 44); 45 46sub ComputeClass($) { 47 my @ranges; 48 my ($class) = @_; 49 my $regexp = "[$class]"; 50 my $start = -1; 51 for (my $i=0; $i<=129; $i++) { 52 if ($i == 129) { $i = 256; } 53 if ($i <= 128 && ($overrides{"$class:$i"} // chr($i) =~ $regexp)) { 54 if ($start < 0) { 55 $start = $i; 56 } 57 } else { 58 if ($start >= 0) { 59 push @ranges, [$start, $i-1]; 60 } 61 $start = -1; 62 } 63 } 64 return @ranges; 65} 66 67sub PrintClass($$@) { 68 my ($cname, $name, @ranges) = @_; 69 print "var code$cname = []rune{ /* $name */\n"; 70 for (my $i=0; $i<@ranges; $i++) { 71 my @a = @{$ranges[$i]}; 72 printf "\t0x%x, 0x%x,\n", $a[0], $a[1]; 73 } 74 print "}\n\n"; 75 my $n = @ranges; 76 my $negname = $name; 77 if ($negname =~ /:/) { 78 $negname =~ s/:/:^/; 79 } else { 80 $negname =~ y/a-z/A-Z/; 81 } 82 return "\t`$name`: {+1, code$cname},\n" . 83 "\t`$negname`: {-1, code$cname},\n"; 84} 85 86my $gen = 0; 87 88sub PrintClasses($@) { 89 my ($cname, @classes) = @_; 90 my @entries; 91 foreach my $cl (@classes) { 92 my @ranges = ComputeClass($cl); 93 push @entries, PrintClass(++$gen, $cl, @ranges); 94 } 95 print "var ${cname}Group = map[string]charGroup{\n"; 96 foreach my $e (@entries) { 97 print $e; 98 } 99 print "}\n"; 100 my $count = @entries; 101} 102 103# Prepare gofmt command 104my $gofmt; 105 106if (@ARGV > 0 && $ARGV[0] =~ /\.go$/) { 107 # Send the output of gofmt to the given file 108 open($gofmt, '|-', 'gofmt >'.$ARGV[0]) or die; 109} else { 110 open($gofmt, '|-', 'gofmt') or die; 111} 112 113# Redirect STDOUT to gofmt input 114select $gofmt; 115 116print <<EOF; 117// Copyright 2013 The Go Authors. All rights reserved. 118// Use of this source code is governed by a BSD-style 119// license that can be found in the LICENSE file. 120 121// Code generated by make_perl_groups.pl; DO NOT EDIT. 122 123package syntax 124 125EOF 126 127PrintClasses("perl", @perlclasses); 128PrintClasses("posix", @posixclasses); 129