2 Module : Functional.Parser
3 Copyright : (c) Miguel Vilaça 2007
5 Maintainer : jmvilaca@di.uminho.pt
6 Stability : experimental
10 Small Functional Language: Parser
13 module Functional.Parser (parse) where
15 import Functional.Language
19 parse :: String -> Either FuncLang String
21 case filter (nul.snd) res of
22 [(term, _)] -> Left term
24 [] -> Right "Null result"
25 l -> Right $ "Ambiguous parsing.\n" ++ show l
26 where res = reads $ map f str
27 f c | isControl c = ' '
29 nul = all (\c -> isControl c || isSpace c)
31 instance Read FuncLang where
32 -- readsPrec :: Int -> String -> [(a, String)]
34 map (\(v,s) -> (Var v,s)) (readVar str) -- variables
35 ++ readParen (d > abst_prec) -- abstraction - allow [x,y]t
38 (vs,r3) <- readVars r2,
39 (t,r4) <- readsPrec (abst_prec+1) r3 ]) str
40 ++ readParen (d > app_prec)
41 (\r -> [(Appl t u, r2) |
42 (t,r1) <- readsPrec (app_prec+1) r,
43 (u,r2) <- readsPrec (app_prec+1) r1 ]) str
44 ++ readTerminal TT "tt" str
45 ++ readTerminal FF "ff" str
46 ++ readParen (d > iter_prec) -- iterbool
47 (\r -> [(IterBool v f b, r8) |
48 ("iterbool",r1) <- lex r,
50 (v,r3) <- readsPrec 0 r2,
52 (f,r5) <- readsPrec 0 r4,
54 (b,r7) <- readsPrec 0 r6,
55 (")",r8) <- lex r7]) str
56 ++ readTerminal Zero "0" str
57 ++ readParen (d > const_prec) -- suc
58 (\r -> [(Succ m, r4) |
61 (m,r3) <- readsPrec 0 r2,
62 (")",r4) <- lex r3]) str
63 ++ readParen (d > iter_prec) -- iternat
64 (\r -> [(IterNat x s z t, r8) |
65 ("iternat",r1) <- lex r,
67 (Abst x s,r3) <- readsPrec 0 r2,
69 (z,r5) <- readsPrec 0 r4,
71 (t,r7) <- readsPrec 0 r6,
72 (")",r8) <- lex r7]) str
73 ++ readTerminal Nil "nil" str
74 ++ readParen (d > const_prec) -- cons
75 (\r -> [(Cons a as, r6) |
76 ("cons(",r1) <- lex r,
78 (a,r3) <- readsPrec 0 r2,
80 (as,r5) <- readsPrec 0 r4,
81 (")",r6) <- lex r5]) str
82 ++ readParen (d > iter_prec) -- iterlist
83 (\r -> [(IterList x y c n l, r8) |
84 ("iterlist",r1) <- lex r,
86 (Abst x (Abst y c),r3) <- readsPrec 0 r2,
88 (n,r5) <- readsPrec 0 r4,
90 (l,r7) <- readsPrec 0 r6,
91 (")",r8) <- lex r7]) str
98 readTerminal term symb str =
99 readParen (d > terminal_prec)
101 (symb1,t) <- lex r, symb1 == symb]) str
105 (v,t) <- lex r, isVariable v]) str
107 [ (Abst v, r1) | (v,r) <- readVar str
111 | (v,r) <- readVar str
113 , (lv, r2) <- readVars r1]
115 reservedWords :: [String]
116 reservedWords = ["tt","ff","iterbool","0","suc","iternat","nil","cons","iterlist"]
118 isVariable :: String -> Bool
121 && str `notElem` reservedWords
122 && all isAlphaNum str
123 && not (isDigit $ head str)
128 str = " [x,y,z,a,b]("
129 ++ "(iterbool(x,y,tt) iterlist([x,y]y (x (a z)), (a z), nil) )"
130 ++ "(iternat([x]x,x,0) iterbool(y,y,tt)))"
132 term = Left $ Abst "x" $ Abst "y" $ Abst "z" $ Abst "a" $ Abst "b" $
134 (Appl (IterBool x y TT)
135 (IterList "x" "y" (Appl y $ Appl x $ Appl a z) (Appl a z) Nil)
137 (Appl (IterNat "x" x x Zero)