home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume38 / ibpag2 / part05 < prev    next >
Encoding:
Text File  |  1993-07-12  |  27.6 KB  |  972 lines

  1. Newsgroups: comp.sources.misc
  2. From: goer@midway.uchicago.edu (Richard L. Goerwitz)
  3. Subject: v38i049:  ibpag2 - Icon-Based Parser Generator, Part05/05
  4. Message-ID: <1993Jul13.044510.17324@sparky.sterling.com>
  5. X-Md4-Signature: 0f43d1c51d8d78bfad1938f6ba3bfd09
  6. Sender: kent@sparky.sterling.com (Kent Landfield)
  7. Organization: University of Chicago
  8. Date: Tue, 13 Jul 1993 04:45:10 GMT
  9. Approved: kent@sparky.sterling.com
  10.  
  11. Submitted-by: goer@midway.uchicago.edu (Richard L. Goerwitz)
  12. Posting-number: Volume 38, Issue 49
  13. Archive-name: ibpag2/part05
  14. Environment: Icon
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  Makefile.dist beta2ref.ibp ibwriter.icn iohno.icn
  21. #   outbits.icn sample.ibp shrnktbl.icn slshupto.icn
  22. # Wrapped by kent@sparky on Sun Jul 11 18:51:51 1993
  23. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  24. echo If this archive is complete, you will see the following message:
  25. echo '          "shar: End of archive 5 (of 5)."'
  26. if test -f 'Makefile.dist' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'Makefile.dist'\"
  28. else
  29.   echo shar: Extracting \"'Makefile.dist'\" \(2833 characters\)
  30.   sed "s/^X//" >'Makefile.dist' <<'END_OF_FILE'
  31. X##########################################################################
  32. X#
  33. X   PROGNAME = ibpag2
  34. X#
  35. X##########################################################################
  36. X#
  37. X#  User-modifiable section.  Read carefully!  You will almost
  38. X#  certainly have to change some settings here.
  39. X#
  40. X
  41. X#
  42. X# Destination directory for binaries files.  Owner and group for
  43. X# public executables.  Leave the trailing slash off of directory
  44. X# names.
  45. X#
  46. XOWNER = richard # root
  47. XGROUP = group   # root
  48. XDESTDIR = /usr/local/bin
  49. X# Put this path into your LPATH variable (on which, see the Icon
  50. X# documentation).  Make sure that the directory exists.
  51. XLIBDIR = /usr/local/lib/icon/data
  52. X
  53. X#
  54. X# Name of your icon compiler and compiler flags.
  55. X#
  56. XICONC = /usr/icon/v8/bin/icont
  57. XIFLAGS = -u #-Sc 400 -Sg 400 -Si 2000 -Sn 4000 -SF 40
  58. X
  59. XSHELL = /bin/sh
  60. XSHAR = /usr/local/bin/shar
  61. XCOMPRESS = /usr/bin/compress
  62. X# COMPRESS = /usr/local/bin/gzip
  63. X
  64. X###########################################################################
  65. X#
  66. X#  Don't change anything below this line unless you're really sure of
  67. X#  what you're doing.
  68. X#
  69. X
  70. XAUX = slshupto.icn rewrap.icn outbits.icn
  71. XSRC = $(PROGNAME).icn $(AUX) slrtbls.icn slritems.icn follow.icn \
  72. X    ibutil.icn iohno.icn ibreader.icn ibtokens.icn ibwriter.icn \
  73. X    shrnktbl.icn version.icn
  74. XPARSER = iiparse.lib
  75. XGLRPARSER = iiglrpar.lib
  76. XSHARFILES = $(SRC) $(PARSER) $(GLRPARSER) sample.ibp beta2ref.ibp \
  77. X    iacc.ibp Makefile.dist README
  78. X
  79. Xall: $(PROGNAME)
  80. X
  81. X$(PROGNAME): $(SRC)
  82. X    $(ICONC) $(IFLAGS) -o $(PROGNAME) $(SRC)
  83. X
  84. X
  85. X##########################################################################
  86. X#
  87. X#  Pseudo-target names (shar, install, clean, clobber)
  88. X#
  89. X
  90. X#
  91. X# Assumes you have a shar program like mine.
  92. X#
  93. Xshar: $(SHARFILES)
  94. X    @echo ""
  95. X    @echo "Removing any old shars in this directory."
  96. X    @echo ""
  97. X    -rm -f $(PROGNAME).[0-9][0-9].Z
  98. X    @echo ""
  99. X    $(SHAR) -fVc -o$(PROGNAME) -L32 $(SHARFILES)
  100. X    $(COMPRESS) -f $(PROGNAME).[0-9][0-9]
  101. X    @echo ""
  102. X    @echo "Shell archive finished."
  103. X    @echo ""
  104. X
  105. X# Pessimistic assumptions regarding the environment (in particular,
  106. X# I don't assume you have the BSD "install" shell script).
  107. Xinstall: all
  108. X    @echo ""
  109. X    -test -d $(DESTDIR) || mkdir $(DESTDIR) && chmod 755 $(DESTDIR)
  110. X    cp $(PROGNAME) $(DESTDIR)/$(PROGNAME)
  111. X    -chgrp $(GROUP) $(DESTDIR)/$(PROGNAME)
  112. X    -chown $(OWNER) $(DESTDIR)/$(PROGNAME)
  113. X    -chmod 755 $(DESTDIR)/$(PROGNAME)
  114. X    -test -d $(LIBDIR) || mkdir $(LIBDIR) && chmod 755 $(LIBDIR)
  115. X    cp $(PARSER) $(LIBDIR)/$(PARSER)
  116. X    cp $(GLRPARSER) $(LIBDIR)/$(GLRPARSER)
  117. X    -chgrp $(GROUP) $(LIBDIR)/$(PARSER)
  118. X    -chown $(OWNER) $(LIBDIR)/$(PARSER)
  119. X    -chgrp $(GROUP) $(LIBDIR)/$(GLRPARSER)
  120. X    -chown $(OWNER) $(LIBDIR)/$(GLRPARSER)
  121. X    -chmod 644 $(LIBDIR)/$(PARSER)
  122. X    -chmod 644 $(LIBDIR)/$(GLRPARSER)
  123. X    @echo ""
  124. X    @echo "Done installing."
  125. X    @echo ""
  126. X
  127. X#
  128. X# Cleanup
  129. X#
  130. Xclean:
  131. X    -rm -f *~ #*# core *.u[12] $(PROGNAME).output
  132. Xclobber: clean
  133. X    -rm $(PROGNAME)
  134. END_OF_FILE
  135.   if test 2833 -ne `wc -c <'Makefile.dist'`; then
  136.     echo shar: \"'Makefile.dist'\" unpacked with wrong size!
  137.   fi
  138.   # end of 'Makefile.dist'
  139. fi
  140. if test -f 'beta2ref.ibp' -a "${1}" != "-c" ; then 
  141.   echo shar: Will not clobber existing file \"'beta2ref.ibp'\"
  142. else
  143.   echo shar: Extracting \"'beta2ref.ibp'\" \(2441 characters\)
  144.   sed "s/^X//" >'beta2ref.ibp' <<'END_OF_FILE'
  145. X#
  146. X# Ibpag2 source file for OT betacode-to-English converter.
  147. X#
  148. X# "Betacode" is the name used for the markers that the Thesaurus
  149. X# Linguae Graecae uses to segment texts into works, books, chapters,
  150. X# verses, etc.  The Michigan-Claremont scan of the Hebrew OT (BHS)
  151. X# uses a subset of the betacode "language."  This file contains a
  152. X# parser for that language that converts it into human readable form.
  153. X#
  154. X# Reads the standard input.  Sends the original text, with betacode
  155. X# markers converted to human-readable form, to the standard output.
  156. X#
  157. X
  158. X%{
  159. X
  160. X# These need to be global, because all of the actions modify them.
  161. X# Remember that the default scope for a variable used in an action is
  162. X# that action.
  163. X#
  164. Xglobal betavals, blev
  165. X
  166. X%}
  167. X
  168. X%token INTVAL, STRVAL, LINE
  169. X
  170. X%%
  171. X
  172. Xbetalines    : betalines, betaline
  173. X        | epsilon
  174. X        ;
  175. X
  176. Xbetaline    : '~', cvalue, xvalue, yvalue, '\n'
  177. X                    { if integer(betavals[2]) then {
  178. X                          write(betavals[1], " ",
  179. X                            betavals[2], ":",
  180. X                            betavals[3])
  181. X                      }
  182. X                      blev := 4 # global
  183. X                    }
  184. X        | LINE, '\n'        { write($1) }
  185. X        ;
  186. X
  187. Xcvalue        : 'a', value, 'b', value, 'c', value
  188. X                    { betavals[blev := 1] := $6 }
  189. X        | 'c', value        { betavals[blev := 1] := $2 }
  190. X        | epsilon
  191. X        ;
  192. X
  193. Xxvalue        : 'x', value        { betavals[blev := 2] := $2 }
  194. X        | 'x'            { if integer(betavals[2])
  195. X                      then betavals[blev := 2] +:= 1
  196. X                      else betavals[blev := 2]  := 1
  197. X                    }
  198. X        | epsilon        { if blev < 2 then
  199. X                          betavals[2] := 1
  200. X                    }
  201. X        ;
  202. X
  203. Xyvalue        : 'y', value        { betavals[blev := 3] := $2 }
  204. X        | 'y'            { betavals[blev := 3] +:= 1 }
  205. X        | epsilon        { if blev < 3 then
  206. X                          betavals[3] := 1
  207. X                    }
  208. X        ;
  209. X
  210. Xvalue        : INTVAL        { return $1 }
  211. X        | STRVAL        { return $1 }
  212. X        ;
  213. X
  214. X
  215. X%%
  216. X
  217. X
  218. Xprocedure iilex(infile)
  219. X
  220. X    local line
  221. X    # betavals is global
  222. X    initial betavals := ["", 0, 0]
  223. X
  224. X    while line := read(infile) do {
  225. X    line ? {
  226. X        if ="~" then {
  227. X        suspend ord("~")
  228. X        until pos(0) do {
  229. X            case move(1) of {
  230. X            "a"     : suspend ord("a")
  231. X            "b"     : suspend ord("b")
  232. X            "c"     : suspend ord("c")
  233. X            "x"     : suspend ord("x")
  234. X            "y"     : suspend ord("y")
  235. X            default : stop("betacode error:  ", line)
  236. X            }
  237. X            if ="\"" then {
  238. X            iilval := tab(find("\""))
  239. X            suspend STRVAL
  240. X            move(1)
  241. X            } else {
  242. X            if iilval := integer(tab(many(&digits)))
  243. X            then suspend INTVAL
  244. X            }
  245. X        }
  246. X        suspend ord("\n")
  247. X        }
  248. X        else {
  249. X        iilval := line
  250. X        suspend LINE
  251. X        suspend ord("\n")
  252. X        }
  253. X    }
  254. X    }
  255. X
  256. Xend
  257. X
  258. X
  259. Xprocedure main()
  260. X    return iiparse(&input)
  261. Xend
  262. END_OF_FILE
  263.   if test 2441 -ne `wc -c <'beta2ref.ibp'`; then
  264.     echo shar: \"'beta2ref.ibp'\" unpacked with wrong size!
  265.   fi
  266.   # end of 'beta2ref.ibp'
  267. fi
  268. if test -f 'ibwriter.icn' -a "${1}" != "-c" ; then 
  269.   echo shar: Will not clobber existing file \"'ibwriter.icn'\"
  270. else
  271.   echo shar: Extracting \"'ibwriter.icn'\" \(3586 characters\)
  272.   sed "s/^X//" >'ibwriter.icn' <<'END_OF_FILE'
  273. X############################################################################
  274. X#
  275. X#    Name:     ibwriter.icn
  276. X#
  277. X#    Title:     Ibpag2 parser/library writer
  278. X#
  279. X#    Author:     Richard L. Goerwitz
  280. X#
  281. X#    Version: 1.5
  282. X#
  283. X############################################################################
  284. X#
  285. X#  Given a grammar, an action table, a goto table, an open output
  286. X#  file, an open iiparser file, and a module name, sends to the output
  287. X#  file a fully loaded LR parser with run-time constructible action
  288. X#  and goto tables.  The iiparser file contains the base LR parser
  289. X#  that the output file uses.
  290. X#
  291. X############################################################################
  292. X#
  293. X#  Links: ibtokens, ximage
  294. X#
  295. X#  See also: iiparse.icn
  296. X#
  297. X############################################################################
  298. X
  299. X#link ibtokens, ximage
  300. Xlink ximage
  301. X
  302. X# defined in ibtokens.icn
  303. X# record ib_TOK(sym, str)
  304. X
  305. Xprocedure ibwriter(iiparse_file, outfile, grammar, atbl, gtbl, module)
  306. X
  307. X    local token, next_token, start_symbol, rule_list, ttbl
  308. X
  309. X    /module      := ""
  310. X    start_symbol := grammar.start
  311. X    rule_list    := grammar.rules
  312. X    ttbl         := grammar.tbl
  313. X    next_token   := create ibtokens(iiparse_file)
  314. X
  315. X    #
  316. X    # Copy tokens in iiparse_file to outfile.  Whenever we find a $
  317. X    # (RHSARG), process: If we find $$, output $; If we find $module,
  318. X    # output image(module); and other such stuff.  Note that
  319. X    # copy_iiparse_tokens suspends tokens before writing them.  It
  320. X    # also blocks writing of any token whose sym field matches the
  321. X    # string given as arg 3.
  322. X    #
  323. X    every token := copy_iiparse_tokens(next_token, outfile, "RHSARG")
  324. X    do {
  325. X    if token.sym == "RHSARG" then {
  326. X        if (token := @next_token).sym == "RHSARG" then {
  327. X        writes(outfile, token.str)
  328. X        next
  329. X        }
  330. X        token.sym == "IDENT" | iohno(60, "line "|| line_number)
  331. X        writes(outfile, " ")
  332. X        case token.str of {
  333. X        # copy $module name over as a literal
  334. X        "module"              : writes(outfile, image(module))
  335. X        # use ximage to copy over action, goto, and token tables,
  336. X        # as well as the production list (used only for debugging)
  337. X        "atbl_insertion_point": writes(outfile, ximage(atbl)) 
  338. X        "gtbl_insertion_point": writes(outfile, ximage(gtbl))
  339. X        "ttbl_insertion_point": writes(outfile, ximage(ttbl))
  340. X        "rule_list_insertion_point"    :
  341. X            writes(outfile, ximage(rule_list))
  342. X        # use image to copy the start symbol into the output file
  343. X        "start_symbol_insertion_point" :
  344. X            writes(outfile, image(start_symbol))
  345. X        # add the module name to anything else beginning with $
  346. X        default               : writes(outfile, token.str, module, " ")
  347. X        }
  348. X    }
  349. X    }
  350. X
  351. X    return
  352. X
  353. Xend
  354. X
  355. X
  356. X#
  357. X# copy_iiparse_tokens:  coexpression x file x string  -> ib_TOK records
  358. X#                       (next_token,   out,   except) -> token records
  359. X#
  360. X#     Copy Icon code to output stream, also suspending as we go.
  361. X#     Insert separators between tokens where needed.  Do not output
  362. X#     any token whose sym field matches except.  The point in
  363. X#     suspending tokens as we go is to enable the calling procedure to
  364. X#     look for signal tokens that indicate insertion or termination
  365. X#     points.  Fail on EOF.
  366. X#
  367. Xprocedure copy_iiparse_tokens(next_token, out, except)
  368. X
  369. X    local separator, T
  370. X
  371. X    separator := ""
  372. X    while T := @next_token do {
  373. X    if \T.sym then suspend T
  374. X    if \T.sym == \except then next
  375. X    if any(&digits ++ &letters ++ '_.', \T.str, 1, 2) & \T.sym ~== "DOT"
  376. X    then writes(out, separator)
  377. X    writes(out, T.str)
  378. X    if any(&digits ++ &letters ++ '_.', \T.str, -1, 0) & \T.sym ~== "DOT"
  379. X    then separator := " " else separator := ""
  380. X    }
  381. X
  382. Xend
  383. END_OF_FILE
  384.   if test 3586 -ne `wc -c <'ibwriter.icn'`; then
  385.     echo shar: \"'ibwriter.icn'\" unpacked with wrong size!
  386.   fi
  387.   # end of 'ibwriter.icn'
  388. fi
  389. if test -f 'iohno.icn' -a "${1}" != "-c" ; then 
  390.   echo shar: Will not clobber existing file \"'iohno.icn'\"
  391. else
  392.   echo shar: Extracting \"'iohno.icn'\" \(2908 characters\)
  393.   sed "s/^X//" >'iohno.icn' <<'END_OF_FILE'
  394. X############################################################################
  395. X#
  396. X#    Name:     iohno.icn
  397. X#
  398. X#    Title:     iohno (error handler, with hard-coded messages)
  399. X#
  400. X#    Author:     Richard L. Goerwitz
  401. X#
  402. X#    Version: 1.20
  403. X#
  404. X############################################################################
  405. X#
  406. X#  This file contains iohno(n, s) - an error handler taking two
  407. X#  arguments: 1) an integer and 2) a string.  The string (2) is an
  408. X#  optional error message.  The integer (1) is one of several
  409. X#  hard-coded error numbers (see below).
  410. X#
  411. X############################################################################
  412. X#
  413. X#  Links: rewrap
  414. X#
  415. X############################################################################
  416. X
  417. X#
  418. X# iohno:  print error message s to stderr; abort with exit status n
  419. X#
  420. Xprocedure iohno(n, s)
  421. X
  422. X    local i, msg
  423. X    static errlist
  424. X    initial {
  425. X        errlist := [[100, "unspecified failure"],
  426. X
  427. X            [2,   "can't find iiparse.lib file"],
  428. X
  429. X            [4,   "unexpected EOF"],
  430. X            [5,   "unknown associativity value"],
  431. X
  432. X                    [11,  "malformed right-hand side"],
  433. X                    [12,  "unexpected RHS symbol type"],
  434. X
  435. X                    [21,  "malformed left-hand side"],
  436. X            
  437. X            [30,  "unknown or unimplemented % declaration"],
  438. X            [31,  "malformed token declaration"],
  439. X            [32,  "start symbol redefined"],
  440. X            [33,  "LHS symbol expected"],
  441. X            [34,  "colon missing"],
  442. X            [35,  "malformed RHS in rule declaration"],
  443. X            [36,  "undeclared character literal"],
  444. X            [37,  "illegal $integer reference"],
  445. X            [38,  "out-of-range $reference"],
  446. X            [39,  "unterminated brace { in action"],
  447. X            [43,  "bogus precedence"],
  448. X            [44,  "superfluous epsilon"],
  449. X            [45,  "superfluous %union declaration"],
  450. X            [47,  "empty or missing rules section"],
  451. X            [48,  "garbled declarations section"],
  452. X            [49,  "multiple characters within quotes"],
  453. X
  454. X            [40,  "same prec, different (or perhaps lacking) assoc"],
  455. X            [41,  "conflict between nonassociative rules"],
  456. X            [42,  "reduce -- reduce conflict"],
  457. X            [46,  "unresolvable shift/reduce conflict"],
  458. X
  459. X            [50,  "illegal conflict for nonassociative rules"],
  460. X            [51,  "reduce/reduce conflict"],
  461. X            [52,  "nonterminal useless and/or declared as a terminal"],
  462. X
  463. X            [60,  "malformed $insertion point in iiparse file"],
  464. X
  465. X            [70,  "bad action format"],
  466. X            [71,  "nonexistent rule number specified in old action"],
  467. X            [72,  "nonexistent rule number specified in new action"],
  468. X
  469. X            [80,  "conflict in goto table"],
  470. X
  471. X            [90,  "RHS nonterminal appears in no LHS"],
  472. X            [91,  "useless nonterminal"]
  473. X            ]
  474. X    }
  475. X
  476. X    /n := 0
  477. X    every i := 1 to *errlist do
  478. X        if errlist[i][1] = n then msg := errlist[i][2]
  479. X    writes(&errout, "error ", n, " (", msg, ")")
  480. X    if \s then {
  481. X    write(&errout, ":  ")
  482. X    every write(&errout, "\t", rewrap(s) | rewrap())
  483. X    }
  484. X    else write(&errout)
  485. X
  486. X    exit(n)
  487. X
  488. Xend
  489. END_OF_FILE
  490.   if test 2908 -ne `wc -c <'iohno.icn'`; then
  491.     echo shar: \"'iohno.icn'\" unpacked with wrong size!
  492.   fi
  493.   # end of 'iohno.icn'
  494. fi
  495. if test -f 'outbits.icn' -a "${1}" != "-c" ; then 
  496.   echo shar: Will not clobber existing file \"'outbits.icn'\"
  497. else
  498.   echo shar: Extracting \"'outbits.icn'\" \(3067 characters\)
  499.   sed "s/^X//" >'outbits.icn' <<'END_OF_FILE'
  500. X############################################################################
  501. X#
  502. X#    Name:     outbits.icn
  503. X#
  504. X#    Title:     output variable-length characters in byte-size chunks
  505. X#
  506. X#    Author:     Richard L. Goerwitz
  507. X#
  508. X#    Version: 1.5
  509. X#
  510. X############################################################################
  511. X#
  512. X#  In any number of instances (e.g. when outputting variable-length
  513. X#  characters or fixed-length encoded strings), the programmer must
  514. X#  fit variable and/or non-byte-sized blocks into standard 8-bit
  515. X#  bytes.  Outbits() performs this task.
  516. X#
  517. X#  Pass to outbits(i, len) an integer i, and a length parameter (len),
  518. X#  and outbits will suspend byte-sized chunks of i converted to
  519. X#  characters (most significant bits first) until there is not enough
  520. X#  left of i to fill up an 8-bit character.  The remaining portion is
  521. X#  stored in a buffer until outbits() is called again, at which point
  522. X#  the buffer is combined with the new i and then output in the same
  523. X#  manner as before.  The buffer is flushed by calling outbits() with
  524. X#  a null i argument.  Note that len gives the number of bits there
  525. X#  are in i (or at least the number of bits you want preserved; those
  526. X#  that are discarded are the most significant ones). 
  527. X#
  528. X#  A trivial example of how outbits() might be used:
  529. X#
  530. X#      outtext := open("some.file.name","w")
  531. X#      l := [1,2,3,4]
  532. X#      every writes(outtext, outbits(!l,3))
  533. X#      writes(outtext, outbits(&null,3))           # flush buffer
  534. X#
  535. X#  List l may be reconstructed with inbits() (see inbits.icn):
  536. X#
  537. X#      intext := open("some.file.name")
  538. X#      l := []
  539. X#      while put(l, inbits(intext, 3))
  540. X#
  541. X#  Note that outbits() is a generator, while inbits() is not.
  542. X#
  543. X############################################################################
  544. X#
  545. X#  Links: none
  546. X#  See also: inbits.icn
  547. X#
  548. X############################################################################
  549. X
  550. X
  551. Xprocedure outbits(i, len)
  552. X
  553. X    local old_part, new_part, window, old_byte_mask
  554. X    static old_i, old_len, byte_length, byte_mask
  555. X    initial {
  556. X    old_i := old_len := 0
  557. X    byte_length := 8
  558. X    byte_mask := (2^byte_length)-1
  559. X    }
  560. X
  561. X    old_byte_mask := (0 < 2^old_len - 1) | 0
  562. X    window := byte_length - old_len
  563. X    old_part := ishift(iand(old_i, old_byte_mask), window)
  564. X
  565. X    # If we have a no-arg invocation, then flush buffer (old_i).
  566. X    if /i then {
  567. X    if old_len > 0 then {
  568. X        old_i := old_len := 0
  569. X        return char(old_part)
  570. X    } else {
  571. X        old_i := old_len := 0
  572. X        fail
  573. X    }
  574. X    } else {
  575. X    new_part := ishift(i, window-len)
  576. X    len -:= (len >= window) | {
  577. X        old_len +:= len
  578. X        old_i := ior(ishift(old_part, len-window), i)
  579. X        fail
  580. X    }
  581. X#    For debugging purposes.
  582. X#    write("old_byte_mask = ", old_byte_mask)
  583. X#    write("window = ", image(window))
  584. X#    write("old_part = ", image(old_part))
  585. X#    write("new_part = ", image(new_part))
  586. X#    write("outputting ", image(ior(old_part, new_part)))
  587. X    suspend char(ior(old_part, new_part))
  588. X    }
  589. X
  590. X    until len < byte_length do {
  591. X    suspend char(iand(ishift(i, byte_length-len), byte_mask))
  592. X    len -:= byte_length
  593. X    }
  594. X
  595. X    old_len := len
  596. X    old_i := i
  597. X    fail
  598. X
  599. Xend
  600. END_OF_FILE
  601.   if test 3067 -ne `wc -c <'outbits.icn'`; then
  602.     echo shar: \"'outbits.icn'\" unpacked with wrong size!
  603.   fi
  604.   # end of 'outbits.icn'
  605. fi
  606. if test -f 'sample.ibp' -a "${1}" != "-c" ; then 
  607.   echo shar: Will not clobber existing file \"'sample.ibp'\"
  608. else
  609.   echo shar: Extracting \"'sample.ibp'\" \(2364 characters\)
  610.   sed "s/^X//" >'sample.ibp' <<'END_OF_FILE'
  611. X#
  612. X# Sample Ibpag2 grammar file.
  613. X#
  614. X
  615. X#
  616. X# The code between %{ and %} gets copied directly.  Note the Iconish
  617. X# comment syntax.
  618. X#
  619. X%{
  620. X
  621. X# Note:  If IIDEBUG is defined in the output file, debugging messages
  622. X# about the stacks and actions get displayed.
  623. X#
  624. X$define IIDEBUG 1
  625. X
  626. X%}
  627. X
  628. X#
  629. X# Here we declare the tokens returned by the lexical analyzer.
  630. X# Precedences increase as we go on.  Note how (unlike YACC), tokens
  631. X# are separated by commas.  Note also how UMINUS is used only for its
  632. X# %prec later.
  633. X#
  634. X%token NUMBER
  635. X%left '+', '-'
  636. X%left '*', '/'
  637. X%right UMINUS
  638. X
  639. X%%
  640. X
  641. X#
  642. X# After this point, and up to the next %%, we have the grammar itself.
  643. X# By default, the start symbol is the left-hand side of the first
  644. X# rule. 
  645. X#
  646. X
  647. Xlines    :    lines, expr, '\n'    { write($2) }
  648. X    |    lines, '\n'
  649. X    |    epsilon     # Note use of epsilon/error tokens.
  650. X    |    error, '\n'        {
  651. X                      write("syntax error; try again:")
  652. X                      # like YACC's yyerrok macro
  653. X                      iierrok
  654. X                    }
  655. X    ;
  656. X
  657. Xexpr    :    expr, '+', expr    { return $1 + $3 }
  658. X    |    expr, '-', expr    { return $1 - $3 }
  659. X    |    expr, '*', expr    { return $1 * $3 }
  660. X    |    expr, '/', expr    { return $1 / $3 }
  661. X    |    '(', expr, ')'    { return $2 }
  662. X    |    '-', expr %prec UMINUS    { return -$2 }
  663. X    |    NUMBER        { return $1 }
  664. X    ;
  665. X
  666. X%%
  667. X
  668. X#
  669. X# From here on, code gets copied directly to the output file.  We are
  670. X# no longer in the grammar proper.
  671. X#
  672. X
  673. X#
  674. X# The lexical analyzer must be called iilex, with the module name
  675. X# appended (if there is one).  It must take one argument, infile (an
  676. X# input stream).  It must be a generator, and fail on EOF (not return
  677. X# something <= 0, as is the case for YACC + Lex).  Iilval holds the
  678. X# literal string value of the token just suspended by iilex().
  679. X#
  680. Xprocedure iilex(infile)
  681. X
  682. X    local nextchar, c, num
  683. X    initial {
  684. X    # Here's where you'd initialize any %{ globals %} declared
  685. X    # above.
  686. X    }
  687. X
  688. X    nextchar := create !(!infile || "\n" || "\n")
  689. X
  690. X    c := @nextchar | fail
  691. X    repeat {
  692. X    if any(&digits, c) then {
  693. X        if not (\num ||:= c) then
  694. X        num := c
  695. X    } else {
  696. X        if iilval := \num then {
  697. X        suspend NUMBER
  698. X        num := &null
  699. X        }
  700. X        if any('+-*/()\n', c) then {
  701. X        iilval := c
  702. X        suspend ord(c)
  703. X        } else {
  704. X        if not any(' \t', c) then {
  705. X            # deliberate error - will be handled later
  706. X            suspend &null
  707. X        }
  708. X        }
  709. X    }
  710. X    c := @nextchar | break
  711. X    }
  712. X    if iilval := \num then {
  713. X    return NUMBER
  714. X    num := &null
  715. X    }
  716. X
  717. Xend
  718. X
  719. Xprocedure main()
  720. X    return iiparse(&input, 1)
  721. Xend
  722. END_OF_FILE
  723.   if test 2364 -ne `wc -c <'sample.ibp'`; then
  724.     echo shar: \"'sample.ibp'\" unpacked with wrong size!
  725.   fi
  726.   # end of 'sample.ibp'
  727. fi
  728. if test -f 'shrnktbl.icn' -a "${1}" != "-c" ; then 
  729.   echo shar: Will not clobber existing file \"'shrnktbl.icn'\"
  730. else
  731.   echo shar: Extracting \"'shrnktbl.icn'\" \(3387 characters\)
  732.   sed "s/^X//" >'shrnktbl.icn' <<'END_OF_FILE'
  733. X############################################################################
  734. X#
  735. X#    Name:     shrnktbl.icn
  736. X#
  737. X#    Title:     table shrinker
  738. X#
  739. X#    Author:     Richard L. Goerwitz
  740. X#
  741. X#    Version: 1.4
  742. X#
  743. X############################################################################
  744. X#
  745. X#  Action/goto table shrinking routine.
  746. X#
  747. X#  Entry point: shrink_tables(start_symbol, st, atbl, gtbl), where
  748. X#  start_symbol is the start symbol for the grammar whose productions
  749. X#  are contained in the list/set st, and where atbl and gtbl are the
  750. X#  action and goto tables, respectively.  Returns &null, for lack of
  751. X#  anything better.
  752. X#  
  753. X#  Basically, this routine merges duplicate structures in atbl and
  754. X#  gtbl (if there are any), replaces the nonterminal symbols in the
  755. X#  action table with integers (including the start symbol), then
  756. X#  resets the goto table so that its keys point to these integers,
  757. X#  instead of to the original nonterminal symbol strings.
  758. X#
  759. X############################################################################
  760. X#
  761. X#  Links: structs, outbits
  762. X#
  763. X#  See also: ibpag2, slrtbls
  764. X#
  765. X############################################################################
  766. X
  767. X# structs has equiv; outbits is for outputting variable-width integers
  768. X# as 8-bit characters
  769. X#
  770. X# link structs, outbits
  771. Xlink structs
  772. X
  773. X#
  774. X# shrink_tables
  775. X#
  776. Xprocedure shrink_tables(grammar, atbl, gtbl)
  777. X
  778. X    local t, k, seen, nontermtbl, r, a, action, state, by_rule,
  779. X    rule_len, LHS, keys
  780. X
  781. X    # Create a table mapping nonterminal symbols to integers.
  782. X    nontermtbl := table()
  783. X    every r := !grammar.rules do
  784. X    # r is a production; production records have LHS, RHS,...no
  785. X    # fields, where the no field contains the rule number; we can
  786. X    # use this as an arbitrary representation for that rule's LHS
  787. X    # nonterminal
  788. X    insert(nontermtbl, r.LHS, r.no)
  789. X
  790. X    # Replace old start symbol.
  791. X    grammar.start := nontermtbl[grammar.start]
  792. X
  793. X    # Re-form the goto table to use the new integer values for
  794. X    # nonterminals.
  795. X    keys := set()
  796. X    every insert(keys, key(gtbl))
  797. X    every k := !keys do {
  798. X    # first create a column for the new integer-valued nonterminal
  799. X    insert(gtbl, string(nontermtbl[k]), gtbl[k])
  800. X    # then clobber the old column with a string-valued nonterminal
  801. X    gtbl[k] := &null
  802. X    }
  803. X
  804. X    # Rewrite actions using a fixed field-width format.
  805. X    every t := !atbl do {
  806. X    every k := key(t) do {
  807. X        a := ""
  808. X        t[k] ? {
  809. X        while action := tab(any('sra')) do {
  810. X            case action of {
  811. X            "s": {
  812. X                outbits(0, 2)
  813. X                state := integer(tab(find(".")))
  814. X                every a ||:= outbits(state, 11)
  815. X                move(1)
  816. X                by_rule := integer(tab(many(&digits)))
  817. X                every a ||:= outbits(by_rule, 11)
  818. X                outbits()
  819. X            }
  820. X            "r": {
  821. X                outbits(1, 2)
  822. X                state := integer(tab(find("<")))
  823. X                every a ||:= outbits(state, 11)
  824. X                move(1)
  825. X                LHS := nontermtbl[tab(find(">"))]
  826. X                every a ||:= outbits(LHS, 11)
  827. X                move(1)
  828. X                rule_len := integer(tab(many(&digits)))
  829. X                every a ||:= outbits(rule_len, 8)
  830. X                outbits()
  831. X            }
  832. X            "a": {
  833. X                outbits(2, 2)
  834. X                a ||:= outbits()
  835. X            }
  836. X            }
  837. X        }
  838. X        }
  839. X        t[k] := a
  840. X    }
  841. X    }
  842. X
  843. X    #
  844. X    # Turn pointers to identical structures into pointers to the same
  845. X    # structure.
  846. X    #
  847. X    seen := set()
  848. X    every t := atbl | gtbl do {
  849. X    every k := key(t) do {
  850. X        if t[k] := equiv(t[k], !seen)
  851. X        then next else insert(seen, t[k])
  852. X    }
  853. X    }
  854. X
  855. X    # signal success
  856. X    return &null
  857. X
  858. Xend
  859. END_OF_FILE
  860.   if test 3387 -ne `wc -c <'shrnktbl.icn'`; then
  861.     echo shar: \"'shrnktbl.icn'\" unpacked with wrong size!
  862.   fi
  863.   # end of 'shrnktbl.icn'
  864. fi
  865. if test -f 'slshupto.icn' -a "${1}" != "-c" ; then 
  866.   echo shar: Will not clobber existing file \"'slshupto.icn'\"
  867. else
  868.   echo shar: Extracting \"'slshupto.icn'\" \(2247 characters\)
  869.   sed "s/^X//" >'slshupto.icn' <<'END_OF_FILE'
  870. X############################################################################
  871. X#
  872. X#    Name:     slshupto.icn
  873. X#
  874. X#    Title:     slshupto (upto with backslash escaping)
  875. X#
  876. X#    Author:     Richard L. Goerwitz
  877. X#
  878. X#    Version: 1.4
  879. X#
  880. X############################################################################
  881. X#
  882. X#  Slshupto works just like upto, except that it ignores backslash
  883. X#  escaped characters.  I can't even begin to express how often I've
  884. X#  run into problems applying Icon's string scanning facilities to
  885. X#  to input that uses backslash escaping.  Normally, I tokenize first,
  886. X#  and then work with lists.  With slshupto() I can now postpone or
  887. X#  even eliminate the traditional tokenizing step, and let Icon's
  888. X#  string scanning facilities to more of the work.
  889. X#
  890. X#  If you're confused:
  891. X#
  892. X#  Typically UNIX utilities (and probably others) use backslashes to
  893. X#  "escape" (i.e. remove the special meaning of) metacharacters.  For
  894. X#  instance, UNIX shells normally accept "*" as a shorthand for "any
  895. X#  series of zero or more characters.  You can make the "*" a literal
  896. X#  "*," with no special meaning, by prepending a backslash.  The rou-
  897. X#  tine slshupto() understands these backslashing conventions.  You
  898. X#  can use it to find the "*" and other special characters because it
  899. X#  will ignore "escaped" characters.
  900. X#
  901. X############################################################################
  902. X#
  903. X#  Links: none
  904. X#
  905. X#  See also: slashbal.icn
  906. X#
  907. X############################################################################
  908. X
  909. X# for compatibility with the original name
  910. X#
  911. Xprocedure slashupto(c, s, i, j)
  912. X    suspend slshupto(c, s, i, j)
  913. Xend
  914. X
  915. X#
  916. X# slshupto:  cset x string x integer x integer -> integers
  917. X#             (c, s, i, j) -> Is (a generator)
  918. X#    where Is are the integer positions in s[i:j] before characters
  919. X#    in c that is not preceded by a backslash escape
  920. X#
  921. Xprocedure slshupto(c, s, i, j)
  922. X
  923. X    local c2
  924. X
  925. X    if /s := &subject
  926. X    then /i := &pos
  927. X    else /i := 1
  928. X    /j := *s + 1
  929. X    
  930. X    /c := &cset
  931. X    c2 := '\\' ++ c
  932. X    s[1:j] ? {
  933. X        tab(i)
  934. X        while tab(upto(c2)) do {
  935. X            if ="\\" then {
  936. X        move(1) | {
  937. X            if find("\\", c)
  938. X            then return &pos - 1
  939. X        }
  940. X        next
  941. X        }
  942. X            suspend .&pos
  943. X            move(1)
  944. X        }
  945. X    }
  946. X
  947. Xend
  948. X
  949. END_OF_FILE
  950.   if test 2247 -ne `wc -c <'slshupto.icn'`; then
  951.     echo shar: \"'slshupto.icn'\" unpacked with wrong size!
  952.   fi
  953.   # end of 'slshupto.icn'
  954. fi
  955. echo shar: End of archive 5 \(of 5\).
  956. cp /dev/null ark5isdone
  957. MISSING=""
  958. for I in 1 2 3 4 5 ; do
  959.     if test ! -f ark${I}isdone ; then
  960.     MISSING="${MISSING} ${I}"
  961.     fi
  962. done
  963. if test "${MISSING}" = "" ; then
  964.     echo You have unpacked all 5 archives.
  965.     rm -f ark[1-9]isdone
  966. else
  967.     echo You still must unpack the following archives:
  968.     echo "        " ${MISSING}
  969. fi
  970. exit 0
  971. exit 0 # Just in case...
  972.