Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/9.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parsing 如何在Haskell中用Parsec隐式乘法解析表达式_Parsing_Haskell_Parsec - Fatal编程技术网

Parsing 如何在Haskell中用Parsec隐式乘法解析表达式

Parsing 如何在Haskell中用Parsec隐式乘法解析表达式,parsing,haskell,parsec,Parsing,Haskell,Parsec,我有一个允许隐式乘法的语法,(1+2)(3+4)与(1+2)*(3+4)或(1+2)7与(1+2)*7 如何在Haskell中实现这一点?以下是我到目前为止的情况: import Control.Monad import Text.ParserCombinators.Parsec import Text.ParserCombinators.Parsec.Expr import Text.ParserCombinators.Parsec.Language import qualified Text

我有一个允许隐式乘法的语法,
(1+2)(3+4)
(1+2)*(3+4)
(1+2)7
(1+2)*7
如何在Haskell中实现这一点?以下是我到目前为止的情况:

import Control.Monad
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
import Text.ParserCombinators.Parsec.Language
import qualified Text.ParserCombinators.Parsec.Token as Token

languageDef =
  emptyDef { Token.identStart      = letter
           , Token.identLetter     = alphaNum
           , Token.reservedOpNames = ["+", "*"]
           }

lexer = Token.makeTokenParser languageDef

reservedOp = Token.reservedOp lexer
parens     = Token.parens     lexer
integer    = Token.integer    lexer

data Expr = Const Int
          | Binary BinOp Expr Expr
            deriving (Show)

data BinOp = Add | Multiply
             deriving (Show)

expression = buildExpressionParser operators term

operators = [ [Infix  (reservedOp "*"   >> return (Binary Multiply)) AssocLeft]
            , [Infix  (reservedOp "+"   >> return (Binary Add     )) AssocLeft]
            ]

term =   liftM (Const . fromIntegral) integer
     <|> parens expression
     <|> (do e1 <- expression
             e2 <- term
             return $ Binary Multiply e1 e2)

parseString str =
  case parse expression "" str of
    Left e  -> error $ show e
    Right r -> r
import-Control.Monad
导入Text.ParserCombinators.Parsec
导入Text.ParserCombinators.Parsec.Expr
导入Text.ParserCombinators.Parsec.Language
导入限定的Text.ParserCombinators.Parsec.Token作为令牌
语言定义=
emptyDef{Token.identStart=字母
,Token.identLetter=alphaNum
,Token.reservedOpNames=[“+”,“*”]
}
lexer=Token.makeTokenParser languageDef
reservedOp=Token.reservedOp lexer
parens=令牌。parens lexer
integer=Token.integer lexer
数据表达式=常数Int
|二进制二进制二进制表达式
派生(显示)
数据BinOp=加|乘
派生(显示)
expression=buildExpressionParser运算符术语
运算符=[[Infix(reservedOp“*”>>返回(二进制乘法))AssocLeft]
,[Infix(reservedOp“+”>>返回(二进制添加))AssocLeft]
]
term=liftM(常量fromIntegral)整数
帕伦斯表达式
(不知道)

但它不起作用,我在解析时出错,当我尝试解析
((1+5)8)
时,我遇到了
意外的“8”期望运算符或“

,除非你对
makeTokenParser
背后的机制有一个很好的理由,否则这似乎有点过头了。通常,当您有一种与现有语言非常相似的语言,或者您有许多不同级别的运算符优先级时,这非常有用。在您的情况下,您可以在几行中编写
表达式

import Text.Parsec.String (Parser) 
import Text.Parsec
import Control.Applicative (some)

-- ...

expression :: Parser Expr
expression = sum
  where
    product = foldl1 (Binary Multiply) <$> factor `sepBy1` optional (char '*')
    sum     = foldl1 (Binary Add)      <$> product `sepBy1` char '+'
    factor  = int <|> between (char '(') (char ')') expression
    int     = Const . read <$> some digit

 -- ...

您能确保您的示例中包含所有导入吗?如果我们必须弄清楚您导入的所有内容,那就有点麻烦了…@Alec我已经添加了所有缺少的部分,以便代码能够编译和工作。您是否尝试将运算符定义从
reservedOp“*”
更改为
reservedOp“*”空格
?@BenjaminHodgson这导致了无限递归。我想我需要改变一下术语,但我不明白你是怎么想出解决办法的?我遇到了一个类似的问题。谢谢,它工作得很好,但实际上我需要其他运算符和运算符优先级,还有二进制的
-
/
^
,我删除了它们以缩短示例代码,这实际上是我使用
BinOp
类型的原因
ghci> parseString "1+2*3"
Binary Add (Const 1) (Binary Multiply (Const 2) (Const 3))
ghci> parseString "(1+2)(3+4)"
Binary Multiply (Binary Add (Const 1) (Const 2)) (Binary Add (Const 3) (Const 4))
ghci> parseString "(1+2)*(3+4)"
Binary Multiply (Binary Add (Const 1) (Const 2)) (Binary Add (Const 3) (Const 4))
ghci> parseString "(1+2)7"
Binary Multiply (Binary Add (Const 1) (Const 2)) (Const 7)
ghci> parseString "(1+2)*7"
Binary Multiply (Binary Add (Const 1) (Const 2)) (Const 7)