rubylexer 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +510 -0
- data/README +134 -0
- data/Rantfile +37 -0
- data/assert.rb +31 -0
- data/charhandler.rb +84 -0
- data/charset.rb +76 -0
- data/context.rb +174 -0
- data/howtouse.txt +136 -0
- data/io.each_til_charset.rb +247 -0
- data/require.rb +103 -0
- data/rlold.rb +12 -0
- data/rubycode.rb +44 -0
- data/rubylexer.rb +1589 -0
- data/rulexer.rb +532 -0
- data/symboltable.rb +65 -0
- data/testcode/deletewarns.rb +39 -0
- data/testcode/dumptokens.rb +38 -0
- data/testcode/locatetest +12 -0
- data/testcode/rubylexervsruby.rb +104 -0
- data/testcode/rubylexervsruby.sh +51 -0
- data/testcode/tokentest.rb +237 -0
- data/testcode/torment +51 -0
- data/testdata/1.rb.broken +729 -0
- data/testdata/23.rb +24 -0
- data/testdata/g.rb +15 -0
- data/testdata/newsyntax.rb +18 -0
- data/testdata/noeolatend.rb +1 -0
- data/testdata/p.rb +1227 -0
- data/testdata/pleac.rb.broken +6282 -0
- data/testdata/pre.rb +33 -0
- data/testdata/pre.unix.rb +33 -0
- data/testdata/regtest.rb +621 -0
- data/testdata/tokentest.assert.rb.can +7 -0
- data/testdata/untitled1.rb +1 -0
- data/testdata/w.rb +22 -0
- data/testdata/wsdlDriver.rb +499 -0
- data/testing.txt +130 -0
- data/testresults/placeholder +0 -0
- data/token.rb +486 -0
- data/tokenprinter.rb +152 -0
- metadata +76 -0
    
        data/testcode/torment
    ADDED
    
    | @@ -0,0 +1,51 @@ | |
| 1 | 
            +
            #!/bin/sh
         | 
| 2 | 
            +
            #export DEBUG=-rdebug
         | 
| 3 | 
            +
             | 
| 4 | 
            +
             | 
| 5 | 
            +
            #export RUBYLEXERVSRUBY=testcode/rubylexervsruby.sh
         | 
| 6 | 
            +
            export RUBYLEXERVSRUBY=testcode/rubylexervsruby.rb
         | 
| 7 | 
            +
            export ARGS=$*
         | 
| 8 | 
            +
              #something broken here
         | 
| 9 | 
            +
               #test -n "$ARGS" && (
         | 
| 10 | 
            +
             | 
| 11 | 
            +
             | 
| 12 | 
            +
               echo 'looking for ruby files in debian packages...'
         | 
| 13 | 
            +
               find testdata/ -name '_*' -print|xargs -l200 rm
         | 
| 14 | 
            +
               for i in `feta find '\.rb'|cut -d: -f2-99`; do
         | 
| 15 | 
            +
                  ln -s "$i" testdata/`echo $i|tr '/ ' '_'` 2>&1 |grep -v ': File exists$';
         | 
| 16 | 
            +
               done
         | 
| 17 | 
            +
               #)
         | 
| 18 | 
            +
             | 
