Skip to content

Commit ece4987

Browse files
committed
Type signatures for nested parameterized rules
1 parent 5594b94 commit ece4987

File tree

1 file changed

+26
-26
lines changed

1 file changed

+26
-26
lines changed

src/Grammar.lhs

+26-26
Original file line numberDiff line numberDiff line change
@@ -298,36 +298,36 @@ Translate the rules from string to name-based.
298298
> rules2 <- mapM transRule rules1
299299

300300
> 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
321305
>
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
322326
> -- in
323-
> tys <- mapM convType [ (nm, t) | (nm, _, Just t) <- rules1 ]
324-
>
325327

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
330329

330+
> let
331331
> env_array :: Array Int String
332332
> env_array = array (errorTok, last_t) name_env
333333
> -- in

0 commit comments

Comments
 (0)