1

スラッシュの間の単純な式を解析しようとしています。例:/ 1+2*3 /は、7と評価する必要があります。しかしParsec:スラッシュ間の式の解析

*Test> parse programInBraces "" "{ 1+2*3/4 }" 
Right 2 

programInSlashes失敗しない:

私は、これはprogramInBraces大丈夫働く

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 

をしようとしていた

*Test> parse programInSlashes "" "/ 1+2*3/4 /" 
Left (line 1, column 12): 
unexpected end of input 
expecting end of "/", integer or "(" 

明らかに問題が/が両方あるということです演算子とプログラム自体の区切り文字です。しかし、言語があいまいではないので、それを解析できるはずはありませんか?

答えて

2

私はText.Parsec.Exprを使って内部表現を解析できると思います。あなたは、たとえば、/ケースのためにバックトラックを埋め込むことができます。

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

また、外部の言語と別のパスで内部式を解析することができます。私はカスタム演算子を持つ言語のコンパイラでこれをやっています。まず、中置式に触れることなくプログラムを解析し、範囲内の演算子に従って中置式を解析する別のパスを実行します。

+0

申し訳ありませんが、今すぐ試してみてください。私は残念なことに、残念なことに、 'parse programInSlashes" "/ 1 + 2 * 3/4 /"と言っています。 左(行1、列10): 予期しない '4' "/" ' –