FixityResolution: resolve.hs

File resolve.hs, 1.4 kB (added by simonmar@microsoft.com, 2 years ago)

sample code for resolving fixity

Line 
1 data Op     = Op String Prec Fixity          deriving Eq
2 data Fixity = Leftfix | Rightfix | Nonfix    deriving Eq
3 data Exp    = Var Var | OpApp Exp Op Exp     deriving Eq
4 type Prec   = Int
5 type Var    = String
6
7 data Tok = TVar Var | TOp Op
8
9 parse :: [Tok] -> Exp
10 parse (TVar x : rest) = fst (parse1 (Var x) (-1) Nonfix rest)
11
12 parse1 :: Exp -> Int -> Fixity -> [Tok] -> (Exp, [Tok])
13 parse1 e p f [] = (e, [])
14 parse1 e p f inp@(TOp op@(Op _ p' f') : TVar x : rest)
15   | p' == p && (f /= f' || f == Nonfix)
16   = error "ambiguous infix expression"
17   | p' < p  ||  p' == p && (f == Leftfix || f' == Nonfix)
18   = (e, inp)
19   | otherwise
20   = let (r,rest') = parse1 (Var x) p' f' rest in
21     parse1 (OpApp e op r) p f rest'
22
23 -- Printing
24
25 instance Show Exp where
26   showsPrec _ (Var x) = showString x
27   showsPrec p e@(OpApp l (Op op _ _) r) =
28         showParen (p > 0) $ showsPrec 9 l . showString op . showsPrec 9 r
29
30 -- Testing
31
32 plus   = TOp (Op "+" 6 Leftfix)
33 times  = TOp (Op "*" 7 Leftfix)
34 divide = TOp (Op "/" 7 Leftfix)
35 gt     = TOp (Op ">" 4 Nonfix)
36 ex     = TOp (Op "^" 8 Rightfix)
37
38 lookupop '+' = plus
39 lookupop '*' = times
40 lookupop '/' = divide
41 lookupop '>' = gt
42 lookupop '^' = ex
43
44 fromstr [x]     = [TVar [x]]
45 fromstr (x:y:z) = TVar [x] : lookupop y : fromstr z
46
47 test1 = fromstr "a+b+c"
48 test2 = fromstr "a+b+c*d"
49 test3 = fromstr "a/b/c"
50 test4 = fromstr "a/b+c"
51 test5 = fromstr "a/b*c"
52 test6 = fromstr "1^2^3+4"
53 test7 = fromstr "a/1^2^3"
54 test8 = fromstr "a*b/c"