gdritter repos apicius / master
Experimenting with better errors Getty Ritter 8 years ago
2 changed file(s) with 33 addition(s) and 7 deletion(s). Collapse all Expand all
3737 \$ $idchar + { lex (TkJoin . T.strip) }
3838
3939 {
40 data Token = Token AlexPosn TkType deriving (Eq, Show)
40 data Token = Token
41 { tkPosn :: AlexPosn
42 , tkType :: TkType
43 } deriving (Eq, Show)
4144
4245 data TkType
4346 = TkLCurl
5558 deriving (Eq, Show)
5659
5760 data AlexUserState = AlexUserState
58 { filePath :: FilePath
61 { filePath :: FilePath
62 , lastToken :: Maybe Token
63 , thisToken :: Maybe Token
5964 } deriving (Eq, Show)
6065
6166 alexInitUserState :: AlexUserState
62 alexInitUserState = AlexUserState "<unknown>"
67 alexInitUserState = AlexUserState "<unknown>" Nothing Nothing
6368
6469 getFilePath :: Alex FilePath
6570 getFilePath = liftM filePath alexGetUserState
6671
6772 setFilePath :: FilePath -> Alex ()
68 setFilePath = alexSetUserState . AlexUserState
73 setFilePath f = do
74 userState <- alexGetUserState
75 alexSetUserState userState { filePath = f }
76
77 getLastToken :: Alex (Maybe Token)
78 getLastToken = liftM lastToken alexGetUserState
79
80 setLastToken :: Token -> Alex ()
81 setLastToken t = do
82 userState <- alexGetUserState
83 alexSetUserState userState
84 { lastToken = thisToken userState
85 , thisToken = Just t
86 }
6987
7088 alexMonadScan' :: Alex Token
7189 alexMonadScan' = do
8098 alexMonadScan'
8199 AlexToken inp' len action -> do
82100 alexSetInput inp'
83 action (ignorePendingBytes inp) len
101 tok <- action (ignorePendingBytes inp) len
102 setLastToken tok
103 return tok
84104
85105 alexError' :: AlexPosn -> String -> Alex a
86106 alexError' (AlexPn _ l c) msg = do
7676 lexwrap = (alexMonadScan' >>=)
7777
7878 happyError :: Token -> Alex a
79 happyError (Token p t) =
80 alexError' p ("parse error at token " ++ show t)
79 happyError (Token pos this) = do
80 last <- getLastToken
81 let msg = case (fmap tkType last, this) of
82 (Just TkArrow, TkArrow) ->
83 "Missing a step description in between arrows."
84 (_, TkSemi) -> "Unexpected semicolon"
85 (_, _) -> "parse error at token " ++ show this
86 alexError' pos msg
8187
8288 parseFile :: FilePath -> String -> Either String [Recipe]
8389 parseFile = runAlex' parse