Haskell 向表达式解析器添加中缀运算符

Haskell 向表达式解析器添加中缀运算符,haskell,parsec,Haskell,Parsec,我正在尝试将中缀运算符的解析器添加到简单表达式解析器中。我已经看过了,但我似乎遗漏了什么 import qualified Text.Parsec.Expr as Expr import qualified Text.Parsec.Token as Tokens import Text.ParserCombinators.Parsec import Text.Parsec data Expr = Number Integer | Op Expr Expr

我正在尝试将中缀运算符的解析器添加到简单表达式解析器中。我已经看过了,但我似乎遗漏了什么

import qualified Text.Parsec.Expr as Expr
import qualified Text.Parsec.Token as Tokens
import Text.ParserCombinators.Parsec
import Text.Parsec

data Expr = Number Integer
          | Op Expr Expr
          | Boolean Bool
      
instance Show Expr where
  show (Op l r) = "(+ " ++ (show l) ++ " " ++ (show r) ++ ")"
  show (Number r) = show r
  show (Boolean b) = show b

parens = Tokens.parens haskell
reserved = Tokens.reservedOp haskell

infix_ operator func =
  Expr.Infix (spaces >> reserved operator >> spaces >> return func) Expr.AssocLeft

infixOp =
  Expr.buildExpressionParser table parser
  where
    table = [[infix_ "+" Op]]

number :: Parser Expr
number = 
  do num <- many1 digit
     return $ Number $ read num

bool :: Parser Expr
bool = (string "true" >> return (Boolean True)) <|> (string "false" >> return (Boolean False))

parser = parens infixOp <|> number <|> bool

run = Text.Parsec.runParser parser () ""
将限定的Text.Parsec.Expr导入为Expr
将限定的Text.Parsec.Token作为标记导入
导入Text.ParserCombinators.Parsec
导入文本.Parsec
数据表达式=整数
|运算表达式
|布尔布尔布尔
实例Show Expr where
show(Op l r)=“(+”+++(show l)++”+”+(show r)++””
显示(数字r)=显示r
显示(布尔b)=显示b
parens=代币。parens haskell
reserved=Tokens.reservedOp haskell
中缀算子func=
Expr.Infix(空格>>保留运算符>>空格>>返回函数)Expr.AssocLeft
infixOp=
Expr.buildExpressionParser表解析器
哪里
表=[[infix_加号“+”Op]]
number::Parser Expr
数字=
do num>return(布尔真)(字符串“false”>>return(布尔假))
parser=parens infixOp数bool
run=Text.Parsec.runParser()“”
此解析器能够解析表达式,如
1
false
(1+2)
(1+false)
,但不能解析
1+2
(解析为
1
)。如果我试图将解析器更改为
parens infixOp infixOp number bool
,它就会卡住


要解析像
1+2
这样没有括号的表达式,我应该更改什么?

您必须在顶层运行
infixOp
解析器,如下所示:

run=Text.Parsec.runParser infixOp()“”

否则,只能在括号中出现时解析中缀表达式

使用
parens infixOp infixOp number bool
的尝试很可能会被卡住,因为它循环:
parser
尝试使用
infixOp
进行解析,它尝试使用
parse
进行解析,以此类推

这些教程可能会帮助您开始使用parsec(他们为我做了):


在这种情况下,“卡住”是什么意思?@FyodorSoikin递归没有基本情况。