1 -- Copyright (c) 2000 Galois Connections, Inc.
2 -- All rights reserved. This software is distributed as
3 -- free software under the license in the file "LICENSE",
4 -- which is included in the distribution.
9 import Parsec hiding (token)
14 program :: Parser Code
22 tokenList :: Parser Code
23 tokenList = many token <?> "list of tokens"
25 token :: Parser GMLToken
27 do { ts <- braces tokenList ; return (TBody ts) }
28 <|> do { ts <- brackets tokenList ; return (TArray ts) }
29 <|> (do { s <- gmlString ; return (TString s) } <?> "string")
30 <|> (do { t <- pident False ; return t } <?> "identifier")
31 <|> (do { char '/' -- No whitespace after slash
32 ; t <- pident True ; return t } <?> "binding identifier")
33 <|> (do { n <- number ; return n } <?> "number")
35 pident :: Bool -> Parser GMLToken
38 ; case (lookup id opTable) of
39 Nothing -> if rebind then return (TBind id) else return (TId id)
40 Just t -> if rebind then error ("Attempted rebinding of identifier " ++ id) else return t
43 ident :: Parser String
46 ; ls <- many (satisfy (\x -> isAlphaNum x || x == '-' || x == '_'))
50 gmlString :: Parser String
51 gmlString = lexeme $ between (char '"') (char '"') (many (satisfy (\x -> isPrint x && x /= '"')))
54 -- Hugs breaks on big exponents (> ~40)
55 test_number = "1234 -1234 1 -0 0" ++
56 " 1234.5678 -1234.5678 1234.5678e12 1234.5678e-12 -1234.5678e-12" ++
57 " -1234.5678e12 -1234.5678E-12 -1234.5678E12" ++
58 " 1234e11 1234E33 -1234e33 1234e-33" ++
59 " 123e 123.4e 123ee 123.4ee 123E 123.4E 123EE 123.4EE"
63 number :: Parser GMLToken
69 ; e <- option "" exponent'
70 ; return (TReal (read (s ++ n ++ "." ++ m ++ e))) -- FIXME: Handle error conditions
72 <|> do { e <- exponent'
73 ; return (TReal (read (s ++ n ++ ".0" ++ e)))
75 <|> do { return (TInt (read (s ++ n))) }
78 exponent' :: Parser String
88 optSign :: Parser String
89 optSign = option "" (string "-")
92 ------------------------------------------------------
93 -- Library for tokenizing.
95 braces p = between (symbol "{") (symbol "}") p
96 brackets p = between (symbol "[") (symbol "]") p
98 symbol name = lexeme (string name)
100 lexeme p = do{ x <- p; whiteSpace; return x }
102 whiteSpace = skipMany (simpleSpace <|> oneLineComment <?> "")
103 where simpleSpace = skipMany1 (oneOf " \t\n\r\v")
106 ; skipMany (noneOf "\n\r\v")
111 ------------------------------------------------------------------------------
113 rayParse :: String -> Code
114 rayParse is = case (parse program "<stdin>" is) of
115 Left err -> error (show err)
118 rayParseF :: String -> IO Code
120 do { r <- parseFromFile program file
122 Left err -> error (show err)
126 run :: String -> IO ()
127 run is = case (parse program "" is) of
128 Left err -> print err
133 do { r <- parseFromFile program "simple.gml"
135 Left err -> print err