zoukankan      html  css  js  c++  java
  • Haskell语言学习笔记(41)Parsec(1)

    Parsec

    Parsec是一个词法及语法分析器。

    匹配字符与字符串

    Prelude Text.Parsec> parseTest anyChar "a"
    'a'
    Prelude Text.Parsec> parseTest (char 'a') "a"
    'a'
    Prelude Text.Parsec> parseTest (satisfy (=='a')) "a"
    'a'
    Prelude Text.Parsec> parseTest (oneOf "abc") "a"
    'a'
    Prelude Text.Parsec> parseTest (string "a") "a"
    "a"
    
    • anyChar 匹配任意字符
    • char c 匹配特定字符 c
    • satisfy p 匹配谓词 p
    • oneOf s 匹配字符串 s 中的任意字符
    • string s 匹配特定字符串 s

    匹配0次,1次或多次

    Prelude Text.Parsec> parseTest (many digit) "3"
    "3"
    Prelude Text.Parsec> parseTest (many digit) ""
    ""
    Prelude Text.Parsec> parseTest (many1 digit) ""
    parse error at (line 1, column 1):
    unexpected end of input
    expecting digit
    Prelude Text.Parsec> parseTest (many1 digit) "3"
    "3"
    Prelude Text.Parsec> parseTest (many1 digit) "34"
    "34"
    Prelude Text.Parsec> parseTest (many digit) "34"
    "34"
    
    • many 匹配0次1次或多次
    • many1 匹配1次或多次
    • digit 匹配数字

    在 Parser Monad 中改变返回值类型

    Prelude Text.Parsec Text.Parsec.String> num = do{ n <- many1 digit; return $ read n } :: Parser Integer
    Prelude Text.Parsec Text.Parsec.String> parseTest num "123"
    123
    

    忽略空白

    Prelude Text.Parsec Text.Parsec.String> whitespace = Control.Monad.void $ many $ oneOf " 
    	" :: Parser ()
    Prelude Text.Parsec Text.Parsec.String> parseTest (whitespace >> anyChar) "  a"
    'a'
    Prelude Text.Parsec Text.Parsec.String> lexeme = (p -> whitespace >> p) :: Parser a -> Parser a
    Prelude Text.Parsec Text.Parsec.String> parseTest (lexeme anyChar) "  a"
    'a'
    

    sequence 和 choice

    Prelude Text.Parsec Text.Parsec.String> parseTest (sequence [anyChar, anyChar]) "ab"
    "ab"
    Prelude Text.Parsec Text.Parsec.String> parseTest (anyChar >>  anyChar) "ab"
    'b'
    Prelude Text.Parsec Text.Parsec.String> parseTest (choice [anyChar, digit]) "a"
    'a'
    Prelude Text.Parsec Text.Parsec.String> parseTest (choice [anyChar, digit]) "3"
    '3'
    Prelude Text.Parsec Text.Parsec.String> parseTest (anyChar <|> digit) "a"
    'a'
    Prelude Text.Parsec Text.Parsec.String> parseTest (anyChar <|> digit) "3"
    '3'
    
    • sequence 匹配并且,与 (>>) 操作符有所不同。
    • choice 匹配或者,也可用 (<|>) 操作符

    使用 try 来回溯

    Prelude Text.Parsec Text.Parsec.String> parseTest (sequence [char 'a', char 'b'] <|> sequence [char 'a', char 'c']) "ac"
    parse error at (line 1, column 2):
    unexpected "c"
    expecting "b"
    Prelude Text.Parsec Text.Parsec.String> parseTest (try (sequence [char 'a', char 'b']) <|> sequence [char 'a', char 'c']) "ac"
    "ac"
    Prelude Text.Parsec Text.Parsec.String> parseTest (string "ab" <|> string "ac") "ac"
    parse error at (line 1, column 1):
    unexpected "c"
    expecting "ab"
    Prelude Text.Parsec Text.Parsec.String> parseTest (try (string "ab") <|> string "ac") "ac"
    "ac"
    
    • 当 choice 的成员parser由多个parser组成时,该成员的某一部分parser成功某一部分parser失败将会导致该成员匹配失败,从而失去匹配其他成员parser的机会。
    • 此时应该使用 try 来强制回溯。

    参考链接

    Intro to Parsing with Parsec in Haskell

  • 相关阅读:
    log4net使用封装,无缝切换 dotnet 和 dotnetcore
    使用 certbot 申请泛域名https证书
    StackExchange.Redis中文使用文档
    在 asp.net core 中使用类似 Application 的服务
    不一样的 SQL Server 日期格式化
    你可能不知道的 docker 命令的奇淫怪巧
    [k8s]dashboard1.8.1搭建( heapster1.5+influxdb+grafana)
    [k8s]k8s 1.9(on the fly搭建) 1.9_cni-flannel部署排错 ipvs模式
    [k8s] kubelet单组件启动静态pod
    [svc]runinit管理多进程
  • 原文地址:https://www.cnblogs.com/zwvista/p/7841428.html
Copyright © 2011-2022 走看看