Description
  • A parenthesis-enclosed list contains one or more members separated by commas.
  • A member of a list can be another list.
  • There may be more than one list in a line.
  • Each parenthesis is assigned a `depth' according to the following rules:
    • If a opening parenthesis is not enclosed by another, its depth is one.
    • The depth of a opening parenthesis is one plus the depth of the nearest opening one enclosing it.
    • Since parentheses are paired, the depth of a closing parenthesis is the same as the corresponding opening one.
  • We want to remove all parentheses whose depth is not maximum.
Raw Input
A1 (B2,(C3,(D4,E5),(F6))) G6 (H7,(I7,(J8,K9)),L0)
Desired Output
A1 B2,C3,(D4,E5),(F6) G6 H7,I7,(J8,K9),L0
Script and Comments
Script1
[ 1] :loop0
[ 2] s/\(.*/\n&\n/
[ 3] /\n/!b
[ 4] :loop1
[ 5] /\n\(/s/$/#/
[ 6] /\n[()].*\n#$/s/\n/\n\n/
[ 7] /\n\)/s/#$//
[ 8] s/\n([()][^()\n]*)/\1\n/
[ 9] /^([^\n]*\n){3}/s/\n[()]//
[10] /\n\n/!b loop1
[11] s/\n\n//
[12] /^([^()]*\([^()]*\))*[^()]*$/!b loop0
Comments
  1. The `-r' option of GNU sed must be used to interpret REs as EREs.
  2. We need a counter to determine the depth of a given parenthesis where `#'s are used to keep the value of the counter.
  3. Each line is scanned from left to right several times where N-th scan removes parentheses of depth N.
  4. Newline characters are used
    • to separate the contents of a line and the counter.
    • as a mark to indicate the parenthesis to be examined in a loop1 iteration.
  5. In each iteration of loop1:
    • Step [5]: increases the counter by one if the parenthesis is an opening one.
    • Step [6]: inserts another newline before a parenthesis of depth 1.
    • Step [7]: decreases the counter by one if the parenthesis is a closing one.
    • Step [8]: moves the mark to the next parenthesis, but can not move across another newline which separates the contents and the counter.
    • Step [9]: if the Pattern Space contains 3 newlines, the leftmost one was inserted by Step [6], which is followed by a depth-1 parenthesis to be removed by this step.
    • Step [10]: if there are parentheses not examined, jumps to Step [4].
  6. Step [12]: if there are parentheses enclosed by other parentheses, i.e., whose depth are greater than one, jumps to Step [1].