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 Text.ParserCombinators.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