|  | #!/usr/bin/perl | 
|  | # Copyright 2008 The Go Authors. All rights reserved. | 
|  | # Use of this source code is governed by a BSD-style | 
|  | # license that can be found in the LICENSE file. | 
|  |  | 
|  | # Modified version of RE2's make_perl_groups.pl. | 
|  |  | 
|  | # Generate table entries giving character ranges | 
|  | # for POSIX/Perl character classes.  Rather than | 
|  | # figure out what the definition is, it is easier to ask | 
|  | # Perl about each letter from 0-128 and write down | 
|  | # its answer. | 
|  |  | 
|  | @posixclasses = ( | 
|  | "[:alnum:]", | 
|  | "[:alpha:]", | 
|  | "[:ascii:]", | 
|  | "[:blank:]", | 
|  | "[:cntrl:]", | 
|  | "[:digit:]", | 
|  | "[:graph:]", | 
|  | "[:lower:]", | 
|  | "[:print:]", | 
|  | "[:punct:]", | 
|  | "[:space:]", | 
|  | "[:upper:]", | 
|  | "[:word:]", | 
|  | "[:xdigit:]", | 
|  | ); | 
|  |  | 
|  | @perlclasses = ( | 
|  | "\\d", | 
|  | "\\s", | 
|  | "\\w", | 
|  | ); | 
|  |  | 
|  | %overrides = ( | 
|  | # Prior to Perl 5.18, \s did not match vertical tab. | 
|  | # RE2 preserves that original behaviour. | 
|  | "\\s:11" => 0, | 
|  | ); | 
|  |  | 
|  | sub ComputeClass($) { | 
|  | my @ranges; | 
|  | my ($class) = @_; | 
|  | my $regexp = "[$class]"; | 
|  | my $start = -1; | 
|  | for (my $i=0; $i<=129; $i++) { | 
|  | if ($i == 129) { $i = 256; } | 
|  | if ($i <= 128 && ($overrides{"$class:$i"} // chr($i) =~ $regexp)) { | 
|  | if ($start < 0) { | 
|  | $start = $i; | 
|  | } | 
|  | } else { | 
|  | if ($start >= 0) { | 
|  | push @ranges, [$start, $i-1]; | 
|  | } | 
|  | $start = -1; | 
|  | } | 
|  | } | 
|  | return @ranges; | 
|  | } | 
|  |  | 
|  | sub PrintClass($$@) { | 
|  | my ($cname, $name, @ranges) = @_; | 
|  | print "var code$cname = []rune{  /* $name */\n"; | 
|  | for (my $i=0; $i<@ranges; $i++) { | 
|  | my @a = @{$ranges[$i]}; | 
|  | printf "\t0x%x, 0x%x,\n", $a[0], $a[1]; | 
|  | } | 
|  | print "}\n\n"; | 
|  | my $n = @ranges; | 
|  | $negname = $name; | 
|  | if ($negname =~ /:/) { | 
|  | $negname =~ s/:/:^/; | 
|  | } else { | 
|  | $negname =~ y/a-z/A-Z/; | 
|  | } | 
|  | return "\t`$name`: {+1, code$cname},\n" . | 
|  | "\t`$negname`: {-1, code$cname},\n"; | 
|  | } | 
|  |  | 
|  | my $gen = 0; | 
|  |  | 
|  | sub PrintClasses($@) { | 
|  | my ($cname, @classes) = @_; | 
|  | my @entries; | 
|  | foreach my $cl (@classes) { | 
|  | my @ranges = ComputeClass($cl); | 
|  | push @entries, PrintClass(++$gen, $cl, @ranges); | 
|  | } | 
|  | print "var ${cname}Group = map[string]charGroup{\n"; | 
|  | foreach my $e (@entries) { | 
|  | print $e; | 
|  | } | 
|  | print "}\n"; | 
|  | my $count = @entries; | 
|  | } | 
|  |  | 
|  | print <<EOF; | 
|  | // Copyright 2013 The Go Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style | 
|  | // license that can be found in the LICENSE file. | 
|  |  | 
|  | // GENERATED BY make_perl_groups.pl; DO NOT EDIT. | 
|  | // make_perl_groups.pl >perl_groups.go | 
|  |  | 
|  | package syntax | 
|  |  | 
|  | EOF | 
|  |  | 
|  | PrintClasses("perl", @perlclasses); | 
|  | PrintClasses("posix", @posixclasses); |