| 19 | 
            +
               for i in testdata/*.rb; do
         | 
| 20 | 
            +
                  $RUBYLEXERVSRUBY $i;
         | 
| 21 | 
            +
               done
         | 
| 22 | 
            +
             | 
| 23 | 
            +
             | 
| 24 | 
            +
               for i in *.rb; do
         | 
| 25 | 
            +
                  $RUBYLEXERVSRUBY $i;
         | 
| 26 | 
            +
               done
         | 
| 27 | 
            +
             | 
| 28 | 
            +
             | 
| 29 | 
            +
             | 
| 30 | 
            +
            #$RUBYLEXERVSRUBY assert.rb
         | 
| 31 | 
            +
            #$RUBYLEXERVSRUBY charhandler.rb
         | 
| 32 | 
            +
            #$RUBYLEXERVSRUBY term.rb
         | 
| 33 | 
            +
            #$RUBYLEXERVSRUBY token.rb
         | 
| 34 | 
            +
            #$RUBYLEXERVSRUBY rubycode.rb
         | 
| 35 | 
            +
            #$RUBYLEXERVSRUBY rumalexer.rb
         | 
| 36 | 
            +
            #$RUBYLEXERVSRUBY rubylexer.rb
         | 
| 37 | 
            +
            #$RUBYLEXERVSRUBY rulexer.rb
         | 
| 38 | 
            +
            #$RUBYLEXERVSRUBY matcher.rb
         | 
| 39 | 
            +
            ####$RUBYLEXERVSRUBY pattern.rb
         | 
| 40 | 
            +
            #$RUBYLEXERVSRUBY rumaparser.rb
         | 
| 41 | 
            +
             | 
| 42 | 
            +
             | 
| 43 | 
            +
            #also look in bin and lib directories
         | 
| 44 | 
            +
            file -L `echo $PATH":/sbin:/usr/sbin"|tr : "\n"|sort -u|xargs -i echo "{}/*"`| \
         | 
| 45 | 
            +
             grep "ruby[^:]*script"|cut -d: -f1 > testresults/rubyexelibs
         | 
| 46 | 
            +
             | 
| 47 | 
            +
            ruby -e 'print ($:.sort.uniq+[""]).join"\n"'|xargs -i ls "{}/*.rb" >> testresults/rubyexelibs
         | 
| 48 | 
            +
             | 
| 49 | 
            +
               for i in `cat testresults/rubyexelibs`; do
         | 
| 50 | 
            +
                  $RUBYLEXERVSRUBY $i;
         | 
| 51 | 
            +
               done
         | 
| @@ -0,0 +1,729 @@ | |
| 1 | 
            +
            class String
         | 
| 2 | 
            +
                def / regex
         | 
| 3 | 
            +
                    scan(regex).first
         | 
| 4 | 
            +
                end
         | 
| 5 | 
            +
            end
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            module Bytes
         | 
| 8 | 
            +
                KILOBYTE, MEGABYTE, GIGABYTE, TERABYTE, PETABYTE = (1..5).map { |x| 2 ** (10 * x) }
         | 
| 9 | 
            +
                FactorOfSuffix = Hash.new(1)
         | 
| 10 | 
            +
                constants.each do |c|
         | 
| 11 | 
            +
                    FactorOfSuffix[c[0,1]] = const_get c
         | 
| 12 | 
            +
                end
         | 
| 13 | 
            +
               
         | 
| 14 | 
            +
                def Bytes.factor_of_suffix suff
         | 
| 15 | 
            +
                    FactorOfSuffix[suff]
         | 
| 16 | 
            +
                end
         | 
| 17 | 
            +
               
         | 
| 18 | 
            +
                def Bytes.[] str
         | 
| 19 | 
            +
                    n, fac = str / /(.+)([A-Z])/
         | 
| 20 | 
            +
                    n = n.to_i
         | 
| 21 | 
            +
                    fac = factor_of_suffix fac
         | 
| 22 | 
            +
                    n * fac
         | 
| 23 | 
            +
                end
         | 
| 24 | 
            +
            end
         | 
| 25 | 
            +
             | 
| 26 | 
            +
            class String
         | 
| 27 | 
            +
                def to_bytes
         | 
| 28 | 
            +
                    Bytes[self]
         | 
| 29 | 
            +
                end
         | 
| 30 | 
            +
            end
         | 
| 31 | 
            +
             | 
| 32 | 
            +
            p '01K'.to_bytes
         | 
| 33 | 
            +
            p '%d - %p' % [Bytes.constants.size, self]
         | 
| 34 | 
            +
             | 
| 35 | 
            +
            p 'abc' / /([ac])/
         | 
| 36 | 
            +
             | 
| 37 | 
            +
            p 'abc' + /([ac])/
         | 
| 38 | 
            +
            p 'abc' - /([ac])/
         | 
| 39 | 
            +
            p 'abc' * /([ac])/
         | 
| 40 | 
            +
            p 'abc' ** /([ac])/
         | 
| 41 | 
            +
            p 'abc' % /([ac])/
         | 
| 42 | 
            +
            p 'abc' ~ /([ac])/
         | 
| 43 | 
            +
             | 
| 44 | 
            +
            require 'benchmark'
         | 
| 45 | 
            +
            S = 'bla' * 100 + "\n" + "\t"*4
         | 
| 46 | 
            +
            T = 200000
         | 
| 47 | 
            +
             | 
| 48 | 
            +
            Benchmark.bm(1) do |bm|
         | 
| 49 | 
            +
                GC.sweep
         | 
| 50 | 
            +
                bm.report('?') { T.times { S.index(?\n) } }
         | 
| 51 | 
            +
                GC.sweep
         | 
| 52 | 
            +
                bm.report('"') { T.times { S.index("\n") } }
         | 
| 53 | 
            +
                GC.sweep
         | 
| 54 | 
            +
                bm.report('/') { T.times { S.index(/\n/) } }
         | 
| 55 | 
            +
                GC.sweep
         | 
| 56 | 
            +
            end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
              def next?()
         | 
| 59 | 
            +
                !end?
         | 
| 60 | 
            +
              end
         | 
| 61 | 
            +
              # Rewinds the generator.
         | 
| 62 | 
            +
              def rewind()
         | 
| 63 | 
            +
                initialize(nil, &@block) if @index.nonzero?
         | 
| 64 | 
            +
             | 
| 65 | 
            +
                self
         | 
| 66 | 
            +
              end
         | 
| 67 | 
            +
             | 
| 68 | 
            +
            a = []
         | 
| 69 | 
            +
            a << a
         | 
| 70 | 
            +
            p a  #-> [[...]]
         | 
| 71 | 
            +
             | 
| 72 | 
            +
            # format.rb: Written by Tadayoshi Funaba 1999-2004
         | 
| 73 | 
            +
            # $Id: format.rb,v 2.14 2004-11-06 10:58:40+09 tadf Exp $
         | 
| 74 | 
            +
             | 
| 75 | 
            +
            require 'rational'
         | 
| 76 | 
            +
             | 
| 77 | 
            +
            class Date
         | 
| 78 | 
            +
             | 
| 79 | 
            +
              MONTHS = {
         | 
| 80 | 
            +
                'january'  => 1, 'february' => 2, 'march'    => 3, 'april'    => 4,
         | 
| 81 | 
            +
                'may'      => 5, 'june'     => 6, 'july'     => 7, 'august'   => 8,
         | 
| 82 | 
            +
                'september'=> 9, 'october'  =>10, 'november' =>11, 'december' =>12
         | 
| 83 | 
            +
              }
         | 
| 84 | 
            +
             | 
| 85 | 
            +
              DAYS = {
         | 
| 86 | 
            +
                'sunday'   => 0, 'monday'   => 1, 'tuesday'  => 2, 'wednesday'=> 3,
         | 
| 87 | 
            +
                'thursday' => 4, 'friday'   => 5, 'saturday' => 6
         | 
| 88 | 
            +
              }
         | 
| 89 | 
            +
             | 
| 90 | 
            +
              ABBR_MONTHS = {
         | 
| 91 | 
            +
                'jan'      => 1, 'feb'      => 2, 'mar'      => 3, 'apr'      => 4,
         | 
| 92 | 
            +
                'may'      => 5, 'jun'      => 6, 'jul'      => 7, 'aug'      => 8,
         | 
| 93 | 
            +
                'sep'      => 9, 'oct'      =>10, 'nov'      =>11, 'dec'      =>12
         | 
| 94 | 
            +
              }
         | 
| 95 | 
            +
             | 
| 96 | 
            +
              ABBR_DAYS = {
         | 
| 97 | 
            +
                'sun'      => 0, 'mon'      => 1, 'tue'      => 2, 'wed'      => 3,
         | 
| 98 | 
            +
                'thu'      => 4, 'fri'      => 5, 'sat'      => 6
         | 
| 99 | 
            +
              }
         | 
| 100 | 
            +
             | 
| 101 | 
            +
              ZONES = {
         | 
| 102 | 
            +
                'ut'  =>  0*3600, 'gmt' =>  0*3600, 'est' => -5*3600, 'edt' => -4*3600,
         | 
| 103 | 
            +
                'cst' => -6*3600, 'cdt' => -5*3600, 'mst' => -7*3600, 'mdt' => -6*3600,
         | 
| 104 | 
            +
                'pst' => -8*3600, 'pdt' => -7*3600,
         | 
| 105 | 
            +
                'a'   =>  1*3600, 'b'   =>  2*3600, 'c'   =>  3*3600, 'd'   =>  4*3600,
         | 
| 106 | 
            +
                'e'   =>  5*3600, 'f'   =>  6*3600, 'g'   =>  7*3600, 'h'   =>  8*3600,
         | 
| 107 | 
            +
                'i'   =>  9*3600, 'k'   => 10*3600, 'l'   => 11*3600, 'm'   => 12*3600,
         | 
| 108 | 
            +
                'n'   => -1*3600, 'o'   => -2*3600, 'p'   => -3*3600, 'q'   => -4*3600,
         | 
| 109 | 
            +
                'r'   => -5*3600, 's'   => -6*3600, 't'   => -7*3600, 'u'   => -8*3600,
         | 
| 110 | 
            +
                'v'   => -9*3600, 'w'   =>-10*3600, 'x'   =>-11*3600, 'y'   =>-12*3600,
         | 
| 111 | 
            +
                'z'   =>  0*3600,
         | 
| 112 | 
            +
                'utc' =>  0*3600, 'wet' =>  0*3600, 'bst' =>  1*3600, 'wat' => -1*3600,
         | 
| 113 | 
            +
                'at'  => -2*3600, 'ast' => -4*3600, 'adt' => -3*3600, 'yst' => -9*3600,
         | 
| 114 | 
            +
                'ydt' => -8*3600, 'hst' =>-10*3600, 'hdt' => -9*3600, 'cat' =>-10*3600,
         | 
| 115 | 
            +
                'ahst'=>-10*3600, 'nt'  =>-11*3600, 'idlw'=>-12*3600, 'cet' =>  1*3600,
         | 
| 116 | 
            +
                'met' =>  1*3600, 'mewt'=>  1*3600, 'mest'=>  2*3600, 'mesz'=>  2*3600,
         | 
| 117 | 
            +
                'swt' =>  1*3600, 'sst' =>  2*3600, 'fwt' =>  1*3600, 'fst' =>  2*3600,
         | 
| 118 | 
            +
                'eet' =>  2*3600, 'bt'  =>  3*3600, 'zp4' =>  4*3600, 'zp5' =>  5*3600,
         | 
| 119 | 
            +
                'zp6' =>  6*3600, 'wast'=>  7*3600, 'wadt'=>  8*3600, 'cct' =>  8*3600,
         | 
| 120 | 
            +
                'jst' =>  9*3600, 'east'=> 10*3600, 'eadt'=> 11*3600, 'gst' => 10*3600,
         | 
| 121 | 
            +
                'nzt' => 12*3600, 'nzst'=> 12*3600, 'nzdt'=> 13*3600, 'idle'=> 12*3600
         | 
| 122 | 
            +
              }
         | 
| 123 | 
            +
             | 
| 124 | 
            +
              def self.__strptime(str, fmt, elem)
         | 
| 125 | 
            +
                fmt.scan(/%[EO]?.|./o) do |c|
         | 
| 126 | 
            +
                  cc = c.sub(/\A%[EO]?(.)\Z/o, '%\\1')
         | 
| 127 | 
            +
                  case cc
         | 
| 128 | 
            +
                  when /\A\s/o
         | 
| 129 | 
            +
                str.sub!(/\A[\s\v]+/o, '')
         | 
| 130 | 
            +
                  when '%A', '%a'
         | 
| 131 | 
            +
                return unless str.sub!(/\A([a-z]+)\b/io, '')
         | 
| 132 | 
            +
                val = DAYS[$1.downcase] || ABBR_DAYS[$1.downcase]
         | 
| 133 | 
            +
                return unless val
         | 
| 134 | 
            +
                elem[:wday] = val
         | 
| 135 | 
            +
                  when '%B', '%b', '%h'
         | 
| 136 | 
            +
                return unless str.sub!(/\A([a-z]+)\b/io, '')
         | 
| 137 | 
            +
                val = MONTHS[$1.downcase] || ABBR_MONTHS[$1.downcase]
         | 
| 138 | 
            +
                return unless val
         | 
| 139 | 
            +
                elem[:mon] = val
         | 
| 140 | 
            +
                  when '%C'
         | 
| 141 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 142 | 
            +
                val = $1.to_i
         | 
| 143 | 
            +
                elem[:cent] = val
         | 
| 144 | 
            +
                  when '%c'
         | 
| 145 | 
            +
                return unless __strptime(str, '%a %b %e %H:%M:%S %Y', elem)
         | 
| 146 | 
            +
                  when '%D'
         | 
| 147 | 
            +
                return unless __strptime(str, '%m/%d/%y', elem)
         | 
| 148 | 
            +
                  when '%d', '%e'
         | 
| 149 | 
            +
                return unless str.sub!(/\A ?(\d+)/o, '')
         | 
| 150 | 
            +
                val = $1.to_i
         | 
| 151 | 
            +
                return unless (1..31) === val
         | 
| 152 | 
            +
                elem[:mday] = val
         | 
| 153 | 
            +
                  when '%F'
         | 
| 154 | 
            +
                return unless __strptime(str, '%Y-%m-%d', elem)
         | 
| 155 | 
            +
                  when '%G'
         | 
| 156 | 
            +
                return unless str.sub!(/\A([-+]?\d+)/o, '')
         | 
| 157 | 
            +
                val = $1.to_i
         | 
| 158 | 
            +
                elem[:cwyear] = val
         | 
| 159 | 
            +
                  when '%g'
         | 
| 160 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 161 | 
            +
                val = $1.to_i
         | 
| 162 | 
            +
                return unless (0..99) === val
         | 
| 163 | 
            +
                elem[:cwyear] = val
         | 
| 164 | 
            +
                elem[:cent] ||= if val >= 69 then 19 else 20 end
         | 
| 165 | 
            +
                  when '%H', '%k'
         | 
| 166 | 
            +
                return unless str.sub!(/\A ?(\d+)/o, '')
         | 
| 167 | 
            +
                val = $1.to_i
         | 
| 168 | 
            +
                return unless (0..24) === val
         | 
| 169 | 
            +
                elem[:hour] = val
         | 
| 170 | 
            +
                  when '%I', '%l'
         | 
| 171 | 
            +
                return unless str.sub!(/\A ?(\d+)/o, '')
         | 
| 172 | 
            +
                val = $1.to_i
         | 
| 173 | 
            +
                return unless (1..12) === val
         | 
| 174 | 
            +
                elem[:hour] = val
         | 
| 175 | 
            +
                  when '%j'
         | 
| 176 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 177 | 
            +
                val = $1.to_i
         | 
| 178 | 
            +
                return unless (1..366) === val
         | 
| 179 | 
            +
                elem[:yday] = val
         | 
| 180 | 
            +
                  when '%M'
         | 
| 181 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 182 | 
            +
                val = $1.to_i
         | 
| 183 | 
            +
                return unless (0..59) === val
         | 
| 184 | 
            +
                elem[:min] = val
         | 
| 185 | 
            +
                  when '%m'
         | 
| 186 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 187 | 
            +
                val = $1.to_i
         | 
| 188 | 
            +
                return unless (1..12) === val
         | 
| 189 | 
            +
                elem[:mon] = val
         | 
| 190 | 
            +
                  when '%n'
         | 
| 191 | 
            +
                return unless __strptime(str, ' ', elem)
         | 
| 192 | 
            +
                  when '%p', '%P'
         | 
| 193 | 
            +
                return unless str.sub!(/\A([ap])(?:m\b|\.m\.)/io, '')
         | 
| 194 | 
            +
                elem[:merid] = if $1.downcase == 'a' then 0 else 12 end
         | 
| 195 | 
            +
                  when '%R'
         | 
| 196 | 
            +
                return unless __strptime(str, '%H:%M', elem)
         | 
| 197 | 
            +
                  when '%r'
         | 
| 198 | 
            +
                return unless __strptime(str, '%I:%M:%S %p', elem)
         | 
| 199 | 
            +
                  when '%S'
         | 
| 200 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 201 | 
            +
                val = $1.to_i
         | 
| 202 | 
            +
                return unless (0..60) === val
         | 
| 203 | 
            +
                elem[:sec] = val
         | 
| 204 | 
            +
                  when '%s'
         | 
| 205 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 206 | 
            +
                val = $1.to_i
         | 
| 207 | 
            +
                elem[:seconds] = val
         | 
| 208 | 
            +
                  when '%T'
         | 
| 209 | 
            +
                return unless __strptime(str, '%H:%M:%S', elem)
         | 
| 210 | 
            +
                  when '%t'
         | 
| 211 | 
            +
                return unless __strptime(str, ' ', elem)
         | 
| 212 | 
            +
                  when '%U', '%W'
         | 
| 213 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 214 | 
            +
                val = $1.to_i
         | 
| 215 | 
            +
                return unless (0..53) === val
         | 
| 216 | 
            +
                elem[if c == '%U' then :wnum0 else :wnum1 end] = val
         | 
| 217 | 
            +
                  when '%u'
         | 
| 218 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 219 | 
            +
                val = $1.to_i
         | 
| 220 | 
            +
                return unless (1..7) === val
         | 
| 221 | 
            +
                elem[:cwday] = val
         | 
| 222 | 
            +
                  when '%V'
         | 
| 223 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 224 | 
            +
                val = $1.to_i
         | 
| 225 | 
            +
                return unless (1..53) === val
         | 
| 226 | 
            +
                elem[:cweek] = val
         | 
| 227 | 
            +
                  when '%v'
         | 
| 228 | 
            +
                return unless __strptime(str, '%e-%b-%Y', elem)
         | 
| 229 | 
            +
                  when '%w'
         | 
| 230 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 231 | 
            +
                val = $1.to_i
         | 
| 232 | 
            +
                return unless (0..6) === val
         | 
| 233 | 
            +
                elem[:wday] = val
         | 
| 234 | 
            +
                  when '%X'
         | 
| 235 | 
            +
                return unless __strptime(str, '%H:%M:%S', elem)
         | 
| 236 | 
            +
                  when '%x'
         | 
| 237 | 
            +
                return unless __strptime(str, '%m/%d/%y', elem)
         | 
| 238 | 
            +
                  when '%Y'
         | 
| 239 | 
            +
                return unless str.sub!(/\A([-+]?\d+)/o, '')
         | 
| 240 | 
            +
                val = $1.to_i
         | 
| 241 | 
            +
                elem[:year] = val
         | 
| 242 | 
            +
                  when '%y'
         | 
| 243 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 244 | 
            +
                val = $1.to_i
         | 
| 245 | 
            +
                return unless (0..99) === val
         | 
| 246 | 
            +
                elem[:year] = val
         | 
| 247 | 
            +
                elem[:cent] ||= if val >= 69 then 19 else 20 end
         | 
| 248 | 
            +
                  when '%Z', '%z'
         | 
| 249 | 
            +
                return unless str.sub!(/\A([-+:a-z0-9]+(?:\s+dst\b)?)/io, '')
         | 
| 250 | 
            +
                val = $1
         | 
| 251 | 
            +
                elem[:zone] = val
         | 
| 252 | 
            +
                offset = zone_to_diff(val)
         | 
| 253 | 
            +
                elem[:offset] = offset
         | 
| 254 | 
            +
                  when '%%'
         | 
| 255 | 
            +
                return unless str.sub!(/\A%/o, '')
         | 
| 256 | 
            +
                  when '%+'
         | 
| 257 | 
            +
                return unless __strptime(str, '%a %b %e %H:%M:%S %Z %Y', elem)
         | 
| 258 | 
            +
            =begin
         | 
| 259 | 
            +
                  when '%.'
         | 
| 260 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 261 | 
            +
                val = $1.to_i.to_r / (10**$1.size)
         | 
| 262 | 
            +
                elem[:sec_fraction] = val
         | 
| 263 | 
            +
            =end
         | 
| 264 | 
            +
                  when '%1'
         | 
| 265 | 
            +
                return unless str.sub!(/\A(\d+)/o, '')
         | 
| 266 | 
            +
                val = $1.to_i
         | 
| 267 | 
            +
                elem[:jd] = val
         | 
| 268 | 
            +
                  when '%2'
         | 
| 269 | 
            +
                return unless __strptime(str, '%Y-%j', elem)
         | 
| 270 | 
            +
                  when '%3'
         | 
| 271 | 
            +
                return unless __strptime(str, '%F', elem)
         | 
| 272 | 
            +
                  else
         | 
| 273 | 
            +
                return unless str.sub!(Regexp.new('\\A' + Regexp.quote(c)), '')
         | 
| 274 | 
            +
                  end
         | 
| 275 | 
            +
                end
         | 
| 276 | 
            +
             | 
| 277 | 
            +
                if cent = elem.delete(:cent)
         | 
| 278 | 
            +
                  if elem[:cwyear]
         | 
| 279 | 
            +
                elem[:cwyear] += cent * 100
         | 
| 280 | 
            +
                  end
         | 
| 281 | 
            +
                  if elem[:year]
         | 
| 282 | 
            +
                elem[:year] += cent * 100
         | 
| 283 | 
            +
                  end
         | 
| 284 | 
            +
                end
         | 
| 285 | 
            +
             | 
| 286 | 
            +
                if merid = elem.delete(:merid)
         | 
| 287 | 
            +
                  if elem[:hour]
         | 
| 288 | 
            +
                elem[:hour] %= 12
         | 
| 289 | 
            +
                elem[:hour] += merid
         | 
| 290 | 
            +
                  end
         | 
| 291 | 
            +
                end
         | 
| 292 | 
            +
             | 
| 293 | 
            +
                str
         | 
| 294 | 
            +
              end
         | 
| 295 | 
            +
             | 
| 296 | 
            +
              private_class_method :__strptime
         | 
| 297 | 
            +
             | 
| 298 | 
            +
              def self._strptime(str, fmt='%F')
         | 
| 299 | 
            +
                elem = {}
         | 
| 300 | 
            +
                elem if __strptime(str.dup, fmt, elem)
         | 
| 301 | 
            +
              end
         | 
| 302 | 
            +
             | 
| 303 | 
            +
              PARSE_MONTHPAT = ABBR_MONTHS.keys.join('|')
         | 
| 304 | 
            +
              PARSE_DAYPAT   = ABBR_DAYS.  keys.join('|')
         | 
| 305 | 
            +
             | 
| 306 | 
            +
              def self._parse(str, comp=false)
         | 
| 307 | 
            +
                str = str.dup
         | 
| 308 | 
            +
             | 
| 309 | 
            +
                str.gsub!(/[^-+,.\/:0-9a-z]+/ino, ' ')
         | 
| 310 | 
            +
             | 
| 311 | 
            +
                # day
         | 
| 312 | 
            +
                if str.sub!(/(#{PARSE_DAYPAT})\S*/ino, ' ')
         | 
