EBNF: parse-h-connection [=[ letter = [a-zA-Z] dash = "-" num = [0-9]+ => [[ string>number ]] connection = letter (dash+)~ num (dash+)~ letter => [[ first3 swap [ 2array >hash-set ] dip ]] ]=] EBNF: parse-h-connections [=[ noise = (!() .)* item = line = (noise~ item)* noise~ ]=] EBNF: parse-v-connection [=[ letter = [a-zA-Z] pipe = "|" num = [0-9]+ => [[ string>number ]] connection = letter (pipe+)~ num (pipe+)~ letter => [[ first3 swap [ 2array >hash-set ] dip ]] ]=] EBNF: parse-v-connections [=[ noise = (!() .)* item = line = (noise~ item)* noise~ ]=] ! I tried to deduplicate the above, but it's just as long below: [==[ USING: hash-sets multiline kernel arrays sequences math.parser peg.ebnf ; IN: easters.good-friday EBNF: ${name} [=[ letter = [a-zA-Z] tether = "${tether}" num = [0-9]+ => [[ string>number ]] connection = letter (tether+)~ num (tether+)~ letter => [[ first3 swap [ 2array >hash-set ] dip ]] ]=] EBNF: ${name}s [=[ noise = (!() .)* item = line = (noise~ item)* noise~ ]=] ]==] [ { { "name" "parse-h-connection" } { "tether" "-" } } [ interpolate>string ] with-variables ] [ { { "name" "parse-v-connection" } { "tether" "|" } } [ interpolate>string ] with-variables ] bi [ eval( -- ) ] bi@