3
我想分析與同$
(如$a=$b
)開頭的變量表達式開頭的變量,使用秒差距的令牌和Expr的模塊。這裏是我的代碼的簡化版本:
module Main where
import Control.Monad.Identity
import Control.Applicative
import Text.Parsec
import Text.Parsec.String
import qualified Text.Parsec.Token as Tok
import qualified Text.Parsec.Language as Tok
import qualified Text.Parsec.Expr as Ex
data Expr
= BinaryOp String Expr Expr
| Var String
deriving (Show)
lexer :: Tok.TokenParser()
lexer = Tok.makeTokenParser style
where
style = Tok.emptyDef
{ Tok.reservedOpNames = ["="]
, Tok.reservedNames = []
, Tok.identStart = letter
, Tok.identLetter = alphaNum
}
reservedOp = Tok.reservedOp lexer
identifier = Tok.identifier lexer
whiteSpace = Tok.whiteSpace lexer
parseExpr :: String -> Either ParseError Expr
parseExpr = parse (whiteSpace *> expr <* eof) ""
expr :: Parser Expr
expr = Ex.buildExpressionParser opTable terms <?> "expression"
where
opTable =
[ [ Ex.Infix (reservedOp "=" >> return (BinaryOp "=")) Ex.AssocLeft ] ]
terms =
try var
var :: Parser Expr
var = Var <$> (char '$' >> identifier)
--
main :: IO()
main = case parseExpr "$a=$b" of
Left err -> print err
Right expr -> print expr
這工作得很好用空白圍繞運營商的表達式(如$a = $b
),但沒有空格($a=$b
)我得到的錯誤:
(line 1, column 5):
unexpected '$'
expecting operator
而且,如果我修改解析器以解析不以$
開頭的變量,則解析器可以使用和不使用空格。因此,$
與運算符之間沒有空白的組合似乎存在問題。
真棒,謝謝! – dermoritz