FixityResolution: resolve.hs

File resolve.hs, 1.4 KB (added by simonmar@…, 6 years ago)

sample code for resolving fixity

Line 
1data Op     = Op String Prec Fixity          deriving Eq
2data Fixity = Leftfix | Rightfix | Nonfix    deriving Eq
3data Exp    = Var Var | OpApp Exp Op Exp     deriving Eq
4type Prec   = Int
5type Var    = String
6
7data Tok = TVar Var | TOp Op
8
9parse :: [Tok] -> Exp
10parse (TVar x : rest) = fst (parse1 (Var x) (-1) Nonfix rest)
11
12parse1 :: Exp -> Int -> Fixity -> [Tok] -> (Exp, [Tok])
13parse1 e p f [] = (e, [])
14parse1 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
25instance 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
32plus   = TOp (Op "+" 6 Leftfix)
33times  = TOp (Op "*" 7 Leftfix)
34divide = TOp (Op "/" 7 Leftfix)
35gt     = TOp (Op ">" 4 Nonfix)
36ex     = TOp (Op "^" 8 Rightfix)
37
38lookupop '+' = plus
39lookupop '*' = times
40lookupop '/' = divide
41lookupop '>' = gt
42lookupop '^' = ex
43
44fromstr [x]     = [TVar [x]]
45fromstr (x:y:z) = TVar [x] : lookupop y : fromstr z
46
47test1 = fromstr "a+b+c"
48test2 = fromstr "a+b+c*d"
49test3 = fromstr "a/b/c"
50test4 = fromstr "a/b+c"
51test5 = fromstr "a/b*c"
52test6 = fromstr "1^2^3+4"
53test7 = fromstr "a/1^2^3"
54test8 = fromstr "a*b/c"