字句解析

まんま

module Main where

import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Expr
import Text.ParserCombinators.Parsec.Token( TokenParser, makeTokenParser, reservedOpNames )
import qualified Text.ParserCombinators.Parsec.Token as P
import Text.ParserCombinators.Parsec.Language( haskellStyle, haskellDef )

lexer :: TokenParser ()
lexer  = makeTokenParser 
         (haskellDef
         { reservedOpNames = ["*","/","+","-"]
         })

whiteSpace = P.whiteSpace lexer
lexeme     = P.lexeme lexer
symbol     = P.symbol lexer
natural    = P.natural lexer
parens     = P.parens lexer
semi       = P.semi lexer
identifier = P.identifier lexer
reserved   = P.reserved lexer
reservedOp = P.reservedOp lexer

expr    :: Parser Integer
expr    = buildExpressionParser table factor
        <?> "expression"

table   = [[op "*" (*) AssocLeft, op "/" div AssocLeft]
          ,[op "+" (+) AssocLeft, op "-" (-) AssocLeft]
          ]          
        where
          op s f assoc
             = Infix (do{ reservedOp s; return f} <?> "operator") assoc

factor  =   parens expr
        <|> natural
        <?> "simple expression"

run :: Show a => Parser a -> String -> IO ()
run p input
        = case (parse p "" input) of
            Left err -> do{ putStr "parse error at "
                          ; print err
                          }
            Right x  -> print x

runLex :: Show a => Parser a -> String -> IO ()
runLex p input
        = run (do{ whiteSpace
                 ; x <- p
                 ; eof
                 ; return x
                 }) input

で、

*Main> runLex expr "1 + 2"
3
*Main> runLex expr "1 + {- comment -} 2 * 3 --multiply has higher priority"
7
*Main> runLex expr "  0xAA / 0o37 / 2"
2
*Main> runLex expr "0xAA / 0o37 2 "
parse error at (line 1, column 13):
unexpected "2"
expecting operator or end of input
  • lexer の閉じ括弧が抜けていた
  • import も色々不足