博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
高阶的Parser:可变运算优先级
阅读量:5840 次
发布时间:2019-06-18

本文共 7862 字,大约阅读时间需要 26 分钟。

如果需要更flex的运算优先级可咋整?

怕是要把这个标注运算优先级的Optable当做参数,一级一级的传下去了。。。

 

module ParserImpl whereimport ASTimport Text.ParserCombinators.ReadP as Pimport Data.Charimport Control.Applicative-- do not change the type!parseStringTerm :: OpTable -> String -> Either ErrMsg TermparseStringTerm table str = let flist = tabterms table []                                fstTerm = head flist                                 term = pTerm fstTerm                                result = parsefTerms term str                            in resultparseStringCmds :: OpTable -> String -> Either ErrMsg [Cmd]parseStringCmds table str = let flist = tabterms table []                                term = head flist                                cmds = pCmds (pTerm term)                                result = parsefCmds cmds str                            in result-- start parser --opCollect :: [FName] ->  ReadP (Term -> Term -> Term)opCollect [fname] = do        _ <- symbol fname        return (\expr1 expr2 -> TFun fname [expr1,expr2])opCollect (fname:flist) = let         a = opCollect [fname]        b = opCollect flist        in (a +++ b)tabterms :: OpTable -> [ReadP Term] -> [ReadP Term]tabterms (OpTable [(fix,flist)]) topTerm =    let fOterm = opCollect flist    in case fix of        FRight -> case topTerm of                   [] -> let a = (chainr1 basicTerm fOterm)                             b = pbasicTerm a                             c = (chainr1 b fOterm)                             d = pbasicTerm c                         in [d]                   [tt] -> let a = (chainr1 tt fOterm)                               b = pbasicTerm a                               c = (chainr1 b fOterm)                               d = pbasicTerm c                           in [d]        _ -> case topTerm of                   [] -> let a = (chainl1 basicTerm fOterm)                             b = pbasicTerm a                             c = (chainl1 b fOterm)                             d = pbasicTerm c                         in [d]                   [tt] -> let a = (chainl1 tt fOterm)                               b = pbasicTerm a                               c = (chainl1 b fOterm)                               d = pbasicTerm c                           in [d]                           tabterms (OpTable ((fix,fnlist) : flist)) topTerm =    case topTerm of        [] -> let fOterm = opCollect fnlist                  alist = (tabterms (OpTable flist) [])                  atop = head alist                  blist = (tabterms (OpTable flist) [pbasicTerm atop])                  btop = pTerm (head blist)                  ct = pTerm (chainr1 btop fOterm)              in case fix of                  FRight -> [pTerm (chainr1 ct fOterm)] ++ blist                  _ -> [pTerm (chainl1 ct fOterm)] ++ blist        [tt] -> let fOterm = opCollect fnlist                    alist = (tabterms (OpTable flist) [tt])                    atop = pTerm (head alist)                in case fix of                    FRight -> [pTerm (chainr1 atop fOterm)] ++ alist                    _ -> [pTerm (chainl1 atop fOterm)] ++ alistparsefTerms :: ReadP Term -> String -> Either ErrMsg TermparsefTerms fterm str =    case null (readP_to_S fterm str) of        True -> Left (show (readP_to_S fterm str))        False -> case [x | x <- readP_to_S fterm str,snd x == ""] of                   [] -> Left (show (readP_to_S fterm str))                   legalstr -> Right (fst (head legalstr))parsefCmds :: ReadP [Cmd] -> String -> Either ErrMsg [Cmd]parsefCmds cmds str =    case null (readP_to_S cmds str) of        True -> Left (show (readP_to_S cmds str))        False -> case [x | x <- readP_to_S cmds str,snd x == ""] of                   [] -> Left (show (readP_to_S cmds str))                   legalstr -> Right (fst (head legalstr))symbol :: String -> ReadP Stringsymbol s = token $ string stoken :: ReadP a -> ReadP atoken p = do             skipSpaces             a <- p             skipSpaces             return apVName :: ReadP TermpVName = do    fist <- satisfy isLetter    send <- munch (\x -> isLetter x || isDigit x)    return (TVar (fist : send))pFName :: ReadP FNamepFName = do    fist <- satisfy isLetter    send <- munch (\x -> isLetter x || isDigit x)    return (fist : send)pPName :: ReadP PNamepPName = do    fist <- satisfy isLetter    send <- munch (\x -> isLetter x || isDigit x)    return (fist : send)pNumber :: ReadP TermpNumber = do    sym <- option ' ' (char '~')    number <- munch1 isDigit    case sym of        '~' -> return (TNum (read ('-' : number)))        _ -> return(TNum (read number))pFun :: ReadP Term -> ReadP TermpFun term = (do    fname <- token pFName    _ <- symbol "("    terms <- token (pTerms term)    _ <- symbol ")"    return (TFun fname terms))    <|> (do    fname <- token pFName    _ <- symbol "("    _ <- symbol ")"    return (TFun fname []))pbasicTerm :: ReadP Term -> ReadP TermpbasicTerm term = (do                _ <- symbol "("                a <- token term                _ <- symbol ")"                return a) <|> (pFun term) <|> term <|> basicTermpTerm :: ReadP Term -> ReadP TermpTerm term = (do                _ <- symbol "("                a <- token term                _ <- symbol ")"                return a) <|> (pFun term) <|> termbasicTerm :: ReadP TermbasicTerm = token pNumber        <|> token pVNamepTerms :: ReadP Term -> ReadP [Term]pTerms term = (pCommaTerm term)          <|> (do           a <- token term           return [a])pCommaTerm :: ReadP Term -> ReadP [Term]pCommaTerm term = do    a <- token term    com <- token (pComTerHelper term)    return (a : com)pComTerHelper :: ReadP Term -> ReadP [Term]pComTerHelper term = (do    _ <- symbol ","    pCommaTerm term) <|>                     (do    _ <- symbol ","    a <- token term    return [a])pCond :: ReadP Term -> ReadP CondpCond term = (do -- one termz empty    name <- token pPName    _ <- symbol "("    _ <- symbol ")"    return (Cond name [] []))    <|> (do      -- one termz not empty    name <- token pPName    _ <- symbol "("    terms <- token (pTerms term)    _ <- symbol ")"    return (Cond name terms []))    <|> (do      -- two termz(empty) and terms    name <- token pPName    _ <- symbol "("    _ <- symbol ";"    terms <- token (pTerms term)    _ <- symbol ")"        return (Cond name [] terms))    <|> (do      -- two termz(not empty) and terms    name <- token pPName    _ <- symbol "("    term1 <- token (pTerms term)    _ <- symbol ";"    term2 <- token (pTerms term)    _ <- symbol ")"    return (Cond name term1 term2))pConds :: ReadP Term -> ReadP [Cond]pConds term = (pCommaConds term)          <|> (do          a <- token (pCond term)          return [a])pCommaConds :: ReadP Term -> ReadP [Cond]pCommaConds term = do    a <- token (pCond term)    com <- token (pComConHelper term)    return (a : com)pComConHelper :: ReadP Term -> ReadP [Cond]pComConHelper term = (do    _ <- symbol ","    pCommaConds term) <|>                     (do    _ <- symbol ","    a <- token (pCond term)    return [a])pRule :: ReadP Term -> ReadP RulepRule term = (do    term1 <- token term    _ <- symbol "="    term2 <- token term    _ <- symbol "."    return (Rule term1 term2 []))    <|> (do    term1 <- token term    _ <- symbol "="    term2 <- token term    _ <- symbol "|"    cons <- token (pConds term)    _ <- symbol "."    return (Rule term1 term2 cons))pCmd :: ReadP Term -> ReadP CmdpCmd term = (do    rule <- token (pRule term)    return (CRule rule))    <|> (do    t <- token term    _ <- symbol "?"    return (CQuery t False))    <|> (do    t <- token term    _ <- symbol "??"    return (CQuery t True))pCmds :: ReadP Term -> ReadP [Cmd]pCmds term = (do    a <- token (pCmd term)    as <- token (pCmds term)    return (a : as))    <|> (do    a <- token (pCmd term)    return [a])

  

转载于:https://www.cnblogs.com/hanani/p/9981216.html

你可能感兴趣的文章
Hadoop序列化
查看>>
类的加载、连接、初始化
查看>>
Windows10放开Administrator权限
查看>>
硬盘分区
查看>>
在这里安家了!
查看>>
虚拟机开机提示:This virtual machine appears to be in use
查看>>
新生代大小对GC的影响
查看>>
Bootstrap框架
查看>>
深入理解jvm jdk1,7(19)
查看>>
DP(递归打印路径) UVA 662 Fast Food
查看>>
Docker commit 命令保存的镜像文件太大的问题
查看>>
航院 6213 Chinese Zodiac
查看>>
关于Spring中的<context:annotation-config/>配置作用
查看>>
47.使用 RequireJS 加载 AngularJS
查看>>
2.mybatis实战教程(mybatis in action)之二:以接口的方式编程
查看>>
Window setInterval() 方法
查看>>
SqlServer2012 数据库的同步之SQL JOB + 建立链接服务器
查看>>
Hibernate查询(Query Language)
查看>>
Revit API创建标注NewTag
查看>>
【15】vuex2.0 之 modules
查看>>