あどけない話

Internet technologies

正規表現を超える


Audrey  Haskell 


 Parsec 使15 Perl6 
 

15Haskell  Parsec  Perl  Haskell 

Perl  Perl Perl  Perl (Parsec)

例題


IPv4 


192.168.0.1
 

0  255 /


[192,168,0,1]
 

/4

用語


()

数字の解析 (Perl)


IPv4  0255 

 Perl 0  255 Perl 
sub digit_byte {
    local ($_) = shift;
    unless (/(\d+)/) {
        die 'Illegal IPv4';
    }
    die 'Illegal IPv4' if (split(//,$1))[0] eq '0';
    die 'Illegal IPv4' if $1 > 255;
    return $1;
}



Perl 

数字の解析 (Parsec)


Parsec 

 Parsec  digit 使 nDigit 
nDigit :: Parser Int
nDigit = doc<- digit
            return $ digitToInt c

digit nDigit  digitToInt 使

digit nDigit digit Parsec 

Parsec Parsec  Haskell ()

nDigit 0  255 
digitByte :: Parser Int
digitByte = dons<- many1 nDigit
               when (head ns == 0) (unexpected "Illegal number")
               return $ nsToInt ns

Parsec  many1 使nsnsToInt 
nsToInt :: [Int] -> Int
nsToInt ns = foldl (\x y -> x * 10 + y) 0 ns

IPv4アドレスの解析 (Perl)


IPv4 


sub ipv4 {
    local ($_) = shift;
    unless (/(\d+)\.(\d+)\.(\d+)\.(\d+)/) {
        die "Illegal IPv4";
    }
    die 'Illegal IPv4' if (split(//,$1))[0] eq '0' ||
                          (split(//,$2))[0] eq '0' ||
                          (split(//,$3))[0] eq '0' ||
                          (split(//,$4))[0] eq '0';
    die "Illegal IPv4" if $1 > 255 || $2 > 255 || $3 > 255 || $4 > 255;
    return [$1,$2,$3,$4];
}

IPv4アドレスの解析 (Parsec)


Parsec  IPv4 Parsec  sepBy1 使digitByte 
ipv4 :: Parser [Int]
ipv4 = do ns <- sepBy1 digitByte (char '.')
          check ns
          return ns
    where
      test n = when (n > 255) (unexpected "IPv4 should be 0-255")
      check ns = do when (length ns /= 4) (unexpected "IPv4 should be 4 bytes")
                    mapM_ test ns

IPv4アドレスへの完全マッチ (Perl)


Perl  ipv4  IPv4 

Web  IPv4 ipv4 Perl ipv4 
sub exactIPv4 {
    local ($_) = shift;
    unless (/^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
        die "Illegal IPv4";
    }
    die 'Illegal IPv4' if (split(//,$1))[0] eq '0' ||
                          (split(//,$2))[0] eq '0' ||
                          (split(//,$3))[0] eq '0' ||
                          (split(//,$4))[0] eq '0';
    die "Illegal IPv4" if $1 > 255 || $2 > 255 || $3 > 255 || $4 > 255;
    return [$1,$2,$3,$4];
}

IPv4アドレスへの完全マッチ (Parsec)


Persec  /^pattern/ 

 IPv4 (/pattern/)ipv4 
inFixIPv4 :: Parser [Int]
inFixIPv4 = try ipv4 <|> do anyChar; inFixIPv4

 ipv4 try anyChar 

使inFix 
inFix :: Parser a -> Parser a
inFix p = try p <|> do anyChar; inFix p

inFixIPv4 :: Parser [Int]
inFixIPv4 = inFix ipv4

Haskell 使

使 Haskell 



 IPv4 (/^pattern$/)
suffix :: Parser a -> Parser a
suffix p = dox<- p
              eof
              return x

exactIPv4 :: Parser [Int]
exactIPv4 = suffix ipv4

(/pattern$/) IPv4 
suffixIPv4 :: Parser [Int]
suffixIPv4 = suffix inFixIPv4

正規表現は異分子




 Parsec 5(nDigit,digitByte,ipv4,inFix,suffix) inFixIPv4exactIPv4suffixIPv4 

Perl Perl Perl Perl 

Perl  DNA ( DNA )

Parsec  Haskell Haskell  Parsec  RFC/Internet-Draft  BNF 2(many )

高い次元へ


 Parsec Parsec 

Parsec 

Parsec /

使

使x使y

Parsec