首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用buildExpressionParser时挂起Parsec

使用buildExpressionParser时挂起Parsec
EN

Stack Overflow用户
提问于 2014-08-12 11:09:39
回答 1查看 213关注 0票数 2

我正在尝试使用Parsec为数学方程创建一个基本的解析器,而且我在使用buildExpressionParser函数时遇到了一些困难。

我已经创建了一个parsecParse函数,但是当我在ghci:parse parsecParse "" "200*6"中调用它时,它就会永远挂起。我搞不懂为什么。有什么想法吗?

代码语言:javascript
复制
module Equation where

import Control.Applicative hiding (many, (<|>))

import Text.Parsec.Char (char, digit)
import Text.Parsec.Combinator (many1, option)
import Text.Parsec.Expr (Assoc (..), Operator (..), buildExpressionParser)
import Text.Parsec.Prim ((<|>), try)
import Text.Parsec.String (Parser)

data Equation = Leaf Double | Tree Op Equation Equation deriving (Show)
data Op = Plus | Minus | Multiply | Divide deriving (Show)

parsecParse :: Parser Equation
parsecParse = try parseOperator <|> parseDouble

parseDouble :: Parser Equation
parseDouble = fmap (Leaf . read) $ (++) <$> integer <*> fraction
    where integer  = many1 digit
          fraction = option "" $ (:) <$> char '.' <*> many1 digit

parseOperator :: Parser Equation
parseOperator = buildExpressionParser table parsecParse
    where table     = [[ getOp '*' Multiply, getOp '/' Divide ],
                       [ getOp '+' Plus,     getOp '-' Minus ]]
          getOp c o = Infix (char c >> return (Tree o)) AssocLeft
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-08-12 11:20:13

您会遇到问题,因为parseOperator在最左边的位置上递归,Parsec无法直接处理,并且会产生无限的递归。

buildExpressionParser的最后一个参数应该是解析更多“基本”元素的解析器。

parseOperator上间接地递归是很好的,例如处理带括号的元素,但不能使它最终位于它自己最左边的位置。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/25262766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档