0N/ADescription : precedence checking
0N/ACopyright : Christian Maeder and Uni Bremen 2006
0N/AMaintainer : Christian.Maeder@dfki.de
0N/AStability : experimental
0N/APortability : portable
0N/A-- | a precedence map using numbers for faster lookup
0N/Adata PrecMap = PrecMap
1178N/AgetIdPrec p ps i = let PrecMap m mx = p in
1178N/A (if begPlace i || endPlace i then
4033N/AgetSimpleIdPrec :: PrecMap -> Id -> Int
4033N/A-- | drop as many elements as are in the first list
4033N/AdropPrefix :: [a] -> [b] -> [b]
1178N/AdropPrefix (_ : xs) (_ : ys) = dropPrefix xs ys
1178N/A-- | check if a left argument will be added.
0N/A-- (The 'Int' is the number of current arguments.)
0N/AisLeftArg :: Id -> [a] -> Bool
4033N/AisLeftArg op nArgs = null nArgs && begPlace op
1178N/A-- | check if a right argument will be added.
1178N/AisRightArg :: Id -> [a] -> Bool
4033N/AisRightArg op@(Id toks _ _) nArgs = endPlace op &&
1178N/A (isSingle $ dropPrefix nArgs $ filter isPlace toks)
0N/AjoinPlace :: AssocEither -> Id -> Bool
4033N/AjoinPlace side = case side of
4033N/AcheckArg :: AssocEither -> GlobalAnnos -> (Id, Int) -> (Id, Int) -> Id -> Bool
4033N/AcheckArg side ga (op, opPrec) (arg, argPrec) weight =
1178N/A junction = joinPlace side arg
4033N/A in if argPrec <= 0 then False
4033N/A else case compare argPrec opPrec of
1178N/A LT -> not junction && op /= applId
0N/A EQ -> if junction then
0N/A case precRel precs op weight of
0N/A case (isInfix arg, joinPlace side op) of
1178N/A (True, True) -> if arg == op
0N/A then not $ isAssoc side assocs op
0N/A (False, True) -> True
0N/A (True, False) -> False
0N/A-- | compute the left or right weight for the application
0N/AnextWeight :: AssocEither -> GlobalAnnos -> Id -> Id -> Id
0N/AnextWeight side ga arg op =
1178N/A case precRel (prec_annos ga) op arg of
-- | check precedence of an argument and a top-level operator.
checkPrec :: GlobalAnnos -> (Id, Int) -> (Id, Int) -> [a] ->
(AssocEither -> Id) -> Bool
checkPrec ga op@(o, _) arg args weight =
if isLeftArg o args then checkArg ARight ga op arg (weight ARight)
else if isRightArg o args then checkArg ALeft ga op arg (weight ALeft)