LoginSignup
2
2

More than 5 years have passed since last update.

ifconfigをParsecする

Last updated at Posted at 2012-06-17

System.Info.MAC.Fetchの実装がMacのifconfigを読んでくれないのでちょっとParsecの勉強ついでに調べてみる。

ifconfigの内容をparsecでパースする。Parserの中でparse関数を読んでいるのは筋が悪い気がするし、こういう分野は正規表現が得意な気がする。

最初に各NICのセクションを分けて、それぞれの中をさらにパースして結果とする。

parse_ifconfig.hs
before :: Parser a -> Parser Bool
before p = try (lookAhead p *> return True) <|> (eof *> return False) <|>(anyChar *> before p)


nicSection :: Parser (String, Maybe MAC)
nicSection = do
  name <- many1 alphaNum
  r <- manyTill anyChar (try $ lookAhead $ (void (char '\n' *> alphaNum)) <|> eof)
  let mac = case (parse macAddr "macaddr parse" r) of
        Left _ -> Nothing
        Right mac -> mac
      ret = (name, mac)
  (char '\n' *> return ret) <|> return ret
  -- Skip next char if it's '\n'. However, the below doesn't work
  -- try $ char '\n'
  -- return ret


nicSections :: Parser [(String, Maybe MAC)]
nicSections = many1 nicSection


macAddr :: Parser (Maybe MAC)
macAddr = do
  found <- before markers
  if found
    then do
      markers
      spaces
      parseMAC ':' >>= return
    else return Nothing
 where
  markers = choice $ map (try . string) [ "ether", "HWaddr" ]


parseNICs' :: Parser [(String, MAC)]
parseNICs' = (foldr macAddrOnOnly []) <$> nicSections
  where
    macAddrOnOnly (_, Nothing) p = p
    macAddrOnOnly (n, Just x) p = (n, x) : p


main:: IO ()
main=do
  let u = parse parseNICs' "ifconfig mac" mac
  putStrLn $ show u

nicSectionの最後の行あたりはもっといい方法がありそうな気がする。「もし今読んでいるところが'\n'なら一文字読む」ということがやりたい。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2