Annotation of 43BSD/contrib/icon/libtest/t-ll.dat, revision 1.1.1.1

1.1       root        1: #      RSG(1)
                      2: #
                      3: #      Random sentence generation
                      4: #
                      5: #      Ralph E. Griswold
                      6: #
                      7: #      Last modified 8/11/84
                      8: #
                      9: 
                     10: global defs, ifile, in, limit, tswitch, prompt
                     11: 
                     12: record nonterm(name)
                     13: record charset(chars)
                     14: record query(name)
                     15: 
                     16: procedure main(x)
                     17:    local line, plist, i, s
                     18:                                        # procedures to try on input lines
                     19:    plist := [define,generate,grammar,source,comment,prompter,error]
                     20:    defs := table()                     # table of definitions
                     21:    defs["lb"] := [["<"]]               # built-in definitions
                     22:    defs["rb"] := [[">"]]
                     23:    defs["vb"] := [["|"]]
                     24:    defs["nl"] := [["\n"]]
                     25:    defs[""] := [[""]]
                     26:    defs["&lcase"] := [[charset(&lcase)]]
                     27:    defs["&ucase"] := [[charset(&ucase)]]
                     28:    defs["&digit"] := [[charset('0123456789')]]
                     29:    i := 0
                     30:    while i < *x do {                   # process options
                     31:       s := x[i +:= 1] | break
                     32:       case s of {
                     33:          "-t":   tswitch := 1
                     34:          "-l":   limit := integer(x[i +:= 1]) | Usage()
                     35:          "-s":   &random := integer(x[i +:= 1]) | Usage()
                     36:          default:   Usage()
                     37:          }
                     38:       }
                     39:    ifile := [&input]                   # stack of input files
                     40:    prompt := ""
                     41:    while in := pop(ifile) do {         # process all files
                     42:       repeat {
                     43:          if *prompt ~= 0 then writes(prompt)
                     44:          line := read(in) | break
                     45:          while line[-1] == "\\" do line := line[1:-1] || read(in) | break
                     46:          (!plist)(line)
                     47:          }
                     48:       close(in)
                     49:       }
                     50: end
                     51: 
                     52: #  look for comment
                     53: #
                     54: procedure comment(line)
                     55:    if line[1] == "#" then return
                     56: end
                     57: 
                     58: #  look for definition
                     59: #
                     60: procedure define(line)
                     61:    return line ?
                     62:       defs[(="<",tab(find(">::=")))] := (move(4),alts(tab(0)))
                     63: end
                     64: 
                     65: #  define nonterminal
                     66: #
                     67: procedure defnon(sym)
                     68:    local chars, name
                     69:    if sym ? {
                     70:       ="'" &
                     71:       chars := cset(tab(-1)) &
                     72:       ="'"
                     73:       }
                     74:    then return charset(chars)
                     75:    else if sym ? {
                     76:       ="?" &
                     77:       name := tab(0)
                     78:       }
                     79:    then return query(name)
                     80:    else return nonterm(sym)
                     81: end
                     82: 
                     83: #  note erroneous input line
                     84: #
                     85: procedure error(line)
                     86:    write("*** erroneous line:  ",line)
                     87:    return
                     88: end
                     89: 
                     90: #  generate sentences
                     91: #
                     92: procedure gener(goal)
                     93:    local pending, genstr, symbol
                     94:    repeat {
                     95:       pending := [nonterm(goal)]
                     96:       genstr := ""
                     97:       while symbol := get(pending) do {
                     98:          if \tswitch then
                     99:             write(&errout,genstr,symimage(symbol),listimage(pending))
                    100:          case type(symbol) of {
                    101:             "string":   genstr ||:= symbol
                    102:             "charset":  genstr ||:= ?symbol.chars
                    103:            "query":    {
                    104:                writes("*** supply string for ",symbol.name,"  ")
                    105:                genstr ||:= read() | {
                    106:                   write(&errout,"*** no value for query to ",symbol.name)
                    107:                   suspend genstr
                    108:                   break next
                    109:                   }
                    110:                }
                    111:             "nonterm":  {
                    112:                pending := ?\defs[symbol.name] ||| pending | {
                    113:                   write(&errout,"*** undefined nonterminal:  <",symbol.name,">")
                    114:                   suspend genstr
                    115:                   break next
                    116:                   }
                    117:                if *pending > \limit then {
                    118:                   write(&errout,"*** excessive symbols remaining")
                    119:                   suspend genstr
                    120:                   break next
                    121:                   }
                    122:                }
                    123:             }
                    124:          }
                    125:       suspend genstr
                    126:       }
                    127: end
                    128: 
                    129: #  look for generation specification
                    130: #
                    131: procedure generate(line)
                    132:    local goal, count
                    133:    if line ? {
                    134:       ="<" &
                    135:       goal := tab(upto('>')) \ 1 &
                    136:       move(1) &
                    137:       count := (pos(0) & 1) | integer(tab(0))
                    138:       }
                    139:    then {
                    140:       every write(gener(goal)) \ count
                    141:       return
                    142:       }
                    143:    else fail
                    144: end
                    145: 
                    146: #  get right hand side of production
                    147: #
                    148: procedure getrhs(a)
                    149:    local rhs
                    150:    rhs := ""
                    151:    every rhs ||:= listimage(!a) || "|"
                    152:    return rhs[1:-1]
                    153: end
                    154: 
                    155: #  look for request to write out grammar
                    156: #
                    157: procedure grammar(line)
                    158:    local file, out, name
                    159:    if line ? {
                    160:       name := tab(find("->")) &
                    161:       move(2) &
                    162:       file := tab(0) &
                    163:       out := if *file = 0 then &output else {
                    164:          open(file,"w") | {
                    165:             write(&errout,"*** cannot open ",file)
                    166:             fail
                    167:             }
                    168:          }
                    169:       }
                    170:    then {
                    171:       (*name = 0) | (name[1] == "<" & name[-1] == ">") | fail
                    172:       pwrite(name,out)
                    173:       if *file ~= 0 then close(out)
                    174:       return
                    175:       }
                    176:    else fail
                    177: end
                    178: 
                    179: #  produce image of list of grammar symbols
                    180: #
                    181: procedure listimage(a)
                    182:    local s, x
                    183:    s := ""
                    184:    every x := !a do
                    185:       s ||:= symimage(x)
                    186:    return s
                    187: end
                    188: 
                    189: #  process alternatives
                    190: #
                    191: procedure alts(defn)
                    192:    local alist
                    193:    alist := []
                    194:    defn ? while put(alist,syms(tab(many(~'|')))) do move(1)
                    195:    return alist
                    196: end
                    197: 
                    198: #  look for new prompt symbol
                    199: #
                    200: procedure prompter(line)
                    201:    if line[1] == "=" then {
                    202:       prompt := line[2:0]
                    203:       return
                    204:       }
                    205: end
                    206: 
                    207: #  write out grammar
                    208: #
                    209: procedure pwrite(name,ofile)
                    210:    local nt, a
                    211:    static builtin
                    212:    initial builtin := ["lb","rb","vb","nl","","&lcase","&ucase","&digit"]
                    213:    if *name = 0 then {
                    214:       a := sort(defs)
                    215:       every nt := !a do {
                    216:          if nt[1] == !builtin then next
                    217:          write(ofile,"<",nt[1],">::=",getrhs(nt[2]))
                    218:          }
                    219:       }
                    220:    else write(ofile,name,"::=",getrhs(\defs[name[2:-1]])) |
                    221:       write("*** undefined nonterminal:  ",name)
                    222: end
                    223: 
                    224: #  look for file with input
                    225: #
                    226: procedure source(line)
                    227:    local file
                    228:    return line ? (="@" & push(ifile,in) & {
                    229:       in := open(file := tab(0)) | {
                    230:          write(&errout,"*** cannot open ",file)
                    231:          fail
                    232:          }
                    233:       })
                    234: end
                    235: 
                    236: #  produce string image of grammar symbol
                    237: #
                    238: procedure symimage(x)
                    239:    return case type(x) of {
                    240:       "string":   x
                    241:       "nonterm":  "<" || x.name || ">"
                    242:       "charset":  "<'" || x.chars || "'>"
                    243:       }
                    244: end
                    245: 
                    246: #  process the symbols in an alternative
                    247: #
                    248: procedure syms(alt)
                    249:    local slist
                    250:    slist := []
                    251:    alt ? while put(slist,tab(many(~'<')) |
                    252:       defnon(2(="<",tab(upto('>')),move(1))))
                    253:    return slist
                    254: end
                    255: 
                    256: #  stop noting incorrect usage
                    257: #
                    258: procedure Usage()
                    259:    stop("usage:  [-t] [-l n] [-s n]")
                    260: end

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.