Brace expansion: Difference between revisions

Rename Perl 6 -> Raku, alphabetize, minor clean-up
m (→‎{{header|REXX}}: added REXX in first line)
(Rename Perl 6 -> Raku, alphabetize, minor clean-up)
Line 916:
{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}
</pre>
 
=={{header|Haskell}}==
[http://www.reddit.com/r/readablecode/comments/1w6exe/p6_crosswalk_braceexpansionparses/cf229at "Here is a direct translation to Haskell using parsec"] (of [http://rosettacode.org/mw/index.php?title=Brace_expansion&oldid=175567#Perl_6 an earlier version of the Perl 6 solution]):
 
<lang haskell>{-# LANGUAGE FlexibleContexts #-}
 
import Text.Parsec
(Parsec, (<|>), anyChar, between, char, many, many1, noneOf, parse,
try)
 
parser :: Parsec String u [String]
parser =
expand <$> many (try alts <|> try alt1 <|> escape <|> pure . pure <$> anyChar)
where
alts = concat <$> between (char '{') (char '}') (alt `sepBy2` char ',')
alt1 =
(: []) . ('{' :) . (++ "}") <$>
between (char '{') (char '}') (many $ noneOf ",{}")
alt =
expand <$>
many (try alts <|> try alt1 <|> escape <|> pure . pure <$> noneOf ",}")
escape = pure <$> sequence [char '\\', anyChar]
expand = foldr ((<*>) . fmap (++)) [""]
p `sepBy2` sep = (:) <$> p <*> many1 (sep >> p)
 
showExpansion :: String -> String
showExpansion = (++) <*> ("\n-->\n" ++) . either show unlines . parse parser []
 
main :: IO ()
main =
mapM_
(putStrLn . showExpansion)
[ "~/{Downloads,Pictures}/*.{jpg,gif,png}"
, "It{{em,alic}iz,erat}e{d,}, please."
, "{,{,gotta have{ ,\\, again\\, }}more }cowbell!"
, "{}} some {\\\\{edge,edgy} }{ cases, here\\\\\\\\\\}"
]</lang>
{{out}}
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png}
-->
~/Downloads/*.jpg
~/Downloads/*.gif
~/Downloads/*.png
~/Pictures/*.jpg
~/Pictures/*.gif
~/Pictures/*.png
 
It{{em,alic}iz,erat}e{d,}, please.
-->
Itemized, please.
Itemize, please.
Italicized, please.
Italicize, please.
Iterated, please.
Iterate, please.
 
{,{,gotta have{ ,\, again\, }}more }cowbell!
-->
cowbell!
more cowbell!
gotta have more cowbell!
gotta have\, again\, more cowbell!
 
{}} some {\\{edge,edgy} }{ cases, here\\\\\}
-->
{}} some {\\edge }{ cases, here\\\\\}
{}} some {\\edgy }{ cases, here\\\\\}</pre>
 
=={{header|Go}}==
Line 1,327 ⟶ 1,260:
ok rosetta_code/Brace_expansion 3.347s
</pre>
 
=={{header|Haskell}}==
[http://www.reddit.com/r/readablecode/comments/1w6exe/p6_crosswalk_braceexpansionparses/cf229at "Here is a direct translation to Haskell using parsec"] (of [http://rosettacode.org/mw/index.php?title=Brace_expansion&oldid=175567#Perl_6 an earlier version of the Perl 6 solution]):
 
<lang haskell>{-# LANGUAGE FlexibleContexts #-}
 
import Text.Parsec
(Parsec, (<|>), anyChar, between, char, many, many1, noneOf, parse,
try)
 
parser :: Parsec String u [String]
parser =
expand <$> many (try alts <|> try alt1 <|> escape <|> pure . pure <$> anyChar)
where
alts = concat <$> between (char '{') (char '}') (alt `sepBy2` char ',')
alt1 =
(: []) . ('{' :) . (++ "}") <$>
between (char '{') (char '}') (many $ noneOf ",{}")
alt =
expand <$>
many (try alts <|> try alt1 <|> escape <|> pure . pure <$> noneOf ",}")
escape = pure <$> sequence [char '\\', anyChar]
expand = foldr ((<*>) . fmap (++)) [""]
p `sepBy2` sep = (:) <$> p <*> many1 (sep >> p)
 
showExpansion :: String -> String
showExpansion = (++) <*> ("\n-->\n" ++) . either show unlines . parse parser []
 
main :: IO ()
main =
mapM_
(putStrLn . showExpansion)
[ "~/{Downloads,Pictures}/*.{jpg,gif,png}"
, "It{{em,alic}iz,erat}e{d,}, please."
, "{,{,gotta have{ ,\\, again\\, }}more }cowbell!"
, "{}} some {\\\\{edge,edgy} }{ cases, here\\\\\\\\\\}"
]</lang>
{{out}}
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png}
-->
~/Downloads/*.jpg
~/Downloads/*.gif
~/Downloads/*.png
~/Pictures/*.jpg
~/Pictures/*.gif
~/Pictures/*.png
 
It{{em,alic}iz,erat}e{d,}, please.
-->
Itemized, please.
Itemize, please.
Italicized, please.
Italicize, please.
Iterated, please.
Iterate, please.
 
{,{,gotta have{ ,\, again\, }}more }cowbell!
-->
cowbell!
more cowbell!
gotta have more cowbell!
gotta have\, again\, more cowbell!
 
{}} some {\\{edge,edgy} }{ cases, here\\\\\}
-->
{}} some {\\edge }{ cases, here\\\\\}
{}} some {\\edgy }{ cases, here\\\\\}</pre>
 
=={{header|J}}==
Line 1,479:
{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}
{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}</pre>
 
 
=={{header|JavaScript}}==
Line 1,726 ⟶ 1,725:
]
}</lang>
 
 
=={{header|Julia}}==
Line 1,983 ⟶ 1,981:
 
</pre>
 
=={{header|Perl 6}}==
The task description allows the taking of shortcuts, but please note that we are not taking any shortcuts here. The solution is short because this particular problem happens to map quite naturally to the strengths of Perl 6.
 
First, the parsing is handled with a grammar that can backtrack in the few places this problem needs it. The <tt>+</tt> quantifier matches one or more alternatives (we handle the case of a single alternative in the walk now), and the <tt>%</tt> modifier requires a comma between each quantified item to its left. Note that the <tt>*</tt> quantifiers do <i>not</i> backtrack here, because the <tt>token</tt> keyword suppresses that; all the backtracking here fails over to a different alternative in an outer alternation (that is, things separated by the <tt>|</tt> character in the grammar. Most of these failovers just nibble an uninteresting character and continue.)
 
On the other end, we recursively walk the parse tree returning expanded sublists, and we do the cartesian concatenation of sublists at each level by use of the <tt>X~</tt> operator, which is a "cross" metaoperator used on a simple <tt>~</tt> concatenation. As a list infix operator, <tt>X~</tt> does not care how many items are on either side, which is just what you want in this case, since some of the arguments are strings and some are lists. Here we use a fold or reduction form in square brackets to interpose the cross-concat between each value generated by the map, which returns a mixture of lists and literal strings. One other thing that might not be obvious: if we bind to the match variable, <tt>$/</tt>, we automatically get all the syntactic sugar for its submatches. In this case, <tt>$0</tt> is short for <tt>$/[0]</tt>, and represents all the submatches captured by 0th set of parens in either <tt>TOP</tt> or <tt>alt</tt>. <tt>$&lt;meta&gt;</tt> is likewise short for <tt>$/&lt;meta&gt;</tt>, and retrieves what was captured by that named submatch.
<lang perl6>grammar BraceExpansion {
token TOP { ( <meta> | . )* }
token meta { '{' <alts> '}' | \\ . }
token alts { <alt>+ % ',' }
token alt { ( <meta> | <-[ , } ]> )* }
}
 
sub crosswalk($/) {
|[X~] flat '', $0.map: -> $/ { $<meta><alts><alt>.&alternatives or ~$/ }
}
 
sub alternatives($_) {
when :not { () }
when 1 { '{' X~ $_».&crosswalk X~ '}' }
default { $_».&crosswalk }
}
 
sub brace-expand($s) { crosswalk BraceExpansion.parse($s) }
 
# Testing:
 
sub bxtest(*@s) {
for @s -> $s {
say "\n$s";
for brace-expand($s) {
say " ", $_;
}
}
}
 
bxtest Q:to/END/.lines;
~/{Downloads,Pictures}/*.{jpg,gif,png}
It{{em,alic}iz,erat}e{d,}, please.
{,{,gotta have{ ,\, again\, }}more }cowbell!
a{b{1,2}c
a{1,2}b}c
a{1,{2},3}b
more{ darn{ cowbell,},}
ab{c,d\,e{f,g\h},i\,j{k,l\,m}n,o\,p}qr
{a,{\,b}c
a{b,{{c}}
{a{\}b,c}d
END</lang>
{{out}}
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png}
~/Downloads/*.jpg
~/Downloads/*.gif
~/Downloads/*.png
~/Pictures/*.jpg
~/Pictures/*.gif
~/Pictures/*.png
 
It{{em,alic}iz,erat}e{d,}, please.
Itemized, please.
Itemize, please.
Italicized, please.
Italicize, please.
Iterated, please.
Iterate, please.
 
{,{,gotta have{ ,\, again\, }}more }cowbell!
cowbell!
more cowbell!
gotta have more cowbell!
gotta have\, again\, more cowbell!
 
{}} some {\\{edge,edgy} }{ cases, here\\\}
{}} some {\\edge }{ cases, here\\\}
{}} some {\\edgy }{ cases, here\\\}
 
a{b{1,2}c
a{b1c
a{b2c
 
a{1,2}b}c
a1b}c
a2b}c
 
a{1,{2},3}b
a1b
a{2}b
a3b
 
more{ darn{ cowbell,},}
more darn cowbell
more darn
more
 
ab{c,d\,e{f,g\h},i\,j{k,l\,m}n,o\,p}qr
abcqr
abd\,efqr
abd\,eg\hqr
abi\,jknqr
abi\,jl\,mnqr
abo\,pqr
 
{a,{\,b}c
{a,{\,b}c
 
a{b,{{c}}
a{b,{{c}}
 
{a{\}b,c}d
{a\}bd
{acd</pre>
 
=={{header|Phix}}==
Line 2,516 ⟶ 2,402:
{}} some }{,{\\ edge ,}{ cases, {here} \\\\}
{}} some }{,{\\ edge ,}{ cases, {here} \\\\}</pre>
 
=={{header|Raku}}==
(formerly Perl 6)
The task description allows the taking of shortcuts, but please note that we are not taking any shortcuts here. The solution is short because this particular problem happens to map quite naturally to the strengths of Perl 6.
 
First, the parsing is handled with a grammar that can backtrack in the few places this problem needs it. The <tt>+</tt> quantifier matches one or more alternatives (we handle the case of a single alternative in the walk now), and the <tt>%</tt> modifier requires a comma between each quantified item to its left. Note that the <tt>*</tt> quantifiers do <i>not</i> backtrack here, because the <tt>token</tt> keyword suppresses that; all the backtracking here fails over to a different alternative in an outer alternation (that is, things separated by the <tt>|</tt> character in the grammar. Most of these failovers just nibble an uninteresting character and continue.)
 
On the other end, we recursively walk the parse tree returning expanded sublists, and we do the cartesian concatenation of sublists at each level by use of the <tt>X~</tt> operator, which is a "cross" metaoperator used on a simple <tt>~</tt> concatenation. As a list infix operator, <tt>X~</tt> does not care how many items are on either side, which is just what you want in this case, since some of the arguments are strings and some are lists. Here we use a fold or reduction form in square brackets to interpose the cross-concat between each value generated by the map, which returns a mixture of lists and literal strings. One other thing that might not be obvious: if we bind to the match variable, <tt>$/</tt>, we automatically get all the syntactic sugar for its submatches. In this case, <tt>$0</tt> is short for <tt>$/[0]</tt>, and represents all the submatches captured by 0th set of parens in either <tt>TOP</tt> or <tt>alt</tt>. <tt>$&lt;meta&gt;</tt> is likewise short for <tt>$/&lt;meta&gt;</tt>, and retrieves what was captured by that named submatch.
<lang perl6>grammar BraceExpansion {
token TOP { ( <meta> | . )* }
token meta { '{' <alts> '}' | \\ . }
token alts { <alt>+ % ',' }
token alt { ( <meta> | <-[ , } ]> )* }
}
 
sub crosswalk($/) {
|[X~] flat '', $0.map: -> $/ { $<meta><alts><alt>.&alternatives or ~$/ }
}
 
sub alternatives($_) {
when :not { () }
when 1 { '{' X~ $_».&crosswalk X~ '}' }
default { $_».&crosswalk }
}
 
sub brace-expand($s) { crosswalk BraceExpansion.parse($s) }
 
# Testing:
 
sub bxtest(*@s) {
for @s -> $s {
say "\n$s";
for brace-expand($s) {
say " ", $_;
}
}
}
 
bxtest Q:to/END/.lines;
~/{Downloads,Pictures}/*.{jpg,gif,png}
It{{em,alic}iz,erat}e{d,}, please.
{,{,gotta have{ ,\, again\, }}more }cowbell!
a{b{1,2}c
a{1,2}b}c
a{1,{2},3}b
more{ darn{ cowbell,},}
ab{c,d\,e{f,g\h},i\,j{k,l\,m}n,o\,p}qr
{a,{\,b}c
a{b,{{c}}
{a{\}b,c}d
END</lang>
{{out}}
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png}
~/Downloads/*.jpg
~/Downloads/*.gif
~/Downloads/*.png
~/Pictures/*.jpg
~/Pictures/*.gif
~/Pictures/*.png
 
It{{em,alic}iz,erat}e{d,}, please.
Itemized, please.
Itemize, please.
Italicized, please.
Italicize, please.
Iterated, please.
Iterate, please.
 
{,{,gotta have{ ,\, again\, }}more }cowbell!
cowbell!
more cowbell!
gotta have more cowbell!
gotta have\, again\, more cowbell!
 
{}} some {\\{edge,edgy} }{ cases, here\\\}
{}} some {\\edge }{ cases, here\\\}
{}} some {\\edgy }{ cases, here\\\}
 
a{b{1,2}c
a{b1c
a{b2c
 
a{1,2}b}c
a1b}c
a2b}c
 
a{1,{2},3}b
a1b
a{2}b
a3b
 
more{ darn{ cowbell,},}
more darn cowbell
more darn
more
 
ab{c,d\,e{f,g\h},i\,j{k,l\,m}n,o\,p}qr
abcqr
abd\,efqr
abd\,eg\hqr
abi\,jknqr
abi\,jl\,mnqr
abo\,pqr
 
{a,{\,b}c
{a,{\,b}c
 
a{b,{{c}}
a{b,{{c}}
 
{a{\}b,c}d
{a\}bd
{acd</pre>
 
=={{header|REXX}}==
Line 3,511 ⟶ 3,510:
{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}
</pre>
 
=={{header|Simula}}==
{{trans|Python}}
10,327

edits