Earley.hs revision f1ef1c750f805c1732b01001f2b157c0077b808e
d9a45a35cd696085be1a038b2cc67bee6819c574cmaederModule : $Header$
8a77240a809197c92c0736c431b4b88947a7bac1Christian MaederDescription : generic mixfix analysis, using an Earley parser
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian MaederCopyright : Christian Maeder and Uni Bremen 2003-2005
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskiLicense : similar to LGPL, see HetCATS/LICENSE.txt or LIZENZ.txt
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskiMaintainer : Christian.Maeder@dfki.de
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu ProdescuStability : experimental
2eeec5240b424984e3ee26296da1eeab6c6d739eChristian MaederPortability : portable
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskiGeneric mixfix analysis, using an Earley parser
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederThe grammer has a single non-terminal for terms (the double
0095c7efbddd0ffeed6aaf8ec015346be161d819Till Mossakowskiunderscore). A rule of the grammer carries an identifier, a precedence
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian Maedernumber, and the actual token list of the identifier to match against
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowskithe input token list..
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederThe parser can be instantiated for any term type. A
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maederfunction parameter determines how applications from identifiers and
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroederarguments are constructed.
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , partitionRules
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski -- * special tokens for special ids
d3c9318c22fcf44d9135a3b2c64f880b9a785babChristian Maeder , getTokenPlaceList
d9a45a35cd696085be1a038b2cc67bee6819c574cmaeder , getPlainPolyTokenList
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , getPolyTokenList
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski -- * resolution chart
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder , getResolved
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maederimport qualified Data.Map as Map
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder-- | take the difference of the two input lists take (length l2 - length l1) l2
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskitakeDiff :: [a] -> [b] -> [b]
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskitakeDiff l1 l2 = zipWith const l2 $ dropPrefix l1 l2
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski-- | update token positions.
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski-- return remaining positions
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedersetToksPos :: [Token] -> Range -> ([Token], Range)
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedersetToksPos (h:ts) (Range (p:ps)) =
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder let (rt, rp) = setToksPos ts (Range ps)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder in (h {tokPos = Range [p]} : rt, rp)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroedersetToksPos ts ps = (ts, ps)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederreverseRange :: Range -> Range
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederreverseRange = Range . reverse . rangeToList
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder-- | update positions in 'Id'.
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski-- return remaining positions
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskisetPlainIdePos :: Id -> Range -> (Id, Range)
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskisetPlainIdePos (Id ts cs _) ps =
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder if null cs then
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder let (newTs, restPs) = setToksPos ts ps
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder in (Id newTs cs nullRange, restPs)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder else let (toks, pls) = splitMixToken ts
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski (front, ps2) = setToksPos toks ps
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski ps2PL = rangeToList ps2
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder (newCs, ps3, ps4) =
adea2e45fa61f1097aadc490a0aeaf4831b729ccChristian Maeder if isNullRange ps2 then error "setPlainIdePos2"
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder else foldl ( \ (prevCs, seps, restPs) a ->
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski let (c1, qs) = setPlainIdePos a restPs
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski qsPL = rangeToList qs
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski in if isNullRange qs then error "setPlainIdePos1"
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder else (c1: prevCs,
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski Range (head qsPL : rangeToList seps),
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder Range (tail qsPL)))
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder ([], Range [head ps2PL], Range (tail ps2PL)) cs
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder (newPls, ps7) = setToksPos pls ps4
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder in (Id (front ++ newPls) (reverse newCs) (reverseRange ps3), ps7)
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski-- no special index type anymore (assuming not much more development)
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski-- the info Int denotes fast precedence
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowskidata Item a = Item
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski { rule :: Id -- the rule to match
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , info :: Int -- additional precedence info for 'rule'
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder , lWeight :: Id -- weights for lower precedence pre- and postfixes
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , rWeight :: Id -- given by the 'Id's itself
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , posList :: Range -- positions of Id tokens
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder , args :: [a] -- currently collected arguments
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski -- both in reverse order
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , ambigArgs :: [[a]] -- field for ambiguities
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , ambigs :: [[a]] -- field for ambiguities
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , rest :: [Token] -- part of the rule after the "dot"
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski , index :: Int -- index into the Table/input string
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu-- | the non-terminal
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskitermStr :: String
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskitermStr = "(__)"
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder-- | builtin terminals
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedercommaTok, termTok, oParenTok, cParenTok :: Token
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskicommaTok = mkSimpleId "," -- for list elements
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskitermTok = mkSimpleId termStr
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskioParenTok = mkSimpleId "("
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaedercParenTok = mkSimpleId ")"
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskilistTok :: Token
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskilistTok = mkSimpleId "[]" -- impossible token
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederprotectTok :: Token
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskiprotectTok = mkSimpleId "()" -- impossible token
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski-- | token for a fixed (or recursively resolved) operator expression
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskiexprTok :: Token
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederexprTok = mkSimpleId "(op )"
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder-- | token for a fixed (or recursively resolved) argument expression
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskivarTok :: Token
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till MossakowskivarTok = mkSimpleId "(var )"
df11e5eab86d8247f58e301d8f0a2c6ecf4c9541Till Mossakowski-- | parenthesis around one place
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederparenId = mkId [oParenTok, placeTok, cParenTok]
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder-- | id for tuples with at least two arguments
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedertupleId = mkId [oParenTok, placeTok, commaTok, placeTok, cParenTok]
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder-- | id for the emtpy tuple
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederunitId = mkId [oParenTok, cParenTok]
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder-- | see 'exprTok'
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederexprId = mkId [exprTok]
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder-- | see 'varTok'
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroedervarId = mkId [varTok]
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederlistId :: (Id, Id) -> Id
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederlistId (f,c) = Id [listTok] [f,c] nullRange
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederisListId :: Id -> Bool
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroederisListId (Id ts _ _) = not (null ts) && head ts == listTok
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder-- | interpret placeholders as literal places
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroederprotect :: Id -> Id
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroederprotect i = Id [protectTok] [i] nullRange
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaederunProtect :: Id -> Maybe Id
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederunProtect (Id ts cs _) = case cs of
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder [i] -> case ts of
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder [tok] | tok == protectTok -> Just i
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder-- | get the token list for a mixfix rule
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedergetPolyTokenList :: Id -> [Token]
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedergetPolyTokenList = getGenPolyTokenList termStr
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder-- | get the plain token list for prefix applications
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedergetPlainPolyTokenList :: Id -> [Token]
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedergetPlainPolyTokenList = getGenPolyTokenList place
a65c6747c9acbbebc93baba7bae94d2e3d8cdafbTill Mossakowskitype Rule = (Id, Int, [Token])
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedermkItem :: Int -> Rule -> Item a
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian MaedermkItem ind (ide, inf, toks) =
d9a45a35cd696085be1a038b2cc67bee6819c574cmaeder Item { rule = ide
d9a45a35cd696085be1a038b2cc67bee6819c574cmaeder , info = inf
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder , lWeight = ide
d9a45a35cd696085be1a038b2cc67bee6819c574cmaeder , rWeight = ide
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder , posList = nullRange
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder , ambigArgs = []
d9a45a35cd696085be1a038b2cc67bee6819c574cmaeder , ambigs = []
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus Luettich , rest = toks
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder , index = ind }
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder-- | extract tokens with the non-terminal for places
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroedergetTokenPlaceList :: Id -> [Token]
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von SchroedergetTokenPlaceList = getTokenList termStr
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder-- | construct a rule for a mixfix
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedermixRule :: Int -> Id -> Rule
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedermixRule b i = (i, b, getTokenPlaceList i)
e7d2b3903c7b44db432538b0d720c21062c24823Christian MaederasListAppl :: ToExpr a -> Id -> [a] -> Range -> a
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederasListAppl toExpr i ra br =
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if isListId i then
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder let Id _ [f, c] _ = i
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder mkList [] ps = toExpr c [] ps
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder mkList (hd:tl) ps = toExpr f [hd, mkList tl ps] ps
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder in mkList ra br
e8eb2b9d68adc3024eb1aa9899b902ed5a3fb460Christian Maeder else if i == typeId
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder || i == exprId
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder || i == parenId
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder || i == varId
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder then case ra of
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder _ -> error "asListAppl"
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder else toExpr i ra br
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder-- | construct the list rules
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus LuettichlistRules :: Int -> GlobalAnnos -> [Rule]
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederlistRules inf g =
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder let lists = list_lit $ literal_annos g
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder listRule co toks = (listId co, inf, toks)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder in concatMap ( \ (bs, (n, c)) ->
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder let (b1, b2, cs) = getListBrackets bs
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder e = Id (b1 ++ b2) cs nullRange in
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder (if e == n then [] -- add b1 ++ b2 if its not yet included by n
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder else [listRule (c, n) $ getPlainTokenList e])
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder ++ [listRule (c, n) (b1 ++ [termTok] ++ b2),
a7be28e157e9ceeec73a8fd0e642c36ea29d4218Christian Maeder listRule (c, n) (b1 ++ [termTok, commaTok, termTok] ++ b2)]
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maedertype Table a = Map.Map Int [Item a]
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederlookUp :: Table a -> Int -> [Item a]
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederlookUp ce k = Map.findWithDefault [] k ce
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder-- | recognize next token (possible introduce new tuple variable)
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaederscanItem :: (a -> a -> a) -> (a, Token) -> Item a -> [Item a]
8c7aa750542dcadb94b971be712564a9a8f1d189Christian MaederscanItem addType (trm, t)
8c7aa750542dcadb94b971be712564a9a8f1d189Christian Maeder p@Item{ rest = ts, args = pArgs, posList = pRange } =
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder let q = p { posList = appRange (tokPos t) pRange }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder in case ts of
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder hd : tt -> let r = q { rest = tt } in
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if hd == t || t == exprTok && hd == varTok then
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder if t == commaTok then
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder sd : _ | sd == termTok ->
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu -- tuple or list elements separator
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescu [ r, q { rest = termTok : ts } ]
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder else if elem t [exprTok, varTok, typeInstTok] then
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder [r { args = trm : pArgs }]
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder else if t == typeTok then
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder case (tt, pArgs) of
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder ([], [arg]) -> [q { rest = [], args = [addType trm arg] }]
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder _ -> error "scanItem: typeTok"
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maederscan :: (a -> a -> a) -> (a, Token) -> [Item a] -> [Item a]
a98fd29a06e80e447af26d898044c23497adbc73Mihai Codescuscan f term = concatMap (scanItem f term)
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedermkAmbigs :: ToExpr a -> Item a -> [a]
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedermkAmbigs toExpr p@Item{ args = l, ambigArgs = aArgs } =
e7d2b3903c7b44db432538b0d720c21062c24823Christian Maeder map ( \ aas -> fst $
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder mkExpr toExpr
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder p { args = takeDiff aas l ++ aas
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian MaederaddArg :: GlobalAnnos -> ToExpr a -> Item a -> Item a -> Item a
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian MaederaddArg ga toExpr argItem@Item { ambigs = ams } p@Item{ args = pArgs,
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder rule = op, posList = pRange, ambigs = pAmbs, rest = pRest} =
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder let (arg, ps) = mkExpr toExpr argItem
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder newAms = mkAmbigs toExpr argItem
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder q = case pRest of
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder p { rest = tl
c911a0ec80ca4a178399c68f1e28be4e2bf42fceChristian Maeder , posList = ps `appRange` pRange
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder , args = arg : pArgs
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder , ambigs = (if null newAms then ams else newAms : ams)
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder _ -> error "addArg"
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder in if isLeftArg op pArgs then
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder q { lWeight = getNewWeight ALeft ga argItem op }
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder else if isRightArg op pArgs then
4ef5e33657aae95850b7e6941f67ac1fb73cd13fChristian Maeder q { rWeight = getNewWeight ARight ga argItem op }
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder-- | shortcut for a function that constructs an expression
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maedertype ToExpr a = Id -> [a] -> Range -> a
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedermkExpr :: ToExpr a -> Item a -> (a, Range)
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedermkExpr toExpr Item { rule = orig, posList = ps, args = iArgs } =
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder let rs = reverseRange ps
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder (ide, qs) = if isListId orig then (orig, rs) else
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder setPlainIdePos (maybe orig id $ unProtect orig) rs
e8eb2b9d68adc3024eb1aa9899b902ed5a3fb460Christian Maeder in (asListAppl toExpr ide (reverse iArgs) qs, rs)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maederreduce :: GlobalAnnos -> Table a -> ToExpr a -> Item a -> [Item a]
e8eb2b9d68adc3024eb1aa9899b902ed5a3fb460Christian Maederreduce ga table toExpr itm =
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder map (addArg ga toExpr itm)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder $ filter (checkPrecs ga itm)
09b431a868c79a92ae7c9bd141565f43f9034144Christian Maeder $ lookUp table $ index itm
09b431a868c79a92ae7c9bd141565f43f9034144Christian MaedergetWeight :: AssocEither -> Item a -> Id
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus LuettichgetWeight side = case side of
cd6e5706893519bfcf24539afa252fcbed5097ddKlaus Luettich ALeft -> lWeight
c40a1fdc8ec6978bd27240d6780d0e0a7b6b0056Dominik Luecke ARight -> rWeight
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaedergetNewWeight :: AssocEither -> GlobalAnnos -> Item a -> Id -> Id
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaedergetNewWeight side ga argItem = nextWeight side ga $ getWeight side argItem
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder-- | check precedences of an argument and a top-level operator.
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaedercheckPrecs :: GlobalAnnos -> Item a -> Item a -> Bool
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaedercheckPrecs ga argItem@Item { rule = arg, info = argPrec }
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder Item { rule = op, info = opPrec, args = oArgs } =
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder checkPrec ga (op, opPrec) (arg, argPrec) oArgs $ flip getWeight argItem
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaederreduceCompleted :: GlobalAnnos -> Table a -> ToExpr a -> [Item a] -> [Item a]
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaederreduceCompleted ga table toExpr =
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder foldr mergeItems [] . map (reduce ga table toExpr) .
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder filter (null . rest)
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaederrecReduce :: GlobalAnnos -> Table a -> ToExpr a -> [Item a] -> [Item a]
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaederrecReduce ga table toExpr items =
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder let reduced = reduceCompleted ga table toExpr items
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder in if null reduced then items
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder else recReduce ga table toExpr reduced `mergeItems` items
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maedercomplete :: ToExpr a -> GlobalAnnos -> Table a -> [Item a] -> [Item a]
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maedercomplete toExpr ga table items =
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder let reducedItems = recReduce ga table toExpr $
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder reduceCompleted ga table toExpr items
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder in reducedItems ++ items
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaederdoPredict :: [Item a] -> ([Item a], [Item a])
556f473448dfcceee22afaa89ed7a364489cdbbbChristian MaederdoPredict items = partition ( \ Item{ rest = ts } ->
556f473448dfcceee22afaa89ed7a364489cdbbbChristian Maeder not (null ts) && head ts == termTok) items
else Map.insert idx (map (mkItem idx) cRules ++ cItems)
Chart { prevTable = Map.empty