brace_expansion.sf 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #!/usr/bin/ruby
  2. #
  3. ## https://rosettacode.org/wiki/Brace_expansion
  4. #
  5. func brace_expand (input) {
  6. var current = ['']
  7. var stack = [[current]]
  8. loop {
  9. var t = input.match(
  10. /\G ((?:[^\\{,}]++ | \\(?:.|\z))++ | . )/gx
  11. )[0] \\ break
  12. if (t == '{') {
  13. stack << [current = ['']]
  14. }
  15. elsif ((t == ',') && (stack.len > 1)) {
  16. stack[-1] << (current = [''])
  17. }
  18. elsif ((t == '}') && (stack.len > 1)) {
  19. var group = stack.pop
  20. current = stack[-1][-1]
  21. # handle the case of brace pairs without commas:
  22. group[0][] = group[0].map{ '{'+_+'}' }... if (group.len == 1)
  23. current[] = current.map { |c|
  24. group.map { .map { c + _ }... }...
  25. }...
  26. }
  27. else {
  28. current[] = current.map { _ + t }...
  29. }
  30. }
  31. # handle the case of missing closing braces:
  32. while (stack.len > 1) {
  33. var right = stack[-1].pop
  34. var sep = ','
  35. if (stack[-1].is_empty) {
  36. sep = '{'
  37. stack.pop
  38. }
  39. current = stack[-1][-1]
  40. current[] = current.map { |c|
  41. right.map { c + sep + _ }...
  42. }...
  43. }
  44. return current
  45. }
  46. DATA.each { |line|
  47. say line
  48. say "\t"+brace_expand(line).join("\n\t")+"\n"
  49. }
  50. __DATA__
  51. ~/{Downloads,Pictures}/*.{jpg,gif,png}
  52. It{{em,alic}iz,erat}e{d,}, please.
  53. {,{,gotta have{ ,\, again\, }}more }cowbell!
  54. {}} some }{,{\\{ edge, edge} \,}{ cases, {here} \\\\\}