############################################################################ # # File: parens.icn # # Subject: Program to produce random balanced strings # # Author: Ralph E. Griswold # # Date: March 26, 2002 # ############################################################################ # # This file is in the public domain. # ############################################################################ # # This program produces parenthesis-balanced strings in which # the parentheses are randomly distributed. # # Options: The following options are available: # # -b n Bound the length of the strings to n left and right # parentheses each. The default is 10. # # -n n Produce n strings. The default is 10. # # -l s Use the string s for the left parenthesis. The default # is ( . # # -r s Use the string s for the right parenthesis. The default # is ) . # # -v Randomly vary the length of the strings between 0 and # the bound. In the absence of this option, all strings # are the exactly as long as the specified bound. # # For example, the output for # # parens -v -b 4 -l "begin " -r "end " # # is # # begin end # begin end begin end # begin begin end end begin end # begin end begin begin end end # begin end # begin begin end end # begin begin begin end end end # begin end begin begin end end # begin end begin end # begin begin end begin end begin end end # # # Comments: This program was motivated by the need for test data # for error repair schemes for block-structured programming lan- # guages. A useful extension to this program would be some # way of generating other text among the parentheses. In addition # to the intended use of the program, it can produce a variety of # interesting patterns, depending on the strings specified by -l # and -r. # ############################################################################ # # Links: options, random # ############################################################################ link options link random global r, k, lp, rp procedure main(args) local string, i, s, bound, limit, varying, opts randomize() bound := limit := 10 # default bound and limit lp := "(" # default left paren rp := ")" # default right paren opts := options(args,"l:r:vb+n+") bound := \opts["b"] | 10 limit := \opts["n"] | 10 lp := \opts["l"] | "(" rp := \opts["r"] | ")" varying := opts["v"] every 1 to limit do { if \varying then k := 2 * ?bound else k := 2 * bound string := "" r := 0 while k ~= r do { if r = 0 then string ||:= Open() else if ?0 < probClose() then string ||:= Close() else string ||:= Open() } while k > 0 do string ||:= Close() write(string) } end procedure Open() r +:= 1 k -:= 1 return lp end procedure Close() r -:= 1 k -:= 1 return rp end procedure probClose() return ((r * (r + k + 2)) / (2.0 * k * (r + 1))) end