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