@@ -298,36 +298,36 @@ Translate the rules from string to name-based.
298
298
> rules2 <- mapM transRule rules1
299
299
300
300
> let
301
- > type_env = [(nt, t) | (nt, _, Just (t,[] )) <- rules] ++
302
- > [(nt, getTokenType dirs) | nt <- terminal_strs] -- XXX: Doesn't handle $$ type!
303
- >
304
- > fixType (ty,s) = go " " ty
305
- > where go acc [] = return (reverse acc)
306
- > go acc (c: r) | isLower c = -- look for a run of alphanumerics starting with a lower case letter
307
- > let (cs,r1) = span isAlphaNum r
308
- > go1 x = go (reverse x ++ acc) r1
309
- > in case lookup (c: cs) s of
310
- > Nothing -> go1 (c: cs) -- no binding found
311
- > Just a -> case lookup a type_env of
312
- > Nothing -> do
313
- > addErr (" Parameterized rule argument '" ++ a ++ " ' does not have type" )
314
- > go1 (c: cs)
315
- > Just t -> go1 $ " (" ++ t ++ " )"
316
- > | otherwise = go (c: acc) r
317
- >
318
- > convType (nm, t)
319
- > = do t' <- fixType t
320
- > return (nm, t')
301
+ > -- tys :: Array Int (M (Maybe (String -> String)))
302
+ > tys = accumArray (\ _ x -> x) (return Nothing ) (0 , last_t) $
303
+ > [ (nm, liftM Just $ fixType ty env) | (nm,_,Just (ty, env)) <- rules1 ] ++
304
+ > [ (nm, return . Just . str . getTokenType $ dirs) | nm <- terminal_names ] -- XXX: Doesn't handle $$ in token
321
305
>
306
+ > -- fixType :: String -> Subst -> M (String -> String)
307
+ > fixType ty env = go ty id
308
+ > where
309
+ > isIdent c = isAlphaNum c || c == ' _'
310
+ > go [] s = return s
311
+ > go r@ (c: _) s | isLower c = -- an identifier starting with a lower case letter
312
+ > let (cs,r1) = span isIdent r
313
+ > in case lookup cs env of -- try to map formal to actual
314
+ > Nothing -> -- no formal found
315
+ > go r1 $ s . str cs -- do not expand
316
+ > Just a -> do -- found actual
317
+ > nm <- mapToName a
318
+ > ty' <- tys ! nm
319
+ > go r1 $ s . brack' (fromMaybe (str cs) ty')
320
+ > | isIdent c = -- an identifier not starting with a lower case letter
321
+ > let (cs,r1) = span isIdent r
322
+ > in go r1 $ s . str cs -- do not expand
323
+ > | otherwise = -- not an identifier
324
+ > let (cs,r1) = break isIdent r
325
+ > in go r1 $ s . str cs -- do not expand
322
326
> -- in
323
- > tys <- mapM convType [ (nm, t) | (nm, _, Just t) <- rules1 ]
324
- >
325
327
326
- > let
327
- > type_array :: Array Int (Maybe String )
328
- > type_array = accumArray (\ _ x -> x) Nothing (first_nt, last_nt)
329
- > [ (nm, Just t) | (nm, t) <- tys ]
328
+ > type_array <- mapM ((fmap . fmap ) ($ " " )) tys
330
329
330
+ > let
331
331
> env_array :: Array Int String
332
332
> env_array = array (errorTok, last_t) name_env
333
333
> -- in
0 commit comments