| 313 | 
            +
                  wday = ABBR_DAYS[$1.downcase]
         | 
| 314 | 
            +
                end
         | 
| 315 | 
            +
             | 
| 316 | 
            +
                # time
         | 
| 317 | 
            +
                if str.sub!(
         | 
| 318 | 
            +
                    /(\d+):(\d+)
         | 
| 319 | 
            +
                     (?:
         | 
| 320 | 
            +
                       :(\d+)(?:[,.](\d*))?
         | 
| 321 | 
            +
                     )?
         | 
| 322 | 
            +
                     (?:
         | 
| 323 | 
            +
                       \s*
         | 
| 324 | 
            +
                       ([ap])(?:m\b|\.m\.)
         | 
| 325 | 
            +
                     )?
         | 
| 326 | 
            +
                     (?:
         | 
| 327 | 
            +
                       \s*
         | 
| 328 | 
            +
                       (
         | 
| 329 | 
            +
                         [a-z]+(?:\s+dst)?\b
         | 
| 330 | 
            +
                       |
         | 
| 331 | 
            +
                         [-+]\d+(?::?\d+)
         | 
| 332 | 
            +
                       )
         | 
| 333 | 
            +
                     )?
         | 
| 334 | 
            +
                    /inox,
         | 
| 335 | 
            +
                    ' ')
         | 
