Parsing Parsec:在斜杠之间解析表达式

Parsing Parsec:在斜杠之间解析表达式,parsing,haskell,expression-trees,parsec,parser-combinators,Parsing,Haskell,Expression Trees,Parsec,Parser Combinators,我试图在斜杠之间解析简单的表达式。示例:/1+2*3/应计算为7 我在试这个 module Test where import Text.Parsec import Text.Parsec.Language (emptyDef) import Text.Parsec.Combinator (between) import Text.Parsec.String (Parser) import qualified Text.Parsec.Expr as Ex import qualified T

我试图在斜杠之间解析简单的表达式。示例:
/1+2*3/
应计算为
7

我在试这个

module Test where

import Text.Parsec
import Text.Parsec.Language (emptyDef)
import Text.Parsec.Combinator (between)
import Text.Parsec.String (Parser)

import qualified Text.Parsec.Expr as Ex
import qualified Text.Parsec.Token as Tok

lexer :: Tok.TokenParser ()
lexer = Tok.makeTokenParser style
  where
    ops = ["+","*","-","/",";"]
    names = ["def","extern"]
    style = emptyDef {
               Tok.commentLine = "#"
             , Tok.reservedOpNames = ops
             , Tok.reservedNames = names
             }

integer :: Parser Int
integer = fromIntegral <$> Tok.integer lexer

parens :: Parser a -> Parser a
parens = Tok.parens lexer

braces :: Parser a -> Parser a
braces = Tok.braces lexer

slashes :: Parser a -> Parser a
slashes = between (reserved "/") (reserved "/")

reserved :: String -> Parser ()
reserved = Tok.reserved lexer

reservedOp :: String -> Parser ()
reservedOp = Tok.reservedOp lexer

binary s f assoc = Ex.Infix (reservedOp s >> return f) assoc
table = [[binary "*" (*) Ex.AssocLeft,
          binary "/" div Ex.AssocLeft]
        ,[binary "+" (+) Ex.AssocLeft,
          binary "-" (-) Ex.AssocLeft]]

factor :: Parser Int
factor = try integer
      <|> parens expr

expr :: Parser Int
expr = Ex.buildExpressionParser table factor

programInSlashes :: Parser Int
programInSlashes = slashes expr

programInBraces :: Parser Int
programInBraces = braces expr
但是,
programInSlashes
会失败:

*Test> parse programInSlashes "" "/ 1+2*3/4 /"
Left (line 1, column 12):
unexpected end of input
expecting end of "/", integer or "("
显然,问题在于
/
既是一个运算符,也是程序本身的分隔符。但是由于语言没有歧义,我们应该能够解析它,不?

我想你可以用它来解析内部表达式;然后可以为
/
案例嵌入回溯,例如:

Infix (try $ do { reserved "/"; notFollowedBy eof; return div }) AssocLeft

您还可以在单独的过程中解析外部语言和内部表达式。我已经在一个带有自定义运算符的语言的编译器中完成了这项工作:首先解析程序而不涉及中缀表达式,然后根据作用域中的运算符运行另一个过程来解析中缀表达式。

抱歉,现在只需要尝试一下。不幸的是,我无法让它工作,仍然在左边说
parse programInSlashes”“/1+2*3/4/”(第1行,第10列):意外的“4”应该是“/”
Infix (try $ do { reserved "/"; notFollowedBy eof; return div }) AssocLeft