Commit 4a454532 authored by Michael Hanus 's avatar Michael Hanus
Browse files

Tools updated

parent 543ddf41
......@@ -14,9 +14,12 @@ currypp/.cpm/packages/abstract-curry-2.0.0
currypp/.cpm/packages/flatcurry-2.0.0
currypp/.cpm/packages/html-2.0.0
currypp/.cpm/packages/xml-2.0.0
currypp/.cpm/packages/fl-parser-1.0.0
currypp/.cpm/packages/regexp-1.1.0
optimize/.cpm/packages/cass-2.0.0
optimize/.cpm/packages/cass-analysis-2.0.0
optimize/.cpm/packages/flatcurry-2.0.0
optimize/.cpm/packages/csv-1.0.0
optimize/.cpm/packages/xml-2.0.0
# executables
......
......@@ -1225,7 +1225,7 @@ are used:
"author": "YOUR NAME <YOUR EMAIL ADDRESS>",
"maintainer": "ANOTHER NAME <ANOTHER EMAIL ADDRESS>",
"synopsis": "A ONE-LINE SUMMARY ABOUT THE PACKAGE",
"synopsis": "A MORE DEATILED SUMMARY ABOUT THE PACKAGE",
"description": "A MORE DETAILED SUMMARY ABOUT THE PACKAGE",
"category": [ "Category1", "Category2" ],
"license": "BSD-3-Clause",
"licenseFile": "LICENSE",
......
......@@ -5,7 +5,6 @@
module CPM.Main where
import Char ( toLower )
import CSV ( showCSV )
import Directory ( doesFileExist, getAbsolutePath, doesDirectoryExist
, copyFile, createDirectory, createDirectoryIfMissing
, getCurrentDirectory, getDirectoryContents
......@@ -20,8 +19,10 @@ import Sort ( sortBy )
import System ( getArgs, getEnviron, setEnviron, unsetEnviron, exitWith
, system )
import Boxes (table, render)
import Boxes ( table, render )
import OptParse
import Text.CSV ( showCSV )
import CPM.ErrorLogger
import CPM.FileUtil ( fileInPath, joinSearchPath, safeReadFile, whenFileExists
, ifFileExists, inDirectory, removeDirectoryComplete
......
......@@ -61,20 +61,24 @@ daFuncRule _ (External _) = [] -- nothing known about other externals
daFuncRule calledFuncs (Rule args rhs) =
map fst
(filter ((==Bot) . snd)
(map (\botarg -> (botarg,absEvalExpr rhs [botarg])) args))
(map (\botarg -> (botarg, absEvalExpr rhs [botarg]))
args))
where
-- abstract evaluation of an expression w.r.t. variables assumed to be Bot
absEvalExpr (Var i) bvs = if i `elem` bvs then Bot else Top
absEvalExpr (Lit _) _ = Top
absEvalExpr (Comb ct g es) bvs =
if ct == FuncCall
then maybe (error $ "Abstract value of " ++ show g ++ " not found!")
(\gdas -> let curargs = map (\ (i,e) -> (i,absEvalExpr e bvs))
(zip [1..] es)
cdas = gdas \\
(map fst (filter ((/=Bot) . snd) curargs))
in if null cdas then Top else Bot)
(lookup g calledFuncs)
then
if g == (prelude,"failed")
then Bot -- Prelude.failed never returns a value
else maybe (error $ "Abstract value of " ++ show g ++ " not found!")
(\gdas -> let curargs = map (\ (i,e) -> (i,absEvalExpr e bvs))
(zip [1..] es)
cdas = gdas \\
map fst (filter ((/=Bot) . snd) curargs)
in if null cdas then Top else Bot)
(lookup g calledFuncs)
else Top
absEvalExpr (Free _ e) bvs = absEvalExpr e bvs
absEvalExpr (Let bs e) bvs = absEvalExpr e (absEvalBindings bs bvs)
......
Copyright (c) 2017, Michael Hanus
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the names of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
csv: Reading/writing files in CSV format
========================================
This package contains a library with operations to read and write
files CSV (comma separated values) format.
Files in CSV format can be imported and exported
by most spreadsheed and database applications.
--------------------------------------------------------------------------
{
"name": "csv",
"version": "1.0.0",
"author": "Michael Hanus <mh@informatik.uni-kiel.de>",
"synopsis": "Library for reading/writing files in CSV format",
"category": [ "Data", "Parsing" ],
"dependencies": { },
"exportedModules": [ "Text.CSV" ],
"compilerCompatibility": {
"pakcs": ">= 1.14.0",
"kics2": ">= 0.5.0"
},
"license": "BSD-3-Clause",
"licenseFile": "LICENSE",
"source": {
"git": "https://git.ps.informatik.uni-kiel.de/curry-packages/csv.git",
"tag": "$version"
}
}
------------------------------------------------------------------------------
--- Library for reading/writing files in CSV format.
--- Files in CSV (comma separated values) format can be imported and exported
--- by most spreadsheed and database applications.
---
--- @author Michael Hanus
--- @version September 2004
--- @category general
------------------------------------------------------------------------------
module Text.CSV
( showCSV, readCSV, readCSVWithDelims
, writeCSVFile, readCSVFile, readCSVFileWithDelims
) where
import List(intersperse)
--- Writes a list of records (where each record is a list of strings)
--- into a file in CSV format.
--- @param fname - the name of the result file (with standard suffix ".csv")
--- @param rows - the list of rows
writeCSVFile :: String -> [[String]] -> IO ()
writeCSVFile fname rows = writeFile fname (showCSV rows)
--- Shows a list of records (where each record is a list of strings)
--- as a string in CSV format.
showCSV :: [[String]] -> String
showCSV rows = concatMap showCSVLine rows
--- Shows a list of strings as a line in CSV format.
showCSVLine :: [String] -> String
showCSVLine row = concat (intersperse "," (map convert row)) ++ "\n"
where
-- enclose in quotation marks if necessary:
convert s =
if any (\c->c `elem` ['"',',',';',':','\n']) s
then '"' : concatMap (\c->if c=='"' then [c,c] else [c]) s ++ "\""
else s
--- Reads a file in CSV format and returns the list of records
--- (where each record is a list of strings).
--- @param fname - the name of the result file (with standard suffix ".csv")
readCSVFile :: String -> IO [[String]]
readCSVFile = readCSVFileWithDelims [',']
--- Reads a file in CSV format and returns the list of records
--- (where each record is a list of strings).
--- @param delims - the list of characters considered as delimiters
--- @param fname - the name of the result file (with standard suffix ".csv")
readCSVFileWithDelims :: [Char] -> String -> IO [[String]]
readCSVFileWithDelims delims fname = do
contents <- readFile fname
return (readCSVWithDelims delims contents)
--- Reads a string in CSV format and returns the list of records
--- (where each record is a list of strings).
--- @param str - the string in CSV format
readCSV :: String -> [[String]]
readCSV = readCSVWithDelims [',']
--- Reads a string in CSV format and returns the list of records
--- (where each record is a list of strings).
--- @param delims - the list of characters considered as delimiters
--- @param str - the string in CSV format
readCSVWithDelims :: [Char] -> String -> [[String]]
readCSVWithDelims delims str = map (components delims) (lines str)
--- Breaks a string in CSV record format into a list of components.
components :: [Char] -> String -> [String]
components _ [] = [[]]
components delims (c:cs) =
if c=='"' then breakString cs
else let (e,s) = break (`elem` delims) (c:cs)
in e : (if null s then [] else components delims (tail s))
where
breakString [] = delimError
breakString [x] = if x=='"' then [[]]
else delimError
breakString (x:y:zs) | x=='"' && y=='"' = let (b:bs) = breakString zs
in (x:b):bs
| x=='"' && y `elem` delims = []:components delims zs
| otherwise = let (b:bs) = breakString (y:zs)
in (x:b):bs
delimError = error "Missing closing delimiter in CSV record!"
-- Examples:
-- writeCSVFile "tmp.csv" [["Name","Value"],["aa\"bb,cc","1"]]
-- readCSVFile "tmp.csv"
......@@ -61,20 +61,24 @@ daFuncRule _ (External _) = [] -- nothing known about other externals
daFuncRule calledFuncs (Rule args rhs) =
map fst
(filter ((==Bot) . snd)
(map (\botarg -> (botarg,absEvalExpr rhs [botarg])) args))
(map (\botarg -> (botarg, absEvalExpr rhs [botarg]))
args))
where
-- abstract evaluation of an expression w.r.t. variables assumed to be Bot
absEvalExpr (Var i) bvs = if i `elem` bvs then Bot else Top
absEvalExpr (Lit _) _ = Top
absEvalExpr (Comb ct g es) bvs =
if ct == FuncCall
then maybe (error $ "Abstract value of " ++ show g ++ " not found!")
(\gdas -> let curargs = map (\ (i,e) -> (i,absEvalExpr e bvs))
(zip [1..] es)
cdas = gdas \\
(map fst (filter ((/=Bot) . snd) curargs))
in if null cdas then Top else Bot)
(lookup g calledFuncs)
then
if g == (prelude,"failed")
then Bot -- Prelude.failed never returns a value
else maybe (error $ "Abstract value of " ++ show g ++ " not found!")
(\gdas -> let curargs = map (\ (i,e) -> (i,absEvalExpr e bvs))
(zip [1..] es)
cdas = gdas \\
map fst (filter ((/=Bot) . snd) curargs)
in if null cdas then Top else Bot)
(lookup g calledFuncs)
else Top
absEvalExpr (Free _ e) bvs = absEvalExpr e bvs
absEvalExpr (Let bs e) bvs = absEvalExpr e (absEvalBindings bs bvs)
......
Copyright (c) 2017, Michael Hanus
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the names of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
fl-parser: Functional logic parser combinators
==============================================
This package contains a library with functional logic parser combinators.
The idea and structure of these combinators are adapted from:
Rafael Caballero and Francisco J. Lopez-Fraguas:
A Functional Logic Perspective of Parsing.
In Proc. FLOPS'99, Springer LNCS 1722, pp. 85-99, 1999
This paper contains a detailed description of the idea and usage
of these parser combinators.
The `examples` directory contains some examples for using
these combinators for parsing.
--------------------------------------------------------------------------
---------------------------------------------------------------------------
-- A simple example for the use of the functional logic parser combinators:
-- We define a parser for arithmetic expressions over natural numbers.
-- The presentation of this parser is the value of the expression.
import Parser
import Char
expression = term t <*> plus_minus op <*> expression e >>> (op t e)
<||> term
where op,t,e free
term = factor f <*> prod_div op <*> term t >>> (op f t)
<||> factor
where op,f,t free
factor = terminal '(' <*> expression e <*> terminal ')' >>> e
<||> num
where e free
plus_minus = terminal '+' >>> (+)
<||> terminal '-' >>> (-)
prod_div = terminal '*' >>> (*)
<||> terminal '/' >>> div
num = some digit l >>> numeric_value l
where l free
numeric_value ds = foldl1 ((+) . (10*)) (map (\c->ord c - ord '0') ds)
digit = satisfy isDigit
-- example application: expression val "(10+5*2)/4" =:= [] where val free
---------------------------------------------------------------------------
-- A simple example for the use of the functional logic parser combinators:
--
-- A parser for palindromes over the alphabet 'a' and 'b'
import Parser
import AllSolutions
-- Terminals:
a = terminal 'a'
b = terminal 'b'
-- Palindromes:
pali = empty <|> a <|> b <|> a<*>pali<*>a <|> b<*>pali<*>b
{-
Examples:
Check correctness of a sentence:
> pali "abaaba" =:= []
Generate palindromes:
> pali [x,y,z] =:= [] where x,y,z free
-}
-- Generate list of all palindromes of length 5:
pali5 = getAllSolutions (\[x1,x2,x3,x4,x5] -> pali [x1,x2,x3,x4,x5] =:= [])
-- Generate palindromes of a given length:
palin len = getAllSolutions (\xs -> strlen xs len & pali xs =:= [])
where
-- Has a list a given length?
strlen [] 0 = True
strlen (_:xs) n | n>0 = strlen xs (n-1)
{
"name": "fl-parser",
"version": "1.0.0",
"author": "Michael Hanus <mh@informatik.uni-kiel.de>",
"synopsis": "Library with functional logic parser combinators",
"category": [ "Parsing" ],
"dependencies": { },
"exportedModules": [ "Parser" ],
"compilerCompatibility": {
"pakcs": ">= 1.14.0",
"kics2": ">= 0.5.0"
},
"license": "BSD-3-Clause",
"licenseFile": "LICENSE",
"source": {
"git": "https://git.ps.informatik.uni-kiel.de/curry-packages/fl-parser.git",
"tag": "$version"
}
}
------------------------------------------------------------------------------
--- Library with functional logic parser combinators.
---
--- Adapted from: Rafael Caballero and Francisco J. Lopez-Fraguas:
--- A Functional Logic Perspective of Parsing.
--- In Proc. FLOPS'99, Springer LNCS 1722, pp. 85-99, 1999
---
--- @author Michael Hanus
--- @version December 2012
--- @category general
------------------------------------------------------------------------------
module Parser where
-- Operator declarations for the parser combinators:
infixr 4 <*>
infixr 3 >>>
infixr 2 <|>, <||>
-- We distinguish two kind of parsers:
-- A parser without a representation has type "[token] -> [token]":
-- it parses a list of tokens and returns the remaining unparsed tokens
type Parser token = [token] -> [token]
-- A parser with representation has type "rep -> [token] -> [token]":
-- in addition to the input tokens, it has the representation as an argument
-- (which is usually a free variable bound to the representation after parsing)
type ParserRep rep token = rep -> Parser token
-- Now we can define the basic combinators for parsers:
--- Combines two parsers without representation in an alternative manner.
(<|>) :: Parser t -> Parser t -> Parser t
p <|> q = \sentence -> p sentence ? q sentence
--- Combines two parsers with representation in an alternative manner.
(<||>) :: ParserRep r t -> ParserRep r t -> ParserRep r t
p <||> q = \rep -> p rep <|> q rep
--- Combines two parsers (with or without representation) in a
--- sequential manner.
(<*>) :: Parser t -> Parser t -> Parser t
p1 <*> p2 = seq
where seq sentence | p1 sentence =:= sent1 = p2 sent1 where sent1 free
--- Attaches a representation to a parser without representation.
(>>>) :: Parser token -> rep -> ParserRep rep token
parser >>> repexp = attach
where attach rep sentence | parser sentence =:= rest &> repexp =:= rep
= rest where rest free
-- Finally, we define some useful basic parsers and derived combinators:
--- The empty parser which recognizes the empty word.
empty :: Parser _
empty sentence = sentence
--- A parser recognizing a particular terminal symbol.
terminal :: token -> Parser token
terminal sym (token:tokens) | sym=:=token = tokens
--- A parser (with representation) recognizing a terminal satisfying
--- a given predicate.
satisfy :: (token->Bool) -> ParserRep token token
satisfy pred sym (token:tokens) | pred token =:= True & sym=:=token = tokens
--- A star combinator for parsers. The returned parser
--- repeats zero or more times a parser p with representation and
--- returns the representation of all parsers in a list.
star :: ParserRep rep token -> ParserRep [rep] token
star p = p x <*> (star p) xs >>> (x:xs)
<||> empty >>> [] where x,xs free
--- A some combinator for parsers. The returned parser
--- repeats the argument parser (with representation) at least once.
some :: ParserRep rep token -> ParserRep [rep] token
some p = p x <*> (star p) xs >>> (x:xs) where x,xs free
{-----------------------------------------------------------------------
As a simple example we define a parser for arithmetic expressions
over natural numbers. The presentation of this parser is the value
of the expression.
expression = term t <*> plus_minus op <*> expression e >>> (op t e)
<||> term
where op,t,e free
term = factor f <*> prod_div op <*> term t >>> (op f t)
<||> factor
where op,f,t free
factor = terminal '(' <*> expression e <*> terminal ')' >>> e
<||> num
where e free
plus_minus = terminal '+' >>> (+)
<||> terminal '-' >>> (-)
prod_div = terminal '*' >>> (*)
<||> terminal '/' >>> div
num = some digit l >>> numeric_value l
where l free
numeric_value ds = foldl1 ((+).(10*)) (map (\c->ord c - ord '0') ds)
digit = satisfy isDigit
-- example application: expression val "(10+5*2)/4" =:= []
-----------------------------------------------------------------------}
Copyright (c) 2017, Michael Hanus, Jasper Sikorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the names of the copyright holders nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
regexp: Regular expression matching
===================================
This package contains libraries dealing with regular expressions:
* `RegExpSem`: This library specifies the semantics of
regular expressions and regular expression matching in a high-level
manner via non-deterministic operations. It might be useful
as an oracle to test more efficient regular expression matchers.
* `RegExp`: This library defines a structure of regular expressions
and a simple match operation for regular expression.
This library is used by the Curry preprocessor to translate
integrated code in the form of POSIX extended regular expressions
into Curry programs.
--------------------------------------------------------------------------
---------------------------------------------------------------------
-- Examples and tests for regular expressions semantics and matching.
---------------------------------------------------------------------
import RegExpSem
import Test.Prop
-- Example: regular expression (a|b|c)
abc :: RE Char
abc = Alt (Alt (Lit 'a') (Lit 'b')) (Lit 'c')
-- Example: regular expression (ab*)
abstar :: RE Char
abstar = Conc (Lit 'a') (Star (Lit 'b'))
-- Example: regular expression (ab+)
abplus :: RE Char
abplus = Conc (Lit 'a') (plus (Lit 'b'))
test1 = sem abc <~> ("a" ? "b" ? "c")
test2 = grep abc "dbe" <~> True
-- The following evaluation is finite due to demand-driven non-determinism:
test3 = grep abstar "dabe" <~> True
test4 = grepShow abstar "dbabe" <~> "abe"
test5 = grepShow abc "dbeaxce" <~> ("beaxce" ? "axce" ? "ce")
test6 = grepPos abplus "sfsfsfabdff" <~> 6
{
"name": "regexp",
"version": "1.1.0",
"author": "Michael Hanus <mh@informatik.uni-kiel.de>",
"synopsis": "Library to specify the semantics of regular expressions",
"category": [ "Parsing" ],
"description": "This package contains a library which specifies the semantics of regular expressions and regular expression matching in a high-level manner via non-deterministic operations. This library might be useful as an oracle to test more efficient regular expression matchers. Furthermore, there is also a library which is used by the Curry preprocessor to translate regular expression in POSIX syntax occurring as integrated code in Curry programs.",
"dependencies": { },
"exportedModules": [ "RegExpSem", "RegExp" ],
"compilerCompatibility": {
"pakcs": ">= 2.0.0",
"kics2": ">= 2.0.0"