| 336 | 
            +
                  hour = $1.to_i
         | 
| 337 | 
            +
                  min = $2.to_i
         | 
| 338 | 
            +
                  sec = $3.to_i if $3
         | 
| 339 | 
            +
                  if $4
         | 
| 340 | 
            +
                sec_fraction = $4.to_i.to_r / (10**$4.size)
         | 
| 341 | 
            +
                  end
         | 
| 342 | 
            +
             | 
| 343 | 
            +
                  if $5
         | 
| 344 | 
            +
                hour %= 12
         | 
| 345 | 
            +
                if $5.downcase == 'p'
         | 
| 346 | 
            +
                  hour += 12
         | 
| 347 | 
            +
                end
         | 
| 348 | 
            +
                  end
         | 
| 349 | 
            +
             | 
| 350 | 
            +
                  if $6
         | 
| 351 | 
            +
                zone = $6
         | 
| 352 | 
            +
                  end
         | 
| 353 | 
            +
                end
         | 
| 354 | 
            +
             | 
| 355 | 
            +
                # eu
         | 
| 356 | 
            +
                if str.sub!(
         | 
| 357 | 
            +
                    /(\d+)\S*
         | 
| 358 | 
            +
                     \s+
         | 
| 359 | 
            +
                     (#{PARSE_MONTHPAT})\S*
         | 
| 360 | 
            +
                     (?:
         | 
| 361 | 
            +
                       \s+
         | 
| 362 | 
            +
                       (-?\d+)
         | 
| 363 | 
            +
                     )?
         | 
| 364 | 
            +
                    /inox,
         | 
| 365 | 
            +
                    ' ')
         | 
| 366 | 
            +
                  mday = $1.to_i
         | 
| 367 | 
            +
                  mon = ABBR_MONTHS[$2.downcase]
         | 
| 368 | 
            +
             | 
| 369 | 
            +
                  if $3
         | 
| 370 | 
            +
                year = $3.to_i
         | 
| 371 | 
            +
                if $3.size > 2
         | 
| 372 | 
            +
                  comp = false
         | 
| 373 | 
            +
                end
         | 
| 374 | 
            +
                  end
         | 
| 375 | 
            +
             | 
| 376 | 
            +
                # us
         | 
| 377 | 
            +
                elsif str.sub!(
         | 
| 378 | 
            +
                       /(#{PARSE_MONTHPAT})\S*
         | 
| 379 | 
            +
                        \s+
         | 
| 380 | 
            +
                        (\d+)\S*
         | 
| 381 | 
            +
                        (?:
         | 
| 382 | 
            +
                          \s+
         | 
| 383 | 
            +
                          (-?\d+)
         | 
| 384 | 
            +
                        )?
         | 
| 385 | 
            +
                       /inox,
         | 
| 386 | 
            +
                       ' ')
         | 
| 387 | 
            +
                  mon = ABBR_MONTHS[$1.downcase]
         | 
| 388 | 
            +
                  mday = $2.to_i
         | 
| 389 | 
            +
             | 
| 390 | 
            +
                  if $3
         | 
| 391 | 
            +
                year = $3.to_i
         | 
| 392 | 
            +
                if $3.size > 2
         | 
| 393 | 
            +
                  comp = false
         | 
| 394 | 
            +
                end
         | 
| 395 | 
            +
                  end
         | 
| 396 | 
            +
             | 
| 397 | 
            +
                # iso
         | 
| 398 | 
            +
                elsif str.sub!(/([-+]?\d+)-(\d+)-(-?\d+)/no, ' ')
         | 
| 399 | 
            +
                  year = $1.to_i
         | 
| 400 | 
            +
                  mon = $2.to_i
         | 
| 401 | 
            +
                  mday = $3.to_i
         | 
| 402 | 
            +
             | 
| 403 | 
            +
                  if $1.size > 2
         | 
| 404 | 
            +
                comp = false
         | 
| 405 | 
            +
                  elsif $3.size > 2
         | 
| 406 | 
            +
                comp = false
         | 
| 407 | 
            +
                mday, mon, year = year, mon, mday
         | 
| 408 | 
            +
                  end
         | 
| 409 | 
            +
             | 
| 410 | 
            +
                # jis
         | 
| 411 | 
            +
                elsif str.sub!(/([MTSH])(\d+)\.(\d+)\.(\d+)/ino, ' ')
         | 
| 412 | 
            +
                  e = { 'm'=>1867,
         | 
| 413 | 
            +
                    't'=>1911,
         | 
| 414 | 
            +
                    's'=>1925,
         | 
| 415 | 
            +
                    'h'=>1988
         | 
| 416 | 
            +
                  }[$1.downcase]
         | 
| 417 | 
            +
                  year = $2.to_i + e
         | 
| 418 | 
            +
                  mon = $3.to_i
         | 
| 419 | 
            +
                  mday = $4.to_i
         | 
| 420 | 
            +
             | 
| 421 | 
            +
                # vms
         | 
| 422 | 
            +
                elsif str.sub!(/(-?\d+)-(#{PARSE_MONTHPAT})[^-]*-(-?\d+)/ino, ' ')
         | 
| 423 | 
            +
                  mday = $1.to_i
         | 
| 424 | 
            +
                  mon = ABBR_MONTHS[$2.downcase]
         | 
| 425 | 
            +
                  year = $3.to_i
         | 
| 426 | 
            +
             | 
| 427 | 
            +
                  if $1.size > 2
         | 
| 428 | 
            +
                comp = false
         | 
| 429 | 
            +
                year, mon, mday = mday, mon, year
         | 
| 430 | 
            +
                  elsif $3.size > 2
         | 
| 431 | 
            +
                comp = false
         | 
| 432 | 
            +
                  end
         | 
| 433 | 
            +
             | 
| 434 | 
            +
                # sla
         | 
| 435 | 
            +
                elsif str.sub!(%r|(-?\d+)/(\d+)(?:/(-?\d+))?|no, ' ')
         | 
| 436 | 
            +
                  mon = $1.to_i
         | 
| 437 | 
            +
                  mday = $2.to_i
         | 
| 438 | 
            +
             | 
| 439 | 
            +
                  if $3
         | 
| 440 | 
            +
                year = $3.to_i
         | 
| 441 | 
            +
                if $3.size > 2
         | 
| 442 | 
            +
                  comp = false
         | 
| 443 | 
            +
                end
         | 
| 444 | 
            +
                  end
         | 
| 445 | 
            +
             | 
| 446 | 
            +
                  if $3 && $1.size > 2
         | 
| 447 | 
            +
                comp = false
         | 
| 448 | 
            +
                year, mon, mday = mon, mday, year
         | 
| 449 | 
            +
                  end
         | 
| 450 | 
            +
             | 
| 451 | 
            +
                # ddd
         | 
| 452 | 
            +
                elsif str.sub!(
         | 
| 453 | 
            +
                       /([-+]?)(\d{4,14})
         | 
| 454 | 
            +
                        (?:
         | 
| 455 | 
            +
                          \s*
         | 
| 456 | 
            +
                          T?
         | 
| 457 | 
            +
                          \s*
         | 
| 458 | 
            +
                          (\d{2,6})(?:[,.](\d*))?
         | 
| 459 | 
            +
                        )?
         | 
| 460 | 
            +
                        (?:
         | 
| 461 | 
            +
                          \s*
         | 
| 462 | 
            +
                          (
         | 
| 463 | 
            +
                        Z
         | 
| 464 | 
            +
                          |
         | 
| 465 | 
            +
                        [-+]\d{2,4}
         | 
| 466 | 
            +
                          )
         | 
| 467 | 
            +
                          \b
         | 
| 468 | 
            +
                        )?
         | 
| 469 | 
            +
                       /inox,
         | 
| 470 | 
            +
                       ' ')
         | 
| 471 | 
            +
                  case $2.size
         | 
| 472 | 
            +
                  when 4
         | 
| 473 | 
            +
                mon  = $2[ 0, 2].to_i
         | 
| 474 | 
            +
                mday = $2[ 2, 2].to_i
         | 
| 475 | 
            +
                  when 6
         | 
| 476 | 
            +
                year = ($1 + $2[ 0, 2]).to_i
         | 
| 477 | 
            +
                mon  = $2[ 2, 2].to_i
         | 
| 478 | 
            +
                mday = $2[ 4, 2].to_i
         | 
| 479 | 
            +
                  when 8, 10, 12, 14
         | 
| 480 | 
            +
                year = ($1 + $2[ 0, 4]).to_i
         | 
| 481 | 
            +
                mon  = $2[ 4, 2].to_i
         | 
| 482 | 
            +
                mday = $2[ 6, 2].to_i
         | 
| 483 | 
            +
                hour = $2[ 8, 2].to_i if $2.size >= 10
         | 
| 484 | 
            +
                min  = $2[10, 2].to_i if $2.size >= 12
         | 
| 485 | 
            +
                sec  = $2[12, 2].to_i if $2.size >= 14
         | 
| 486 | 
            +
                comp = false
         | 
| 487 | 
            +
                  end
         | 
| 488 | 
            +
                  if $3
         | 
| 489 | 
            +
                case $3.size
         | 
| 490 | 
            +
                when 2, 4, 6
         | 
| 491 | 
            +
                  hour = $3[ 0, 2].to_i
         | 
| 492 | 
            +
                  min  = $3[ 2, 2].to_i if $3.size >= 4
         | 
| 493 | 
            +
                  sec  = $3[ 4, 2].to_i if $3.size >= 6
         | 
| 494 | 
            +
                end
         | 
| 495 | 
            +
                  end
         | 
| 496 | 
            +
                  if $4
         | 
| 497 | 
            +
                sec_fraction = $4.to_i.to_r / (10**$4.size)
         | 
| 498 | 
            +
                  end
         | 
| 499 | 
            +
                  if $5
         | 
| 500 | 
            +
                zone = $5
         | 
| 501 | 
            +
                  end
         | 
| 502 | 
            +
                end
         | 
| 503 | 
            +
             | 
| 504 | 
            +
                if str.sub!(/\b(bc\b|bce\b|b\.c\.|b\.c\.e\.)/ino, ' ')
         | 
| 505 | 
            +
                  if year
         | 
| 506 | 
            +
                year = -year + 1
         | 
| 507 | 
            +
                  end
         | 
| 508 | 
            +
                end
         | 
| 509 | 
            +
             | 
| 510 | 
            +
                if comp and year
         | 
| 511 | 
            +
                  if year >= 0 and year <= 99
         | 
| 512 | 
            +
                if year >= 69
         | 
| 513 | 
            +
                  year += 1900
         | 
| 514 | 
            +
                else
         | 
| 515 | 
            +
                  year += 2000
         | 
| 516 | 
            +
                end
         | 
| 517 | 
            +
                  end
         | 
| 518 | 
            +
                end
         | 
| 519 | 
            +
             | 
| 520 | 
            +
                elem = {}
         | 
| 521 | 
            +
                elem[:year] = year if year
         | 
| 522 | 
            +
                elem[:mon] = mon if mon
         | 
| 523 | 
            +
                elem[:mday] = mday if mday
         | 
| 524 | 
            +
                elem[:hour] = hour if hour
         | 
| 525 | 
            +
                elem[:min] = min if min
         | 
| 526 | 
            +
                elem[:sec] = sec if sec
         | 
| 527 | 
            +
                elem[:sec_fraction] = sec_fraction if sec_fraction
         | 
| 528 | 
            +
                elem[:zone] = zone if zone
         | 
| 529 | 
            +
                offset = zone_to_diff(zone) if zone
         | 
| 530 | 
            +
                elem[:offset] = offset if offset
         | 
| 531 | 
            +
                elem[:wday] = wday if wday
         | 
| 532 | 
            +
                elem
         | 
| 533 | 
            +
              end
         | 
| 534 | 
            +
             | 
| 535 | 
            +
              def self.zone_to_diff(str)
         | 
| 536 | 
            +
                abb, dst = str.downcase.split(/\s+/o, 2)
         | 
| 537 | 
            +
                if ZONES.include?(abb)
         | 
| 538 | 
            +
                  offset  = ZONES[abb]
         | 
| 539 | 
            +
                  offset += 3600 if dst
         | 
| 540 | 
            +
                elsif /\A([-+])(\d{2}):?(\d{2})?\Z/no =~ str
         | 
| 541 | 
            +
                  offset = $2.to_i * 3600 + $3.to_i * 60
         | 
| 542 | 
            +
                  offset *= -1 if $1 == '-'
         | 
| 543 | 
            +
                end
         | 
| 544 | 
            +
                offset
         | 
| 545 | 
            +
              end
         | 
| 546 | 
            +
             | 
| 547 | 
            +
              def strftime(fmt='%F')
         | 
| 548 | 
            +
                o = ''
         | 
| 549 | 
            +
                fmt.scan(/%[EO]?.|./o) do |c|
         | 
| 550 | 
            +
                  cc = c.sub(/^%[EO]?(.)$/o, '%\\1')
         | 
| 551 | 
            +
                  case cc
         | 
| 552 | 
            +
                  when '%A'; o << DAYNAMES[wday]
         | 
| 553 | 
            +
                  when '%a'; o << ABBR_DAYNAMES[wday]
         | 
| 554 | 
            +
                  when '%B'; o << MONTHNAMES[mon]
         | 
| 555 | 
            +
                  when '%b'; o << ABBR_MONTHNAMES[mon]
         | 
| 556 | 
            +
                  when '%C'; o << '%02d' % (year / 100.0).floor        # P2,ID
         | 
| 557 | 
            +
                  when '%c'; o << strftime('%a %b %e %H:%M:%S %Y')
         | 
| 558 | 
            +
                  when '%D'; o << strftime('%m/%d/%y')            # P2,ID
         | 
| 559 | 
            +
                  when '%d'; o << '%02d' % mday
         | 
| 560 | 
            +
                  when '%e'; o <<  '%2d' % mday
         | 
| 561 | 
            +
                  when '%F'; o << strftime('%Y-%m-%d')            # ID
         | 
| 562 | 
            +
                  when '%G'; o << '%.4d' %  cwyear                # ID
         | 
| 563 | 
            +
                  when '%g'; o << '%02d' % (cwyear % 100)            # ID
         | 
| 564 | 
            +
                  when '%H'; o << '%02d' %   hour
         | 
| 565 | 
            +
                  when '%h'; o << strftime('%b')                # P2,ID
         | 
| 566 | 
            +
                  when '%I'; o << '%02d' % ((hour % 12).nonzero? or 12)
         | 
| 567 | 
            +
                  when '%j'; o << '%03d' % yday
         | 
| 568 | 
            +
                  when '%k'; o <<  '%2d' %   hour                # AR,TZ,GL
         | 
| 569 | 
            +
                  when '%l'; o <<  '%2d' % ((hour % 12).nonzero? or 12)    # AR,TZ,GL
         | 
| 570 | 
            +
                  when '%M'; o << '%02d' % min
         | 
| 571 | 
            +
                  when '%m'; o << '%02d' % mon
         | 
| 572 | 
            +
                  when '%n'; o << "\n"                    # P2,ID
         | 
| 573 | 
            +
                  when '%P'; o << if hour < 12 then 'am' else 'pm' end    # GL
         | 
| 574 | 
            +
                  when '%p'; o << if hour < 12 then 'AM' else 'PM' end
         | 
| 575 | 
            +
                  when '%R'; o << strftime('%H:%M')                # ID
         | 
| 576 | 
            +
                  when '%r'; o << strftime('%I:%M:%S %p')            # P2,ID
         | 
| 577 | 
            +
                  when '%S'; o << '%02d' % sec
         | 
| 578 | 
            +
                  when '%s'                            # TZ,GL
         | 
| 579 | 
            +
                d = ajd - self.class.jd_to_ajd(self.class.civil_to_jd(1970,1,1), 0)
         | 
| 580 | 
            +
                s = (d * 86400).to_i
         | 
| 581 | 
            +
                o << '%d' % s
         | 
| 582 | 
            +
                  when '%T'; o << strftime('%H:%M:%S')            # P2,ID
         | 
| 583 | 
            +
                  when '%t'; o << "\t"                    # P2,ID
         | 
| 584 | 
            +
                  when '%U', '%W'
         | 
| 585 | 
            +
                a = self.class.civil_to_jd(year, 1, 1, ns?) + 6
         | 
| 586 | 
            +
                k = if c == '%U' then 0 else 1 end
         | 
| 587 | 
            +
                w = (jd - (a - ((a - k) + 1) % 7) + 7) / 7
         | 
| 588 | 
            +
                o << '%02d' % w
         | 
| 589 | 
            +
                  when '%u'; o <<   '%d' % cwday                # P2,ID
         | 
| 590 | 
            +
                  when '%V'; o << '%02d' % cweek                # P2,ID
         | 
| 591 | 
            +
                  when '%v'; o << strftime('%e-%b-%Y')            # AR,TZ
         | 
| 592 | 
            +
                  when '%w'; o <<   '%d' % wday
         | 
| 593 | 
            +
                  when '%X'; o << strftime('%H:%M:%S')
         | 
| 594 | 
            +
                  when '%x'; o << strftime('%m/%d/%y')
         | 
| 595 | 
            +
                  when '%Y'; o << '%.4d' %  year
         | 
| 596 | 
            +
                  when '%y'; o << '%02d' % (year % 100)
         | 
| 597 | 
            +
                  when '%Z'; o << (if offset.zero? then 'Z' else strftime('%z') end)
         | 
| 598 | 
            +
                  when '%z'                            # ID
         | 
| 599 | 
            +
                o << if offset < 0 then '-' else '+' end
         | 
| 600 | 
            +
                of = offset.abs
         | 
| 601 | 
            +
                hh, fr = of.divmod(1.to_r/24)
         | 
| 602 | 
            +
                mm = fr / (1.to_r/1440)
         | 
| 603 | 
            +
                o << '%02d' % hh
         | 
| 604 | 
            +
                o << '%02d' % mm
         | 
| 605 | 
            +
                  when '%%'; o << '%'
         | 
| 606 | 
            +
                  when '%+'; o << strftime('%a %b %e %H:%M:%S %Z %Y')    # TZ
         | 
| 607 | 
            +
            =begin
         | 
| 608 | 
            +
                  when '%.'
         | 
| 609 | 
            +
                o << '%06d' % (sec_fraction / (1.to_r/86400/(10**6)))
         | 
| 610 | 
            +
            =end
         | 
| 611 | 
            +
                  when '%1'; o <<   '%d' % jd
         | 
| 612 | 
            +
                  when '%2'; o << strftime('%Y-%j')
         | 
| 613 | 
            +
                  when '%3'; o << strftime('%Y-%m-%d')
         | 
| 614 | 
            +
                  else;      o << c
         | 
| 615 | 
            +
                  end
         | 
| 616 | 
            +
                end
         | 
| 617 | 
            +
                o
         | 
| 618 | 
            +
              end
         | 
| 619 | 
            +
             | 
| 620 | 
            +
            # alias_method :format, :strftime
         | 
| 621 | 
            +
             | 
| 622 | 
            +
              def asctime() strftime('%c') end
         | 
| 623 | 
            +
             | 
| 624 | 
            +
              alias_method :ctime, :asctime
         | 
| 625 | 
            +
             | 
| 626 | 
            +
            end
         | 
| 627 | 
            +
             | 
| 628 | 
            +
            class DateTime < Date
         | 
| 629 | 
            +
             | 
| 630 | 
            +
              def self._strptime(str, fmt='%FT%T%Z')
         | 
| 631 | 
            +
                super(str, fmt)
         | 
| 632 | 
            +
              end
         | 
| 633 | 
            +
             | 
| 634 | 
            +
              def strftime(fmt='%FT%T%Z')
         | 
| 635 | 
            +
                super(fmt)
         | 
| 636 | 
            +
              end
         | 
| 637 | 
            +
             | 
| 638 | 
            +
            end
         | 
| 639 | 
            +
             | 
| 640 | 
            +
            require 'generator'
         | 
| 641 | 
            +
            a = [2, 3, 5, 7, 11]
         | 
| 642 | 
            +
            b = %w#h a l l o#
         | 
| 643 | 
            +
            SyncEnumerator.new(a, b).each { |i, j|
         | 
| 644 | 
            +
              puts "#{i} & #{j}"
         | 
| 645 | 
            +
            }
         | 
| 646 | 
            +
             | 
| 647 | 
            +
            class Signature < Array
         | 
| 648 | 
            +
                def === x
         | 
| 649 | 
            +
                    x.kind_of? Array and zip(x).all? { |me, it| me === it }
         | 
| 650 | 
            +
                end
         | 
| 651 | 
            +
            end
         | 
| 652 | 
            +
             | 
| 653 | 
            +
            module Chess
         | 
| 654 | 
            +
             | 
| 655 | 
            +
                BOARD_RANGE = 1..8
         | 
| 656 | 
            +
               
         | 
| 657 | 
            +
                class Position
         | 
| 658 | 
            +
                   
         | 
| 659 | 
            +
                    attr_reader :x, :y
         | 
| 660 | 
            +
                   
         | 
| 661 | 
            +
                    def initialize *args
         | 
| 662 | 
            +
                        @x, @y = case args
         | 
| 663 | 
            +
                        when Signature[Fixnum, Fixnum]
         | 
| 664 | 
            +
                            args
         | 
| 665 | 
            +
                        when Signature[String]
         | 
| 666 | 
            +
                            Position.decode args.first
         | 
| 667 | 
            +
                        else
         | 
| 668 | 
            +
                            raise ArgumentError, 'wrong number of arguments(one String or two fixnums)'
         | 
| 669 | 
            +
                        end
         | 
| 670 | 
            +
                        raise RuntimeError, '%p is out of the chess board' % self unless Position.valid? @x, @y
         | 
| 671 | 
            +
                    end
         | 
| 672 | 
            +
               
         | 
| 673 | 
            +
                    def inspect
         | 
| 674 | 
            +
                        'Position(%p, %p)' % [x, y]
         | 
| 675 | 
            +
                    end
         | 
| 676 | 
            +
                   
         | 
| 677 | 
            +
                    def Position.decode pos
         | 
| 678 | 
            +
                        x, y = pos.split('')
         | 
| 679 | 
            +
                        return x.upcase[0] - ?A + 1, @y = y[0] - ?0
         | 
| 680 | 
            +
                    end
         | 
| 681 | 
            +
                   
         | 
| 682 | 
            +
                    def Position.valid? x, y
         | 
| 683 | 
            +
                        BOARD_RANGE.include? x and BOARD_RANGE.include? y
         | 
| 684 | 
            +
                    end
         | 
| 685 | 
            +
                end
         | 
| 686 | 
            +
               
         | 
| 687 | 
            +
            end
         | 
| 688 | 
            +
             | 
| 689 | 
            +
            p Chess::Position.new('H3')
         | 
| 690 | 
            +
            SuperString = Class.new String
         | 
| 691 | 
            +
            p Chess::Position.new(SuperString.new('C5'))
         | 
| 692 | 
            +
            p Chess::Position.new(3, 6)
         | 
| 693 | 
            +
            p Chess::Position.new(3, 9)
         | 
| 694 | 
            +
             | 
| 695 | 
            +
            require 'grammar'
         | 
| 696 | 
            +
             | 
| 697 | 
            +
            def test_grammars
         | 
| 698 | 
            +
                [<<EOG1, <<EOG2, <<EOG3,].map { |g| Grammar.new g }
         | 
| 699 | 
            +
            Z --> S
         | 
| 700 | 
            +
            S --> Sb
         | 
| 701 | 
            +
            S --> bAa
         | 
| 702 | 
            +
            A --> aSc
         | 
| 703 | 
            +
            A --> a
         | 
| 704 | 
            +
            A --> aSb
         | 
| 705 | 
            +
            EOG1
         | 
| 706 | 
            +
             | 
| 707 | 
            +
            C --> d
         | 
| 708 | 
            +
            C --> ABC
         | 
| 709 | 
            +
            B -->
         | 
| 710 | 
            +
            B --> c
         | 
| 711 | 
            +
            A --> B
         | 
| 712 | 
            +
            A --> a
         | 
| 713 | 
            +
            EOG2
         | 
| 714 | 
            +
             | 
| 715 | 
            +
            E - TD
         | 
| 716 | 
            +
            D - pTD
         | 
| 717 | 
            +
            D -
         | 
| 718 | 
            +
            T - FS
         | 
| 719 | 
            +
            S - uFS
         | 
| 720 | 
            +
            S -
         | 
| 721 | 
            +
            F - aEz
         | 
| 722 | 
            +
            F - i
         | 
| 723 | 
            +
            EOG3
         | 
| 724 | 
            +
            end
         | 
| 725 | 
            +
             | 
| 726 | 
            +
            $trace = false
         | 
| 727 | 
            +
            test_grammars.each_with_index do |g, i|
         | 
| 728 | 
            +
                puts "Grammar #{i} is #{'not ' if g.ll1?}LL(1)."
         | 
| 729 | 
            +
            end
         |