Annotation of 43BSD/contrib/icon/port/rsg.icn, revision 1.1

1.1     ! root        1: #  This program generates randomly selected sentences from
        !             2: #  user-specified grammars.  It is an extension of a program
        !             3: #  given in Chapter 20 of the Icon book and is included in
        !             4: #  the Icon program library.
        !             5: 
        !             6: global defs, ifile, in, limit, tswitch, prompt
        !             7: record nonterm(name)
        !             8: record charset(chars)
        !             9: record query(name)
        !            10: procedure main(x)
        !            11:    local line, plist
        !            12:    plist := [define,generate,grammar,source,comment,prompter,error]
        !            13:    defs := table()
        !            14:    defs["lb"] := [["<"]]
        !            15:    defs["rb"] := [[">"]]
        !            16:    defs["vb"] := [["|"]]
        !            17:    defs["nl"] := [["\n"]]
        !            18:    defs[""] := [[""]]
        !            19:    defs["&lcase"] := [[charset(&lcase)]]
        !            20:    defs["&ucase"] := [[charset(&ucase)]]
        !            21:    defs["&digit"] := [[charset('0123456789')]]
        !            22:    i := 0
        !            23:    while i < *x do {
        !            24:       s := x[i +:= 1] | break
        !            25:       case s of {
        !            26:          "-t":   tswitch := 1
        !            27:          "-l":   limit := integer(x[i +:= 1]) | stop("usage: [-t] [-l n]")
        !            28:          default:   stop("usage: [-t] [-l n]")
        !            29:          }
        !            30:       }
        !            31:    ifile := [&input]
        !            32:    prompt := ""
        !            33:    while in := pop(ifile) do {
        !            34:       repeat {
        !            35:          if *prompt ~= 0 then writes(prompt)
        !            36:          line := read(in) | break
        !            37:          while line[-1] == "\\" do line := line[1:-1] || read(in) | break
        !            38:          (!plist)(line)
        !            39:          }
        !            40:       close(in)
        !            41:       }
        !            42: end
        !            43: 
        !            44: procedure comment(line)
        !            45:    if line[1] == "#" then return
        !            46: end
        !            47: 
        !            48: procedure define(line)
        !            49:    return line ?
        !            50:       defs[(="<",tab(find(">::=")))] := (move(4),alts(tab(0)))
        !            51: end
        !            52: 
        !            53: procedure defnon(sym)
        !            54:    if sym ? {
        !            55:       ="'" &
        !            56:       chars := cset(tab(-1)) &
        !            57:       ="'"
        !            58:       }
        !            59:    then return charset(chars)
        !            60:    else if sym ? {
        !            61:       ="?" &
        !            62:       name := tab(0)
        !            63:       }
        !            64:    then return query(name)
        !            65:    else return nonterm(sym)
        !            66: end
        !            67: 
        !            68: procedure error(line)
        !            69:    write("*** erroneous line:  ",line)
        !            70:    return
        !            71: end
        !            72: 
        !            73: procedure gener(goal)
        !            74:    local pending, genstr, symbol
        !            75:    repeat {
        !            76:       pending := [nonterm(goal)]
        !            77:       genstr := ""
        !            78:       while symbol := get(pending) do {
        !            79:          if \tswitch then write(&errout,genstr,symimage(symbol),listimage(pending))
        !            80:          case type(symbol) of {
        !            81:             "string":   genstr ||:= symbol
        !            82:             "charset":  genstr ||:= ?symbol.chars
        !            83:            "query":    {
        !            84:                writes("*** supply string for ",symbol.name,"  ")
        !            85:                genstr ||:= read() | {
        !            86:                   write(&errout,"*** no value for query to ",symbol.name)
        !            87:                   suspend genstr
        !            88:                   break next
        !            89:                   }
        !            90:                }
        !            91:             "nonterm":  {
        !            92:                pending := ?\defs[symbol.name] ||| pending | {
        !            93:                   write(&errout,"*** undefined nonterminal:  <",symbol.name,">")
        !            94:                   suspend genstr
        !            95:                   break next
        !            96:                   }
        !            97:                if *pending > \limit then {
        !            98:                   write(&errout,"*** excessive symbols remaining")
        !            99:                   suspend genstr
        !           100:                   break next
        !           101:                   }
        !           102:                }
        !           103:             }
        !           104:          }
        !           105:       suspend genstr
        !           106:       }
        !           107: end
        !           108: 
        !           109: procedure generate(line)
        !           110:    local goal, count
        !           111:    if line ? {
        !           112:       ="<" &
        !           113:       goal := tab(upto('>')) \ 1 &
        !           114:       move(1) &
        !           115:       count := (pos(0) & 1) | integer(tab(0))
        !           116:       }
        !           117:    then {
        !           118:       every write(gener(goal)) \ count
        !           119:       return
        !           120:       }
        !           121:    else fail
        !           122: end
        !           123: 
        !           124: procedure getrhs(a)
        !           125:    local rhs
        !           126:    rhs := ""
        !           127:    every rhs ||:= sform(!a) || "|"
        !           128:    return rhs[1:-1]
        !           129: end
        !           130: 
        !           131: procedure grammar(line)
        !           132:    local file, out
        !           133:    if line ? {
        !           134:       name := tab(find("->")) &
        !           135:       move(2) &
        !           136:       file := tab(0) &
        !           137:       out := if *file = 0 then &output else {
        !           138:          open(file,"w") | {
        !           139:             write(&errout,"*** cannot open ",file)
        !           140:             fail
        !           141:             }
        !           142:          }
        !           143:       }
        !           144:    then {
        !           145:       (*name = 0) | (name[1] == "<" & name[-1] == ">") | fail
        !           146:       pwrite(name,out)
        !           147:       if *file ~= 0 then close(out)
        !           148:       return
        !           149:       }
        !           150:    else fail
        !           151: end
        !           152: 
        !           153: procedure listimage(a)
        !           154:    local s, x
        !           155:    s := ""
        !           156:    every x := !a do
        !           157:       s ||:= symimage(x)
        !           158:    return s
        !           159: end
        !           160: 
        !           161: procedure alts(defn)
        !           162:    local alist
        !           163:    alist := []
        !           164:    defn ? while put(alist,syms(tab(many(~'|')))) do move(1)
        !           165:    return alist
        !           166: end
        !           167: 
        !           168: procedure prompter(line)
        !           169:    if line[1] == "=" then {
        !           170:       prompt := line[2:0]
        !           171:       return
        !           172:       }
        !           173: end
        !           174: 
        !           175: procedure pwrite(name,ofile)
        !           176:    local nt, a
        !           177:    static builtin
        !           178:    initial builtin := ["lb","rb","vb","nl","","&lcase","&ucase","&digit"]
        !           179:    if *name = 0 then {
        !           180:       a := sort(defs)
        !           181:       every nt := !a do {
        !           182:          if nt[1] == !builtin then next
        !           183:          write(ofile,"<",nt[1],">::=",getrhs(nt[2]))
        !           184:          }
        !           185:       }
        !           186:    else write(ofile,name,"::=",getrhs(\defs[name[2:-1]])) |
        !           187:       write("*** undefined nonterminal:  ",name)
        !           188: end
        !           189: 
        !           190: procedure sform(alt)
        !           191:    local s, x
        !           192:    s := ""
        !           193:    every x := !alt do
        !           194:       s ||:= case type(x) of {
        !           195:          "string":  x
        !           196:          "nonterm": "<" || x.name || ">"
        !           197:          "charset": "<'" || x.chars || "'>"
        !           198:          }
        !           199:    return s
        !           200: end
        !           201: 
        !           202: procedure source(line)
        !           203:    return line ? (="@" & push(ifile,in) & {
        !           204:       in := open(file := tab(0)) | {
        !           205:          write(&errout,"*** cannot open ",file)
        !           206:          fail
        !           207:          }
        !           208:       })
        !           209: end
        !           210: 
        !           211: procedure symimage(x)
        !           212:    return case type(x) of {
        !           213:       "string":   x
        !           214:       "nonterm":  "<" || x.name || ">"
        !           215:       "charset":  "<'" || x.chars || "'>"
        !           216:       }
        !           217: end
        !           218: 
        !           219: procedure syms(alt)
        !           220:    local slist
        !           221:    slist := []
        !           222:    alt ? while put(slist,tab(many(~'<')) |
        !           223:       defnon(2(="<",tab(upto('>')),move(1))))
        !           224:    return slist
        !           225: end
        !           226: 

unix.superglobalmegacorp.com

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