Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.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
用Haskell-Parsec解析算术表达式_Haskell_Parsec - Fatal编程技术网

用Haskell-Parsec解析算术表达式

用Haskell-Parsec解析算术表达式,haskell,parsec,Haskell,Parsec,我正在写一个算术解析器来处理像“1+2-3”这样的表达式。我用它作为参考。为了处理左关联性和优先级,我根据这个BNF(来自博客文章)用Parsec编写了一个解析器 我不明白为什么会出现这种结果输入意外结束请考虑解析1+2。在parseExp中,将1解析为t1=Const 1,然后进入循环循环(Const 1)。循环尝试第一个可选的termSuffix(Const 1),它成功地解析了运算符+,下一个术语t2=Const 2,然后循环回termSuffix(Binary Plus(Const 1)

我正在写一个算术解析器来处理像“1+2-3”这样的表达式。我用它作为参考。为了处理左关联性和优先级,我根据这个BNF(来自博客文章)用Parsec编写了一个解析器


我不明白为什么会出现这种结果
输入意外结束

请考虑解析
1+2
。在
parseExp
中,将
1
解析为
t1=Const 1
,然后进入循环
循环(Const 1)
。循环尝试第一个可选的
termSuffix(Const 1)
,它成功地解析了运算符
+
,下一个术语
t2=Const 2
,然后循环回
termSuffix(Binary Plus(Const 1)(Const 2))
,它需要一个
+
-
。解析失败。不要循环回
termSuffix
,而应该循环回
loop
,以允许在第一个
+
之后有一个术语:

parseExp :: Parser Exp
parseExp = do
  t1 <- parseTerm
  loop t1
  where termSuffix t1 = do
          op <- lexeme $ oneOf "+-"
          t2 <- parseTerm
          case op of
            -- *** use `loop` here, not `termSuffix` ***
            '+' -> loop (Binary Plus t1 t2)
            '-' -> loop (Binary Minus t1 t2)
        loop t = termSuffix t <|> return t
parseExp::Parser Exp
parseExp=do

t1由于您使用的是
parsec
,因此您可能对该模块感兴趣。
*Main CodeGen Parser> parseWithEof parseExp "-2"
Right (Unary ArithNeg (Const 2))
*Main CodeGen Parser> parseWithEof parseExp "(2)"
Right (Const 2)
*Main CodeGen Parser> parseWithEof parseExp "-!(((2)))"
Right (Unary ArithNeg (Unary LogNeg (Const 2)))
*Main CodeGen Parser> parseWithEof parseExp "1+2"
Left (line 1, column 4):
unexpected end of input
expecting digit
*Main CodeGen Parser> parseWithEof parseExp "1+2+3"
Left (line 1, column 6):
unexpected end of input
expecting digit
*Main CodeGen Parser> parseWithEof parseExp "1+2*3"
Left (line 1, column 6):
unexpected end of input
expecting digit
parseExp :: Parser Exp
parseExp = do
  t1 <- parseTerm
  loop t1
  where termSuffix t1 = do
          op <- lexeme $ oneOf "+-"
          t2 <- parseTerm
          case op of
            -- *** use `loop` here, not `termSuffix` ***
            '+' -> loop (Binary Plus t1 t2)
            '-' -> loop (Binary Minus t1 t2)
        loop t = termSuffix t <|> return t