September 2017 Update

This commit is contained in:
Ingy döt Net 2017-09-23 10:01:46 +02:00
parent bba7bfd280
commit ba8067c3b7
14570 changed files with 153136 additions and 63871 deletions

View file

@ -0,0 +1,66 @@
# split a string based on a number of separators #
# MODE to hold the split results #
MODE SPLITINFO = STRUCT( STRING text # delimited string, may be empty #
, INT position # starting position of the token #
, STRING delimiter # the delimiter that terminated the token #
);
# calculates the length of string s #
OP LENGTH = ( STRING s )INT: ( UPB s + 1 ) - LWB s;
# returns TRUE if s starts with p, FALSE otherwise #
PRIO STARTSWITH = 5;
OP STARTSWITH = ( STRING s, p )BOOL: IF LENGTH p > LENGTH s THEN FALSE ELSE s[ LWB s : ( LWB s + LENGTH p ) - 1 ] = p FI;
# returns an array of SPLITINFO describing the tokens in str based on the delimiters #
# zero-length delimiters are ignored #
PRIO SPLIT = 5;
OP SPLIT = ( STRING str, []STRING delimiters )[]SPLITINFO:
BEGIN
# count the number of tokens #
# allow there to be as many tokens as characters in the string + 2 #
# that would cater for a string composed of delimiters only #
[ 1 : ( UPB str + 3 ) - LWB str ]SPLITINFO tokens;
INT token count := 0;
INT str pos := LWB str;
INT str max = UPB str;
BOOL token pending := FALSE;
# construct the tokens #
str pos := LWB str;
INT prev pos := LWB str;
token count := 0;
token pending := FALSE;
WHILE str pos <= str max
DO
BOOL found delimiter := FALSE;
FOR d FROM LWB delimiters TO UPB delimiters WHILE NOT found delimiter DO
IF LENGTH delimiters[ d ] > 0 THEN
IF found delimiter := str[ str pos : ] STARTSWITH delimiters[ d ] THEN
token count +:= 1;
tokens[ token count ] := ( str[ prev pos : str pos - 1 ], prev pos, delimiters[ d ] );
str pos +:= LENGTH delimiters[ d ];
prev pos := str pos;
token pending := FALSE
FI
FI
OD;
IF NOT found delimiter THEN
# the current character is part of s token #
token pending := TRUE;
str pos +:= 1
FI
OD;
IF token pending THEN
# there is an additional token after the final delimiter #
token count +:= 1;
tokens[ token count ] := ( str[ prev pos : ], prev pos, "" )
FI;
# return an array of the actual tokens #
tokens[ 1 : token count ]
END # SPLIT # ;
# test the SPLIT operator #
[]SPLITINFO test tokens = "a!===b=!=c" SPLIT []STRING( "==", "!=", "=" );
FOR t FROM LWB test tokens TO UPB test tokens DO
SPLITINFO token = test tokens[ t ];
print( ( "token: [", text OF token, "] at: ", whole( position OF token, 0 ), " delimiter: (", delimiter OF token, ")", newline ) )
OD

View file

@ -1,27 +1,28 @@
import Data.List as L
import Data.Maybe
import Data.List
(isPrefixOf, stripPrefix, genericLength, intercalate)
trysplit :: Eq a => [a] -> [[a]] -> Maybe ([a], [a])
trysplit :: String -> [String] -> Maybe (String, String)
trysplit s delims =
case filter (`L.isPrefixOf` s) delims of
[] -> Nothing
(d:_) -> Just (d, fromJust $ L.stripPrefix d s)
case filter (`isPrefixOf` s) delims of
[] -> Nothing
(d:_) -> Just (d, (\(Just x) -> x) $ stripPrefix d s)
multisplit :: (Eq a, Num n) => [a] -> [[a]] -> [([a], [a], n)]
multisplit :: String -> [String] -> [(String, String, Int)]
multisplit list delims =
let ms [] acc pos = [(acc, [], pos)]
let ms [] acc pos = [(acc, [], pos)]
ms l@(s:sx) acc pos =
case trysplit l delims of
Nothing -> ms sx (s:acc) (pos + 1)
Just (d, sxx) -> (acc, d, pos) : ms sxx [] (pos + L.genericLength d)
Nothing -> ms sx (s : acc) (pos + 1)
Just (d, sxx) -> (acc, d, pos) : ms sxx [] (pos + genericLength d)
in ms list [] 0
main :: IO ()
main = do
let test = "a!===b=!=c"
delims = ["==", "!=", "="]
parsed = multisplit test delims
putStrLn "split string:"
putStrLn $ L.intercalate "," $ map (\(a, _, _) -> a) parsed
putStrLn "with [(string, delimiter, offset)]:"
print parsed
let parsed = multisplit "a!===b=!=c" ["==", "!=", "="]
mapM_
putStrLn
[ "split string:"
, intercalate "," $ map (\(a, _, _) -> a) parsed
, "with [(string, delimiter, offset)]:"
, show parsed
]

View file

@ -0,0 +1,31 @@
// version 1.0.6
fun main(args: Array<String>) {
val input = "a!===b=!=c"
val delimiters = arrayOf("==", "!=", "=")
val output = input.split(*delimiters).toMutableList()
for (i in 0 until output.size) {
if (output[i].isEmpty()) output[i] = "empty string"
else output[i] = "\"" + output[i] + "\""
}
println("The splits are:")
println(output)
// now find positions of matched delimiters
val matches = mutableListOf<Pair<String, Int>>()
var index = 0
while (index < input.length) {
var matched = false
for (d in delimiters) {
if (input.drop(index).take(d.length) == d) {
matches.add(d to index)
index += d.length
matched = true
break
}
}
if (!matched) index++
}
println("\nThe delimiters matched and the indices at which they occur are:")
println(matches)
}

View file

@ -0,0 +1,24 @@
procedure multisplit(string text, sequence delims)
integer k = 1, kdx
while 1 do
integer kmin = 0
for i=1 to length(delims) do
integer ki = match(delims[i],text,k)
if ki!=0 then
if kmin=0 or ki<kmin then
kmin = ki
kdx = i
end if
end if
end for
string token = text[k..kmin-1]
if kmin=0 then
printf(1,"Token: [%s] at %d\n",{token,k})
exit
end if
printf(1,"Token: [%s] at %d, delimiter (%s) at %d\n",{token,k,delims[kdx],kmin})
k = kmin+length(delims[kdx])
end while
end procedure
multisplit("a!===b=!=c",{"==","!=","="})

View file

@ -0,0 +1,17 @@
fcn multisplit(text, sep){
lastmatch := i := 0; matches := List();
while(i < text.len()){
foreach j,s in ([0..].zip(sep)){
if(i == text.find(s,i)){
if(i > lastmatch) matches.append(text[lastmatch,i-lastmatch]);
matches.append(T(j,i)); # Replace the string containing the matched separator with a tuple of which separator and where in the string the match occured
lastmatch = i + s.len();
i += s.len()-1;
break;
}
}
i += 1;
}
if(i > lastmatch) matches.append(text[lastmatch,i-lastmatch]);
return(matches);
}

View file

@ -0,0 +1,2 @@
multisplit("a!===b=!=c", T("==", "!=", "=")).println();
multisplit("a!===b=!=c", T("!=", "==", "=")).println();