Brace expansion: Difference between revisions
Content added Content deleted
(Added Lua.) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 276: | Line 276: | ||
=={{header|11l}}== |
=={{header|11l}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=11l>F getitem(=s, depth = 0) |
||
V out = [‘’] |
V out = [‘’] |
||
L s != ‘’ |
L s != ‘’ |
||
Line 317: | Line 317: | ||
{,{,gotta have{ ,\, again\, }}more }cowbell! |
{,{,gotta have{ ,\, again\, }}more }cowbell! |
||
{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}’.split("\n") |
{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}’.split("\n") |
||
print(([s] [+] getitem(s)[0]).join("\n\t")"\n")</ |
print(([s] [+] getitem(s)[0]).join("\n\t")"\n")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 337: | Line 337: | ||
This may seem like a cheat, but it ''is'' a legitimate and obvious way to tackle the problem with AppleScript in the unlikely event that the need should arise. It adjusts the escape levels in the input text, feeds it as a shell script to macOS's sh shell, and lets ''it'' handle the expansion. |
This may seem like a cheat, but it ''is'' a legitimate and obvious way to tackle the problem with AppleScript in the unlikely event that the need should arise. It adjusts the escape levels in the input text, feeds it as a shell script to macOS's sh shell, and lets ''it'' handle the expansion. |
||
< |
<syntaxhighlight lang=applescript>use AppleScript version "2.4" -- OS X 10.10 (Yosemite) or later |
||
use framework "Foundation" |
use framework "Foundation" |
||
use scripting additions |
use scripting additions |
||
Line 372: | Line 372: | ||
set AppleScript's text item delimiters to astid |
set AppleScript's text item delimiters to astid |
||
log output -- To see the result without the backslash-escaping.</ |
log output -- To see the result without the backslash-escaping.</syntaxhighlight> |
||
{{output}} |
{{output}} |
||
Line 396: | Line 396: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
< |
<syntaxhighlight lang=autohotkey>;This one is a lot more simpler than the rest |
||
BraceExp(string, del:="`n") { |
BraceExp(string, del:="`n") { |
||
Loop, Parse, string |
Loop, Parse, string |
||
Line 412: | Line 412: | ||
Msgbox, % BraceExp("apple {bush,tree}") |
Msgbox, % BraceExp("apple {bush,tree}") |
||
Msgbox, % BraceExp("h{i,ello}") |
Msgbox, % BraceExp("h{i,ello}") |
||
Msgbox, % BraceExp("rosetta{code,stone}")</ |
Msgbox, % BraceExp("rosetta{code,stone}")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>enable_video |
<pre>enable_video |
||
Line 428: | Line 428: | ||
=={{header|C}}== |
=={{header|C}}== |
||
Handles only properly formed input. |
Handles only properly formed input. |
||
< |
<syntaxhighlight lang=c>#include <stdbool.h> |
||
#include <stdio.h> |
#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 738: | Line 738: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Pattern: ~/{Downloads,Pictures}/*.{jpg,gif,png} |
<pre>Pattern: ~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
Line 765: | Line 765: | ||
C++11 solution: |
C++11 solution: |
||
< |
<syntaxhighlight lang=cpp>#include <iostream> |
||
#include <iterator> |
#include <iterator> |
||
#include <string> |
#include <string> |
||
Line 937: | Line 937: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
This approach turns the string into a tree structure, with Tokens that are either text, a concatenation or an alteration. |
This approach turns the string into a tree structure, with Tokens that are either text, a concatenation or an alteration. |
||
{{works with|C sharp|8}} |
{{works with|C sharp|8}} |
||
< |
<syntaxhighlight lang=csharp>using System; |
||
using System.Collections; |
using System.Collections; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
Line 1,098: | Line 1,098: | ||
return result; |
return result; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=csharp>public static class BraceExpansion |
||
{ |
{ |
||
const char L = '{', R = '}', S = ','; |
const char L = '{', R = '}', S = ','; |
||
Line 1,149: | Line 1,149: | ||
return (null, ""); |
return (null, ""); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,175: | Line 1,175: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang=lisp>(defstruct alternation |
||
(alternatives nil :type list)) |
(alternatives nil :type list)) |
||
Line 1,260: | Line 1,260: | ||
(dolist (output (expand input)) |
(dolist (output (expand input)) |
||
(format t " ~A~%" output)) |
(format t " ~A~%" output)) |
||
(terpri)))</ |
(terpri)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
Line 1,292: | Line 1,292: | ||
{{trans|Python}} |
{{trans|Python}} |
||
This code is not UTF-corrected, because it uses slicing instead of front, popFront, etc. |
This code is not UTF-corrected, because it uses slicing instead of front, popFront, etc. |
||
< |
<syntaxhighlight lang=d>import std.stdio, std.typecons, std.array, std.range, std.algorithm, std.string; |
||
Nullable!(Tuple!(string[], string)) getGroup(string s, in uint depth) |
Nullable!(Tuple!(string[], string)) getGroup(string s, in uint depth) |
||
Line 1,372: | Line 1,372: | ||
foreach (const s; testCases.splitLines) |
foreach (const s; testCases.splitLines) |
||
writefln("%s\n%-( %s\n%)\n", s, s.getItems[0]); |
writefln("%s\n%-( %s\n%)\n", s, s.getItems[0]); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
Line 1,447: | Line 1,447: | ||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
< |
<syntaxhighlight lang=elixir>defmodule Brace_expansion do |
||
def getitem(s), do: getitem(String.codepoints(s), 0, [""]) |
def getitem(s), do: getitem(String.codepoints(s), 0, [""]) |
||
Line 1,498: | Line 1,498: | ||
|> Enum.each(fn str -> IO.puts "\t#{str}" end) |
|> Enum.each(fn str -> IO.puts "\t#{str}" end) |
||
IO.puts "" |
IO.puts "" |
||
end)</ |
end)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,531: | Line 1,531: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
<code>expand.go</code>: |
<code>expand.go</code>: |
||
< |
<syntaxhighlight lang=go>package expand |
||
// Expander is anything that can be expanded into a slice of strings. |
// Expander is anything that can be expanded into a slice of strings. |
||
Line 1,732: | Line 1,732: | ||
alt = append(alt, sub) |
alt = append(alt, sub) |
||
return alt |
return alt |
||
}</ |
}</syntaxhighlight> |
||
<code>expand_test.go</code> |
<code>expand_test.go</code> |
||
< |
<syntaxhighlight lang=go>package expand |
||
import ( |
import ( |
||
Line 1,817: | Line 1,817: | ||
Expand(input) |
Expand(input) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,875: | Line 1,875: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang=groovy>class BraceExpansion { |
||
static void main(String[] args) { |
static void main(String[] args) { |
||
for (String s : [ |
for (String s : [ |
||
Line 1,924: | Line 1,924: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Itemized, please. |
<pre>Itemized, please. |
||
Line 1,951: | Line 1,951: | ||
[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#Raku an earlier version of the Raku solution]): |
[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#Raku an earlier version of the Raku solution]): |
||
< |
<syntaxhighlight lang=haskell>import qualified Text.Parsec as P |
||
showExpansion :: String -> String |
showExpansion :: String -> String |
||
Line 1,994: | Line 1,994: | ||
, "{,{,gotta have{ ,\\, again\\, }}more }cowbell!" |
, "{,{,gotta have{ ,\\, again\\, }}more }cowbell!" |
||
, "{}} some }{,{\\\\{ edge, edge} \\,}{ cases, {here} \\\\\\\\\\}" |
, "{}} some }{,{\\\\{ edge, edge} \\,}{ cases, {here} \\\\\\\\\\}" |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>It{{em,alic}iz,erat}e{d,}, please. |
<pre>It{{em,alic}iz,erat}e{d,}, please. |
||
Line 2,022: | Line 2,022: | ||
Implementation: |
Implementation: |
||
<syntaxhighlight lang=J> |
|||
<lang J> |
|||
NB. legit { , and } do not follow a legit backslash: |
NB. legit { , and } do not follow a legit backslash: |
||
legit=: 1,_1}.4>(3;(_2[\"1".;._2]0 :0);('\';a.);0 _1 0 1)&;:&.(' '&,) |
legit=: 1,_1}.4>(3;(_2[\"1".;._2]0 :0);('\';a.);0 _1 0 1)&;:&.(' '&,) |
||
Line 2,064: | Line 2,064: | ||
options=. }:mask <;._1 y |
options=. }:mask <;._1 y |
||
prefix,each options,each suffix |
prefix,each options,each suffix |
||
)</ |
)</syntaxhighlight> |
||
Examples: |
Examples: |
||
< |
<syntaxhighlight lang=J> >expand t1 |
||
~/Downloads/*.jpg |
~/Downloads/*.jpg |
||
~/Downloads/*.gif |
~/Downloads/*.gif |
||
Line 2,089: | Line 2,089: | ||
>expand t4 |
>expand t4 |
||
{}} some {\\edge }{ cases, here\\\} |
{}} some {\\edge }{ cases, here\\\} |
||
{}} some {\\edgy }{ cases, here\\\}</ |
{}} some {\\edgy }{ cases, here\\\}</syntaxhighlight> |
||
Explanation: |
Explanation: |
||
Line 2,101: | Line 2,101: | ||
=={{header|Java}}== |
=={{header|Java}}== |
||
Should be able to handle all printable Unicode. |
Should be able to handle all printable Unicode. |
||
< |
<syntaxhighlight lang=java>public class BraceExpansion { |
||
public static void main(String[] args) { |
public static void main(String[] args) { |
||
Line 2,146: | Line 2,146: | ||
} |
} |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre>Itemized, please. |
<pre>Itemized, please. |
||
Line 2,180: | Line 2,180: | ||
Each node of the parse tree consists of one of two simple functions (AND: syntagmatic concatenation, OR: flattening of paradigms) with a set of arguments, each of which may be a plain string or an AND or OR subtree. The expansions are derived by evaluating the parse tree as an expression. |
Each node of the parse tree consists of one of two simple functions (AND: syntagmatic concatenation, OR: flattening of paradigms) with a set of arguments, each of which may be a plain string or an AND or OR subtree. The expansions are derived by evaluating the parse tree as an expression. |
||
< |
<syntaxhighlight lang=JavaScript>(function () { |
||
'use strict' |
'use strict' |
||
Line 2,370: | Line 2,370: | ||
}).join('\n\n'); |
}).join('\n\n'); |
||
})();</ |
})();</syntaxhighlight> |
||
Value returned by function: |
Value returned by function: |
||
Line 2,406: | Line 2,406: | ||
Sample of parse trees logged to the console: |
Sample of parse trees logged to the console: |
||
< |
<syntaxhighlight lang=JavaScript>{ |
||
"fn": "[function and]", |
"fn": "[function and]", |
||
"args": [ |
"args": [ |
||
Line 2,440: | Line 2,440: | ||
" please." |
" please." |
||
] |
] |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
{{trans|Python}} < |
{{trans|Python}} <syntaxhighlight lang=julia> function getitem(s, depth=0) |
||
out = [""] |
out = [""] |
||
while s != "" |
while s != "" |
||
Line 2,494: | Line 2,494: | ||
println(ans) |
println(ans) |
||
end |
end |
||
end </ |
end </syntaxhighlight> {{output}} <pre> |
||
~/{Downloads,Pictures}/*.{jpg,gif,png} |
~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
-------------------------------------------- |
-------------------------------------------- |
||
Line 2,528: | Line 2,528: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|Java}} |
{{trans|Java}} |
||
< |
<syntaxhighlight lang=scala>// version 1.1.2 |
||
object BraceExpansion { |
object BraceExpansion { |
||
Line 2,579: | Line 2,579: | ||
BraceExpansion.expand(s) |
BraceExpansion.expand(s) |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,612: | Line 2,612: | ||
Note that this code isn't very memory efficient. |
Note that this code isn't very memory efficient. |
||
< |
<syntaxhighlight lang=Lua>local function wrapEachItem(items, prefix, suffix) |
||
local itemsWrapped = {} |
local itemsWrapped = {} |
||
Line 2,705: | Line 2,705: | ||
end |
end |
||
print() |
print() |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,723: | Line 2,723: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang=Mathematica>(*The strategy is to first capture all special sub-expressions and reformat them so they are semantically clear. The built in function Distribute could then do the work of creating the alternatives, but the order wouldn't match that given in the instructions (although as a set the alternatives would be correct). I'll take a more complicated route so as to follow the instructions exactly.*) |
||
(*A few named constants for readability.*) |
(*A few named constants for readability.*) |
||
Line 2,756: | Line 2,756: | ||
(*Data was stored in a local file.*) |
(*Data was stored in a local file.*) |
||
BraceTestData=ReadList[FileNameJoin[{NotebookDirectory[],"BraceTestData.txt"}],String];BraceTestData//TableForm</ |
BraceTestData=ReadList[FileNameJoin[{NotebookDirectory[],"BraceTestData.txt"}],String];BraceTestData//TableForm</syntaxhighlight> |
||
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
It{{em,alic}iz,erat}e{d,}, please. |
It{{em,alic}iz,erat}e{d,}, please. |
||
Line 2,791: | Line 2,791: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
{{trans|Seed7}} |
{{trans|Seed7}} |
||
< |
<syntaxhighlight lang=Nim>proc expandBraces(str: string) = |
||
var |
var |
||
Line 2,838: | Line 2,838: | ||
"{}} some }{,{\\\\{ edge, edge} \\,}{ cases, {here} \\\\\\\\\\}"]: |
"{}} some }{,{\\\\{ edge, edge} \\,}{ cases, {here} \\\\\\\\\\}"]: |
||
echo "\nExpansions of \"", str, "\":" |
echo "\nExpansions of \"", str, "\":" |
||
expandBraces(str)</ |
expandBraces(str)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,875: | Line 2,875: | ||
So here is a manual solution that implements the specification precisely: |
So here is a manual solution that implements the specification precisely: |
||
< |
<syntaxhighlight lang=perl>sub brace_expand { |
||
my $input = shift; |
my $input = shift; |
||
my @stack = ([my $current = ['']]); |
my @stack = ([my $current = ['']]); |
||
Line 2,915: | Line 2,915: | ||
return @$current; |
return @$current; |
||
}</ |
}</syntaxhighlight> |
||
Usage demonstration: |
Usage demonstration: |
||
< |
<syntaxhighlight lang=perl>while (my $input = <DATA>) { |
||
chomp($input); |
chomp($input); |
||
print "$input\n"; |
print "$input\n"; |
||
Line 2,929: | Line 2,929: | ||
It{{em,alic}iz,erat}e{d,}, please. |
It{{em,alic}iz,erat}e{d,}, please. |
||
{,{,gotta have{ ,\, again\, }}more }cowbell! |
{,{,gotta have{ ,\, again\, }}more }cowbell! |
||
{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}</ |
{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,962: | Line 2,962: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Fairly straightforward recursive solution |
Fairly straightforward recursive solution |
||
<!--< |
<!--<syntaxhighlight lang=Phix>(phixonline)--> |
||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Brace_expansion.exw</span> |
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Brace_expansion.exw</span> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
Line 3,035: | Line 3,035: | ||
<span style="color: #000000;">edump</span><span style="color: #0000FF;">(</span><span style="color: #000000;">brarse</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`{,{,gotta have{ ,\, again\, }}more }cowbell!`</span><span style="color: #0000FF;">))</span> |
<span style="color: #000000;">edump</span><span style="color: #0000FF;">(</span><span style="color: #000000;">brarse</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`{,{,gotta have{ ,\, again\, }}more }cowbell!`</span><span style="color: #0000FF;">))</span> |
||
<span style="color: #000000;">edump</span><span style="color: #0000FF;">(</span><span style="color: #000000;">brarse</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}`</span><span style="color: #0000FF;">))</span> |
<span style="color: #000000;">edump</span><span style="color: #0000FF;">(</span><span style="color: #000000;">brarse</span><span style="color: #0000FF;">(</span><span style="color: #008000;">`{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}`</span><span style="color: #0000FF;">))</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{Out}} |
{{Out}} |
||
<pre> |
<pre> |
||
Line 3,060: | Line 3,060: | ||
=={{header|PHP}}== |
=={{header|PHP}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=php>function getitem($s,$depth=0) { |
||
$out = ['']; |
$out = ['']; |
||
while ($s) { |
while ($s) { |
||
Line 3,133: | Line 3,133: | ||
printf(" %s\n", $expansion); |
printf(" %s\n", $expansion); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,164: | Line 3,164: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang=PicoLisp>(de braceExpand (Str) |
||
(let Lst |
(let Lst |
||
(make |
(make |
||
Line 3,195: | Line 3,195: | ||
(if (pair (car Lst)) |
(if (pair (car Lst)) |
||
(mapcan recurse (car Lst)) |
(mapcan recurse (car Lst)) |
||
(list (car Lst)) ) ) ) ) ) ) )</ |
(list (car Lst)) ) ) ) ) ) ) )</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang=PicoLisp>(test |
||
(quote |
(quote |
||
"~/Downloads/*.jpg" |
"~/Downloads/*.jpg" |
||
Line 3,229: | Line 3,229: | ||
"{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}" |
"{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}" |
||
"{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}" ) |
"{}} some }{,{\\ edge \,}{ cases, {here} \\\\\}" ) |
||
(braceExpand "{}} some }{,{\\\\{ edge, edge} \\,}{ cases, {here} \\\\\\\\\\}") )</ |
(braceExpand "{}} some }{,{\\\\{ edge, edge} \\,}{ cases, {here} \\\\\\\\\\}") )</syntaxhighlight> |
||
=={{header|PowerShell}}== |
=={{header|PowerShell}}== |
||
{{works with|PowerShell|2}} |
{{works with|PowerShell|2}} |
||
< |
<syntaxhighlight lang=PowerShell> |
||
function Expand-Braces ( [string]$String ) |
function Expand-Braces ( [string]$String ) |
||
{ |
{ |
||
Line 3,289: | Line 3,289: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
< |
<syntaxhighlight lang=PowerShell> |
||
$TestStrings = @( |
$TestStrings = @( |
||
'It{{em,alic}iz,erat}e{d,}, please.' |
'It{{em,alic}iz,erat}e{d,}, please.' |
||
Line 3,305: | Line 3,305: | ||
Expand-Braces $String |
Expand-Braces $String |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,340: | Line 3,340: | ||
=={{header|Prolog}}== |
=={{header|Prolog}}== |
||
< |
<syntaxhighlight lang=Prolog> |
||
sym(',', commalist) --> ['\\',','], !. |
sym(',', commalist) --> ['\\',','], !. |
||
sym(H, Context) --> [H], { not(H = '{'; H = '}'), (Context = commalist -> not(H = ','); true) }. |
sym(H, Context) --> [H], { not(H = '{'; H = '}'), (Context = commalist -> not(H = ','); true) }. |
||
Line 3,362: | Line 3,362: | ||
brace_expansion(In, Out) :- atom_chars(In, Chars), findall(Out,grammar(Out, Chars, []), List), list_to_set(List, Out). |
brace_expansion(In, Out) :- atom_chars(In, Chars), findall(Out,grammar(Out, Chars, []), List), list_to_set(List, Out). |
||
</syntaxhighlight> |
|||
</lang> |
|||
Testing: |
Testing: |
||
< |
<syntaxhighlight lang=Prolog> |
||
?- brace_expansion("~/{Downloads,Pictures}/*.{jpg,gif,png}", Out). |
?- brace_expansion("~/{Downloads,Pictures}/*.{jpg,gif,png}", Out). |
||
Out = ["~/Downloads/*.jpg","~/Downloads/*.gif","~/Downloads/*.png","~/Pictures/*.jpg","~/Pictures/*.gif","~/Pictures/*.png"]. |
Out = ["~/Downloads/*.jpg","~/Downloads/*.gif","~/Downloads/*.png","~/Pictures/*.jpg","~/Pictures/*.gif","~/Pictures/*.png"]. |
||
Line 3,375: | Line 3,375: | ||
Out = ["cowbell!", "more cowbell!", "gotta have more cowbell!", "gotta have, again, more cowbell!"]. |
Out = ["cowbell!", "more cowbell!", "gotta have more cowbell!", "gotta have, again, more cowbell!"]. |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Python}}== |
=={{header|Python}}== |
||
< |
<syntaxhighlight lang=python>def getitem(s, depth=0): |
||
out = [""] |
out = [""] |
||
while s: |
while s: |
||
Line 3,417: | Line 3,417: | ||
{,{,gotta have{ ,\, again\, }}more }cowbell! |
{,{,gotta have{ ,\, again\, }}more }cowbell! |
||
{}} some }{,{\\\\{ edge, edge} \,}{ cases, {here} \\\\\\\\\}'''.split('\n'): |
{}} some }{,{\\\\{ edge, edge} \,}{ cases, {here} \\\\\\\\\}'''.split('\n'): |
||
print "\n\t".join([s] + getitem(s)[0]) + "\n"</ |
print "\n\t".join([s] + getitem(s)[0]) + "\n"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,451: | Line 3,451: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=racket>#lang racket/base |
||
(require racket/match) |
(require racket/match) |
||
(define (merge-lists as . bss) |
(define (merge-lists as . bss) |
||
Line 3,500: | Line 3,500: | ||
)) |
)) |
||
(for ((s (in-list patterns)) #:when (printf "expand: ~a~%" s) (x (in-list (brace-expand s)))) |
(for ((s (in-list patterns)) #:when (printf "expand: ~a~%" s) (x (in-list (brace-expand s)))) |
||
(printf "\t~a~%" x)))</ |
(printf "\t~a~%" x)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>expand: ~/{Downloads,Pictures}/*.{jpg,gif,png} |
<pre>expand: ~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
Line 3,532: | Line 3,532: | ||
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>$<meta></tt> is likewise short for <tt>$/<meta></tt>, and retrieves what was captured by that named submatch. |
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>$<meta></tt> is likewise short for <tt>$/<meta></tt>, and retrieves what was captured by that named submatch. |
||
<lang |
<syntaxhighlight lang=raku line>grammar BraceExpansion { |
||
token TOP { ( <meta> | . )* } |
token TOP { ( <meta> | . )* } |
||
token meta { '{' <alts> '}' | \\ . } |
token meta { '{' <alts> '}' | \\ . } |
||
Line 3,574: | Line 3,574: | ||
a{b,{{c}} |
a{b,{{c}} |
||
{a{\}b,c}d |
{a{\}b,c}d |
||
END</ |
END</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
Line 3,639: | Line 3,639: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
< |
<syntaxhighlight lang=rexx>/*- REXX -------------------------------------------------------------- |
||
* Brace expansion |
* Brace expansion |
||
* 26.07.2016 |
* 26.07.2016 |
||
Line 3,846: | Line 3,846: | ||
Say arg(1) /* show on screen */ |
Say arg(1) /* show on screen */ |
||
Call lineout oid,arg(1) /* write to file */ |
Call lineout oid,arg(1) /* write to file */ |
||
Return</ |
Return</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>J:\>rexx braces |
<pre>J:\>rexx braces |
||
Line 3,896: | Line 3,896: | ||
=={{header|Ruby}}== |
=={{header|Ruby}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=ruby>def getitem(s, depth=0) |
||
out = [""] |
out = [""] |
||
until s.empty? |
until s.empty? |
||
Line 3,936: | Line 3,936: | ||
puts getitem(s)[0].map{|str| "\t"+str} |
puts getitem(s)[0].map{|str| "\t"+str} |
||
puts |
puts |
||
end</ |
end</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,968: | Line 3,968: | ||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang=rust>const OPEN_CHAR: char = '{'; |
||
const CLOSE_CHAR: char = '}'; |
const CLOSE_CHAR: char = '}'; |
||
const SEPARATOR: char = ','; |
const SEPARATOR: char = ','; |
||
Line 4,151: | Line 4,151: | ||
println!("{}", line); |
println!("{}", line); |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Line 4,186: | Line 4,186: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=rust> |
||
fn main() { |
fn main() { |
||
let input = "~/{Downloads,Pictures}/*.{jpg,gif,png} |
let input = "~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
Line 4,267: | Line 4,267: | ||
None |
None |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 4,297: | Line 4,297: | ||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
{{works with|Scala|2.11}} |
{{works with|Scala|2.11}} |
||
< |
<syntaxhighlight lang=scala> |
||
import collection.mutable.ListBuffer |
import collection.mutable.ListBuffer |
||
case class State(isChild: Boolean, alts: ListBuffer[String], rem: List[Char]) |
case class State(isChild: Boolean, alts: ListBuffer[String], rem: List[Char]) |
||
Line 4,328: | Line 4,328: | ||
parseElem(State(false, ListBuffer(""), s.toList)).alts |
parseElem(State(false, ListBuffer(""), s.toList)).alts |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang=scala> |
||
println(expand("""~/{Downloads,Pictures}/*.{jpg,gif,png}""") mkString "\n") |
println(expand("""~/{Downloads,Pictures}/*.{jpg,gif,png}""") mkString "\n") |
||
println(expand("It{{em,alic}iz,erat}e{d,}, please.") mkString "\n") |
println(expand("It{{em,alic}iz,erat}e{d,}, please.") mkString "\n") |
||
println(expand("""{,{,gotta have{ ,\, again\, }}more }cowbell!""") mkString "\n") |
println(expand("""{,{,gotta have{ ,\, again\, }}more }cowbell!""") mkString "\n") |
||
println(expand("""{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}""") mkString "\n") |
println(expand("""{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}""") mkString "\n") |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,359: | Line 4,359: | ||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
< |
<syntaxhighlight lang=Scheme> |
||
(define (parse-brackets str) |
(define (parse-brackets str) |
||
;; We parse the bracketed strings using an accumulator and a stack |
;; We parse the bracketed strings using an accumulator and a stack |
||
Line 4,450: | Line 4,450: | ||
(bracket-expand "It{{em,alic}iz,erat}e{d,}") |
(bracket-expand "It{{em,alic}iz,erat}e{d,}") |
||
;; '("Ited" "Ite" "Itemed" "Iteme" "Italiced" "Italice" "Itized" "Itize" "Iterated" "Iterate") |
;; '("Ited" "Ite" "Itemed" "Iteme" "Italiced" "Italice" "Itized" "Itize" "Iterated" "Iterate") |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Seed7}}== |
=={{header|Seed7}}== |
||
< |
<syntaxhighlight lang=seed7>$ include "seed7_05.s7i"; |
||
const proc: expandBraces (in string: stri) is func |
const proc: expandBraces (in string: stri) is func |
||
Line 4,512: | Line 4,512: | ||
expandBraces(stri); |
expandBraces(stri); |
||
end for; |
end for; |
||
end func;</ |
end func;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,542: | Line 4,542: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang=ruby>func brace_expand (input) { |
||
var current = [''] |
var current = [''] |
||
var stack = [[current]] |
var stack = [[current]] |
||
Line 4,603: | Line 4,603: | ||
It{{em,alic}iz,erat}e{d,}, please. |
It{{em,alic}iz,erat}e{d,}, please. |
||
{,{,gotta have{ ,\, again\, }}more }cowbell! |
{,{,gotta have{ ,\, again\, }}more }cowbell! |
||
{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}</ |
{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,635: | Line 4,635: | ||
=={{header|Simula}}== |
=={{header|Simula}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=simula>CLASS ARRAYLISTS; |
||
BEGIN |
BEGIN |
||
Line 4,721: | Line 4,721: | ||
END; |
END; |
||
END;</ |
END;</syntaxhighlight><syntaxhighlight lang=simula>EXTERNAL CLASS ARRAYLISTS; |
||
ARRAYLISTS |
ARRAYLISTS |
||
BEGIN |
BEGIN |
||
Line 4,871: | Line 4,871: | ||
END |
END |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
<pre>~/{Downloads,Pictures}/*.{jpg,gif,png} |
||
Line 4,902: | Line 4,902: | ||
=={{header|Tailspin}}== |
=={{header|Tailspin}}== |
||
< |
<syntaxhighlight lang=tailspin> |
||
templates braceExpansion |
templates braceExpansion |
||
composer braceParse |
composer braceParse |
||
Line 4,936: | Line 4,936: | ||
'{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}' -> '"$;" expands to $ -> braceExpansion ... -> '$#10;$;';$#10;$#10;' -> !OUT::write |
'{}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}' -> '"$;" expands to $ -> braceExpansion ... -> '$#10;$;';$#10;$#10;' -> !OUT::write |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,968: | Line 4,968: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
{{works with|Tcl|8.6}} |
{{works with|Tcl|8.6}} |
||
< |
<syntaxhighlight lang=tcl>package require Tcl 8.6 |
||
proc combine {cases1 cases2 {insert ""}} { |
proc combine {cases1 cases2 {insert ""}} { |
||
Line 5,037: | Line 5,037: | ||
} |
} |
||
return $current |
return $current |
||
}</ |
}</syntaxhighlight> |
||
Demonstrating: |
Demonstrating: |
||
< |
<syntaxhighlight lang=tcl>foreach testcase { |
||
"~/{Downloads,Pictures}/*.{jpg,gif,png}" |
"~/{Downloads,Pictures}/*.{jpg,gif,png}" |
||
"It{{em,alic}iz,erat}e{d,}, please." |
"It{{em,alic}iz,erat}e{d,}, please." |
||
Line 5,046: | Line 5,046: | ||
} { |
} { |
||
puts $testcase\n\t[join [commatize $testcase] \n\t] |
puts $testcase\n\t[join [commatize $testcase] \n\t] |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 5,075: | Line 5,075: | ||
=={{header|Visual Basic .NET}}== |
=={{header|Visual Basic .NET}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=vbnet>Module Module1 |
||
Function GetGroup(s As String, depth As Integer) As Tuple(Of List(Of String), String) |
Function GetGroup(s As String, depth As Integer) As Tuple(Of List(Of String), String) |
||
Line 5,149: | Line 5,149: | ||
End Sub |
End Sub |
||
End Module</ |
End Module</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>It{{em,alic}iz,erat}e{d,}, please. |
<pre>It{{em,alic}iz,erat}e{d,}, please. |
||
Line 5,176: | Line 5,176: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang=ecmascript>var getGroup // forward declaration |
||
var getItem = Fn.new { |s, depth| |
var getItem = Fn.new { |s, depth| |
||
Line 5,241: | Line 5,241: | ||
for (s in getItem.call(input, 0)[0]) System.print(" " + s) |
for (s in getItem.call(input, 0)[0]) System.print(" " + s) |
||
System.print() |
System.print() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 5,274: | Line 5,274: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
This is a two pass algorithm (2*length(string)), one pass to find valid {} pairs, the next pass to expand them. |
This is a two pass algorithm (2*length(string)), one pass to find valid {} pairs, the next pass to expand them. |
||
< |
<syntaxhighlight lang=zkl>fcn eyeball(code,ps=L(),brace=False){ //-->indexes of valid braces & commas |
||
cs:=L(); |
cs:=L(); |
||
foreach c in (code){ // start fresh or continue (if recursing) |
foreach c in (code){ // start fresh or continue (if recursing) |
||
Line 5,305: | Line 5,305: | ||
} |
} |
||
strings |
strings |
||
}</ |
}</syntaxhighlight> |
||
< |
<syntaxhighlight lang=zkl>foreach bs in (T("It{{em,alic}iz,erat}e{d,}", "~/{Downloads,Pictures}/*.{jpg,gif,png}", |
||
"It{{em,alic}iz,erat}e{d,}, please.", "a{2,1}b{X,Y,X}c", 0'|a\\{\\\{b,c\,d}|, |
"It{{em,alic}iz,erat}e{d,}, please.", "a{2,1}b{X,Y,X}c", 0'|a\\{\\\{b,c\,d}|, |
||
"{a,b{c{,{d}}e}f", 0'|{,{,gotta have{ ,\, again\, }}more }cowbell!|, |
"{a,b{c{,{d}}e}f", 0'|{,{,gotta have{ ,\, again\, }}more }cowbell!|, |
||
Line 5,312: | Line 5,312: | ||
{ |
{ |
||
"%s expands to\n %s".fmt(bs,expando(bs)).println(); |
"%s expands to\n %s".fmt(bs,expando(bs)).println(); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |