1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
------------------------------------------------------------------------------ --- Library for converting ground terms to strings and vice versa. --- --- @author Michael Hanus --- @version April 2005 ------------------------------------------------------------------------------ module ReadShowTerm(showTerm,showQTerm,readQTerm,readsQTerm, readsUnqualifiedTerm,readUnqualifiedTerm,readsTerm,readTerm, readQTermFile,readQTermListFile, writeQTermFile,writeQTermListFile) where import Data.Char(isSpace) --- Transforms a ground(!) term into a string representation --- in standard prefix notation. --- Thus, showTerm suspends until its argument is ground. --- This function is similar to the prelude function <code>show</code> --- but can read the string back with <code>readUnqualifiedTerm</code> --- (provided that the constructor names are unique without the module --- qualifier). showTerm :: _ -> String showTerm x = prim_showTerm $## x prim_showTerm :: _ -> String prim_showTerm external --- Transforms a ground(!) term into a string representation --- in standard prefix notation. --- Thus, showTerm suspends until its argument is ground. --- Note that this function differs from the prelude function <code>show</code> --- since it prefixes constructors with their module name --- in order to read them back with <code>readQTerm</code>. showQTerm :: _ -> String showQTerm x = prim_showQTerm $## x prim_showQTerm :: _ -> String prim_showQTerm external --- Transform a string containing a term in standard prefix notation --- without module qualifiers into the corresponding data term. --- The first argument is a non-empty list of module qualifiers that are tried to --- prefix the constructor in the string in order to get the qualified constructors --- (that must be defined in the current program!). --- In case of a successful parse, the result is a one element list --- containing a pair of the data term and the remaining unparsed string. readsUnqualifiedTerm :: [String] -> String -> [(_,String)] readsUnqualifiedTerm [] _ = error "ReadShowTerm.readsUnqualifiedTerm: list of module prefixes is empty" readsUnqualifiedTerm (prefix:prefixes) s = readsUnqualifiedTermWithPrefixes (prefix:prefixes) s readsUnqualifiedTermWithPrefixes :: [String] -> String -> [(_,String)] readsUnqualifiedTermWithPrefixes prefixes s = (prim_readsUnqualifiedTerm $## prefixes) $## s prim_readsUnqualifiedTerm :: [String] -> String -> [(_,String)] prim_readsUnqualifiedTerm external --- Transforms a string containing a term in standard prefix notation --- without module qualifiers into the corresponding data term. --- The first argument is a non-empty list of module qualifiers that are tried to --- prefix the constructor in the string in order to get the qualified constructors --- (that must be defined in the current program!). --- --- Example: <code>readUnqualifiedTerm ["Prelude"] "Just 3"</code> --- evaluates to <code>(Just 3)</code> readUnqualifiedTerm :: [String] -> String -> _ readUnqualifiedTerm prefixes s = case result of [(term,tail)] -> if all isSpace tail then term else error ("ReadShowTerm.readUnqualifiedTerm: no parse, unmatched string after term: "++tail) [] -> error "ReadShowTerm.readUnqualifiedTerm: no parse" _ -> error "ReadShowTerm.readUnqualifiedTerm: ambiguous parse" where result = readsUnqualifiedTerm prefixes s --- For backward compatibility. Should not be used since their use can be problematic --- in case of constructors with identical names in different modules. readsTerm :: String -> [(_,String)] readsTerm s = prim_readsUnqualifiedTerm [] $## s --- For backward compatibility. Should not be used since their use can be problematic --- in case of constructors with identical names in different modules. readTerm :: String -> _ readTerm s = case result of [(term,tail)] -> if all isSpace tail then term else error ("ReadShowTerm.readTerm: no parse, unmatched string after term: "++tail) [] -> error "ReadShowTerm.readTerm: no parse" _ -> error "ReadShowTerm.readTerm: ambiguous parse" where result = prim_readsUnqualifiedTerm [] $## s --- Transforms a string containing a term in standard prefix notation --- with qualified constructor names into the corresponding data term. --- In case of a successful parse, the result is a one element list --- containing a pair of the data term and the remaining unparsed string. readsQTerm :: String -> [(_,String)] readsQTerm s = prim_readsQTerm $## s prim_readsQTerm :: String -> [(_,String)] prim_readsQTerm external --- Transforms a string containing a term in standard prefix notation --- with qualified constructor names into the corresponding data term. readQTerm :: String -> _ readQTerm s = case result of [(term,tail)] -> if all isSpace tail then term else error "ReadShowTerm.readQTerm: no parse" [] -> error "ReadShowTerm.readQTerm: no parse" _ -> error "ReadShowTerm.readQTerm: ambiguous parse" where result = readsQTerm s --- Reads a file containing a string representation of a term --- in standard prefix notation and returns the corresponding data term. readQTermFile :: String -> IO _ readQTermFile file = readFile file >>= return . readQTerm --- Reads a file containing lines with string representations of terms --- of the same type and returns the corresponding list of data terms. readQTermListFile :: String -> IO [_] readQTermListFile file = readFile file >>= return . map readQTerm . lines --- Writes a ground term into a file in standard prefix notation. --- @param filename - The name of the file to be written. --- @param term - The term to be written to the file as a string. writeQTermFile :: String -> _ -> IO () writeQTermFile filename term = writeFile filename (showQTerm term) --- Writes a list of ground terms into a file. --- Each term is written into a separate line which might be useful --- to modify the file with a standard text editor. --- @param filename - The name of the file to be written. --- @param terms - The list of terms to be written to the file. writeQTermListFile :: String -> [_] -> IO () writeQTermListFile filename terms = writeFile filename (unlines (map showQTerm terms)) |