home *** CD-ROM | disk | FTP | other *** search
Text File | 1993-04-10 | 94.2 KB | 2,618 lines |
- Newsgroups: comp.sources.unix
- From: ross@spam.adelaide.edu.au (Ross Williams)
- Subject: v26i135: funnelweb - a tool for literate programming in C, Part15/20
- Sender: unix-sources-moderator@vix.com
- Approved: paul@vix.com
-
- Submitted-By: ross@spam.adelaide.edu.au (Ross Williams)
- Posting-Number: Volume 26, Issue 135
- Archive-Name: funnelweb/part15
-
- [ several files in this archive will unpack with the wrong size, due to
- length restrictions in NNTP. --vix ]
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 15 (of 20)."
- # Contents: answers/pr08.lis sources/parser.c
- # Wrapped by vixie@gw.home.vix.com on Sun Apr 11 11:00:31 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'answers/pr08.lis' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'answers/pr08.lis'\"
- else
- echo shar: Extracting \"'answers/pr08.lis'\" \(48225 characters\)
- sed "s/^X//" >'answers/pr08.lis' <<'END_OF_FILE'
- XFUNNELWEB LISTING FILE
- X======================
- X
- Dump of mapped file "<<Suppressed>>".
- X
- MEMORY DUMP OF MAPPED FILE
- X==========================
- X
- X+-------------------------------------------------+------------------+
- X| 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F | 0123456789ABCDEF |
- X+-------------------------------------------------+------------------+
- X| 50 52 30 38 3A 20 54 65 73 74 20 73 65 6D 61 6E | PR08: Test seman |
- X| 74 69 63 20 63 68 65 63 6B 69 6E 67 20 6F 66 20 | tic checking of |
- X| 6D 61 63 72 6F 20 64 65 66 69 6E 69 74 69 6F 6E | macro definition |
- X| 73 2E 0A 0A 54 72 69 70 20 70 61 72 73 65 72 20 | s...Trip parser |
- X| 74 6F 20 62 65 20 73 75 72 65 20 74 68 61 74 20 | to be sure that |
- X| 77 65 20 77 6F 6E 27 74 20 67 65 74 20 61 6E 79 | we won't get any |
- X| 20 6F 75 74 70 75 74 20 66 69 6C 65 73 21 0A 40 | output files!.@ |
- X| 3E 0A 0A 31 2E 20 46 69 6C 65 20 6D 61 63 72 6F | >..1. File macro |
- X| 20 68 61 73 20 70 61 72 61 6D 65 74 65 72 73 2E | has parameters. |
- X| 20 45 72 72 6F 72 2E 0A 40 4F 40 3C 53 6C 6F 74 | Error..@O@<Slot |
- X| 68 20 31 40 3E 40 28 40 33 40 29 40 7B 57 61 6C | h 1@>@(@3@)@{Wal |
- X| 72 75 73 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 | rus@}.@A@<Error |
- X| 72 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E | recovery point@> |
- X| 0A 0A 32 2E 20 46 69 6C 65 20 6D 61 63 72 6F 20 | ..2. File macro |
- X| 69 73 20 61 64 64 69 74 69 76 65 2E 20 45 72 72 | is additive. Err |
- X| 6F 72 2E 0A 40 4F 40 3C 53 6C 6F 74 68 20 32 40 | or..@O@<Sloth 2@ |
- X| 3E 2B 3D 40 7B 57 61 6C 72 75 73 40 7D 0A 40 41 | >+=@{Walrus@}.@A |
- X| 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 | @<Error recovery |
- X| 20 70 6F 69 6E 74 40 3E 0A 0A 33 2E 20 46 69 6C | point@>..3. Fil |
- X| 65 20 6D 61 63 72 6F 20 68 61 73 20 74 6F 6F 20 | e macro has too |
- X| 6C 6F 6E 67 20 61 20 6E 61 6D 65 2E 20 54 68 65 | long a name. The |
- X| 20 74 65 73 74 20 6E 61 6D 65 20 68 61 73 20 31 | test name has 1 |
- X| 32 30 30 20 63 68 61 72 61 63 74 65 72 73 2E 20 | 200 characters. |
- X| 45 72 72 2E 0A 4E 6F 74 65 3A 20 54 68 69 73 20 | Err..Note: This |
- X| 74 65 73 74 20 63 61 6E 27 74 20 74 65 73 74 20 | test can't test |
- X| 74 68 65 20 65 72 72 6F 72 20 6D 65 73 73 61 67 | the error messag |
- X| 65 20 69 66 20 74 68 65 20 6D 61 78 69 6D 75 6D | e if the maximum |
- X| 20 6C 65 6E 67 74 68 20 6F 66 20 61 0A 6D 61 63 | length of a.mac |
- X| 72 6F 20 6E 61 6D 65 20 69 73 20 6C 65 73 73 20 | ro name is less |
- X| 74 68 61 6E 20 74 68 65 20 6D 61 78 69 6D 75 6D | than the maximum |
- X| 20 6C 65 6E 67 74 68 20 6F 66 20 61 20 66 69 6C | length of a fil |
- X| 65 20 6E 61 6D 65 20 61 73 20 74 68 65 20 6E 61 | e name as the na |
- X| 6D 65 0A 65 72 72 6F 72 20 69 73 20 63 61 75 67 | me.error is caug |
- X| 68 74 20 66 69 72 73 74 2E 0A 40 70 20 6D 61 78 | ht first..@p max |
- X| 69 6D 75 6D 5F 69 6E 70 75 74 5F 6C 69 6E 65 5F | imum_input_line_ |
- X| 6C 65 6E 67 74 68 20 3D 20 69 6E 66 69 6E 69 74 | length = infinit |
- X| 79 0A 40 4F 40 3C 31 32 33 34 35 36 37 38 39 30 | y.@O@<1234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 31 32 33 34 35 36 37 38 39 30 | 5678901234567890 |
- X| 31 32 33 34 35 36 37 38 39 30 31 32 33 34 35 36 | 1234567890123456 |
- X| 37 38 39 30 31 32 33 34 35 36 37 38 39 30 31 32 | 7890123456789012 |
- X| 33 34 35 36 37 38 39 30 31 32 33 34 35 36 37 38 | 3456789012345678 |
- X| 39 30 31 32 33 34 35 36 37 38 39 30 31 32 33 34 | 9012345678901234 |
- X| 35 36 37 38 39 30 40 3E 40 7B 40 7D 0A 40 41 40 | 567890@>@{@}.@A@ |
- X| 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 | <Error recovery |
- X| 70 6F 69 6E 74 40 3E 0A 0A 34 2E 20 46 69 6C 65 | point@>..4. File |
- X| 20 6D 61 63 72 6F 20 68 61 73 20 7A 65 72 6F 20 | macro has zero |
- X| 6F 72 20 6D 61 6E 79 20 61 74 74 72 69 62 75 74 | or many attribut |
- X| 65 73 2E 20 45 72 72 6F 72 2E 0A 40 4F 40 3C 53 | es. Error..@O@<S |
- X| 6C 6F 74 68 20 33 40 3E 40 5A 40 7B 57 61 6C 72 | loth 3@>@Z@{Walr |
- X| 75 73 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 | us@}.@A@<Error r |
- X| 65 63 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A | ecovery point@>. |
- X| 0A 40 4F 40 3C 53 6C 6F 74 68 20 34 40 3E 40 4D | .@O@<Sloth 4@>@M |
- X| 40 7B 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C 45 | @{Walrus@}.@A@<E |
- X| 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F | rror recovery po |
- X| 69 6E 74 40 3E 0A 0A 40 4F 40 3C 53 6C 6F 74 68 | int@>..@O@<Sloth |
- X| 20 35 40 3E 40 5A 40 4D 40 7B 57 61 6C 72 75 73 | 5@>@Z@M@{Walrus |
- X| 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 | @}.@A@<Error rec |
- X| 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 35 | overy point@>..5 |
- X| 2E 20 50 72 65 76 69 6F 75 73 20 64 65 66 69 6E | . Previous defin |
- X| 69 74 69 6F 6E 20 69 73 20 66 75 6C 6C 2C 20 63 | ition is full, c |
- X| 75 72 72 65 6E 74 20 69 73 20 61 64 64 69 74 69 | urrent is additi |
- X| 76 65 2E 0A 40 24 40 3C 57 61 6C 72 75 73 20 31 | ve..@$@<Walrus 1 |
- X| 40 3E 3D 3D 40 7B 53 6C 6F 74 68 40 7D 0A 40 24 | @>==@{Sloth@}.@$ |
- X| 40 3C 57 61 6C 72 75 73 20 31 40 3E 2B 3D 40 7B | @<Walrus 1@>+=@{ |
- X| 41 61 72 64 76 61 72 6B 40 7D 0A 40 41 40 3C 45 | Aardvark@}.@A@<E |
- X| 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F | rror recovery po |
- X| 69 6E 74 40 3E 0A 0A 36 2E 20 50 72 65 76 69 6F | int@>..6. Previo |
- X| 75 73 20 64 65 66 69 6E 69 74 69 6F 6E 20 69 73 | us definition is |
- X| 20 61 64 64 69 74 69 76 65 2C 20 63 75 72 72 65 | additive, curre |
- X| 6E 74 20 69 73 20 66 75 6C 6C 2E 0A 40 24 40 3C | nt is full..@$@< |
- X| 57 61 6C 72 75 73 20 32 40 3E 2B 3D 40 7B 53 6C | Walrus 2@>+=@{Sl |
- X| 6F 74 68 40 7D 0A 40 24 40 3C 57 61 6C 72 75 73 | oth@}.@$@<Walrus |
- X| 20 32 40 3E 3D 3D 40 7B 41 61 72 64 76 61 72 6B | 2@>==@{Aardvark |
- X| 40 7D 0A 40 41 40 3C 45 72 72 6F 72 20 72 65 63 | @}.@A@<Error rec |
- X| 6F 76 65 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 37 | overy point@>..7 |
- X| 2E 20 4E 6F 6E 2D 66 69 72 73 74 20 62 6F 64 79 | . Non-first body |
- X| 20 70 61 72 74 20 6F 66 20 70 61 72 74 69 61 6C | part of partial |
- X| 20 68 61 73 20 70 61 72 61 6D 65 74 65 72 2E 0A | has parameter.. |
- X| 40 24 40 3C 55 6E 69 63 6F 72 6E 40 3E 40 28 40 | @$@<Unicorn@>@(@ |
- X| 33 40 29 2B 3D 40 7B 54 75 72 6B 65 79 40 7D 0A | 3@)+=@{Turkey@}. |
- X| 40 24 40 3C 55 6E 69 63 6F 72 6E 40 3E 40 28 40 | @$@<Unicorn@>@(@ |
- X| 33 40 29 2B 3D 40 7B 54 75 72 6B 65 79 40 7D 0A | 3@)+=@{Turkey@}. |
- X| 40 41 40 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 | @A@<Error recove |
- X| 72 79 20 70 6F 69 6E 74 40 3E 0A 0A 38 2E 20 5A | ry point@>..8. Z |
- X| 65 72 6F 20 6F 72 20 6D 61 6E 79 20 61 74 74 72 | ero or many attr |
- X| 69 62 75 74 65 73 20 6F 6E 20 6E 6F 6E 2D 66 69 | ibutes on non-fi |
- X| 72 73 74 20 62 6F 64 79 20 70 61 72 74 20 6F 66 | rst body part of |
- X| 20 61 64 64 69 74 69 76 65 2E 0A 40 24 40 3C 45 | additive..@$@<E |
- X| 6C 65 70 68 61 6E 74 40 3E 40 5A 40 4D 2B 3D 40 | lephant@>@Z@M+=@ |
- X| 7B 54 75 72 6B 65 79 40 7D 0A 40 24 40 3C 45 6C | {Turkey@}.@$@<El |
- X| 65 70 68 61 6E 74 40 3E 40 5A 40 4D 2B 3D 40 7B | ephant@>@Z@M+=@{ |
- X| 54 75 72 6B 65 79 40 7D 0A 40 41 40 3C 45 72 72 | Turkey@}.@A@<Err |
- X| 6F 72 20 72 65 63 6F 76 65 72 79 20 70 6F 69 6E | or recovery poin |
- X| 74 40 3E 0A 0A 39 2E 20 43 68 65 63 6B 20 74 68 | t@>..9. Check th |
- X| 61 74 20 6E 6F 6E 2D 65 78 69 73 74 65 6E 74 20 | at non-existent |
- X| 66 6F 72 6D 61 6C 20 70 61 72 61 6D 65 74 65 72 | formal parameter |
- X| 73 20 61 72 65 20 63 61 75 67 68 74 2E 0A 0A 40 | s are caught...@ |
- X| 24 40 3C 5A 65 72 6F 40 3E 40 5A 40 7B 53 6C 6F | $@<Zero@>@Z@{Slo |
- X| 74 68 40 31 57 61 6C 72 75 73 40 7D 0A 40 41 40 | th@1Walrus@}.@A@ |
- X| 3C 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 | <Error recovery |
- X| 70 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 4F 6E 65 | point@>..@$@<One |
- X| 40 3E 40 28 40 31 40 29 40 5A 40 7B 53 6C 6F 74 | @>@(@1@)@Z@{Slot |
- X| 68 40 32 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C | h@2Walrus@}.@A@< |
- X| 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 | Error recovery p |
- X| 6F 69 6E 74 40 3E 0A 0A 40 24 40 3C 4D 61 6E 79 | oint@>..@$@<Many |
- X| 40 3E 40 28 40 37 40 29 40 5A 40 7B 53 6C 6F 74 | @>@(@7@)@Z@{Slot |
- X| 68 40 38 57 61 6C 72 75 73 40 7D 0A 40 41 40 3C | h@8Walrus@}.@A@< |
- X| 45 72 72 6F 72 20 72 65 63 6F 76 65 72 79 20 70 | Error recovery p |
- X| 6F 69 6E 74 40 3E 0A | oint@>. |
- X+-------------------------------------------------+------------------+
- X
- X
- X=========================== Start of LINE LIST DUMP ============================
- X
- Globl Local| Text
- X-----------+--------------------------------------------------------------------
- X00001 00001| PR08: Test semantic checking of macro definitions.<010>
- X00002 00002| <010>
- X00003 00003| Trip parser to be sure that we won't get any output files!<010>
- X00004 00004| @><010>
- X00005 00005| <010>
- X00006 00006| 1. File macro has parameters. Error.<010>
- X00007 00007| @O@<Sloth 1@>@(@3@)@{Walrus@}<010>
- X00008 00008| @A@<Error recovery point@><010>
- X00009 00009| <010>
- X00010 00010| 2. File macro is additive. Error.<010>
- X00011 00011| @O@<Sloth 2@>+=@{Walrus@}<010>
- X00012 00012| @A@<Error recovery point@><010>
- X00013 00013| <010>
- X00014 00014| 3. File macro has too long a name. The test name has 1200 characters. Err.<010>
- X00015 00015| Note: This test can't test the error message if the maximum length of a<010>
- X00016 00016| macro name is less than the maximum length of a file name as the name<010>
- X00017 00017| error is caught first.<010>
- X00018 00018| @p maximum_input_line_length = infinity<010>
- X00019 00019| @O@<1234567890(elided by comp.sources.unix moderator)1234567890@>@{@}<010>
- X00020 00020| @A@<Error recovery point@><010>
- X00021 00021| <010>
- X00022 00022| 4. File macro has zero or many attributes. Error.<010>
- X00023 00023| @O@<Sloth 3@>@Z@{Walrus@}<010>
- X00024 00024| @A@<Error recovery point@><010>
- X00025 00025| <010>
- X00026 00026| @O@<Sloth 4@>@M@{Walrus@}<010>
- X00027 00027| @A@<Error recovery point@><010>
- X00028 00028| <010>
- X00029 00029| @O@<Sloth 5@>@Z@M@{Walrus@}<010>
- X00030 00030| @A@<Error recovery point@><010>
- X00031 00031| <010>
- X00032 00032| 5. Previous definition is full, current is additive.<010>
- X00033 00033| @$@<Walrus 1@>==@{Sloth@}<010>
- X00034 00034| @$@<Walrus 1@>+=@{Aardvark@}<010>
- X00035 00035| @A@<Error recovery point@><010>
- X00036 00036| <010>
- X00037 00037| 6. Previous definition is additive, current is full.<010>
- X00038 00038| @$@<Walrus 2@>+=@{Sloth@}<010>
- X00039 00039| @$@<Walrus 2@>==@{Aardvark@}<010>
- X00040 00040| @A@<Error recovery point@><010>
- X00041 00041| <010>
- X00042 00042| 7. Non-first body part of partial has parameter.<010>
- X00043 00043| @$@<Unicorn@>@(@3@)+=@{Turkey@}<010>
- X00044 00044| @$@<Unicorn@>@(@3@)+=@{Turkey@}<010>
- X00045 00045| @A@<Error recovery point@><010>
- X00046 00046| <010>
- X00047 00047| 8. Zero or many attributes on non-first body part of additive.<010>
- X00048 00048| @$@<Elephant@>@Z@M+=@{Turkey@}<010>
- X00049 00049| @$@<Elephant@>@Z@M+=@{Turkey@}<010>
- X00050 00050| @A@<Error recovery point@><010>
- X00051 00051| <010>
- X00052 00052| 9. Check that non-existent formal parameters are caught.<010>
- X00053 00053| <010>
- X00054 00054| @$@<Zero@>@Z@{Sloth@1Walrus@}<010>
- X00055 00055| @A@<Error recovery point@><010>
- X00056 00056| <010>
- X00057 00057| @$@<One@>@(@1@)@Z@{Sloth@2Walrus@}<010>
- X00058 00058| @A@<Error recovery point@><010>
- X00059 00059| <010>
- X00060 00060| @$@<Many@>@(@7@)@Z@{Sloth@8Walrus@}<010>
- X00061 00061| @A@<Error recovery point@><010>
- X00062 00062| <End-Of-File><010>
- X-----------+--------------------------------------------------------------------
- Globl Local| Text
- X
- X============================ End of LINE LIST DUMP =============================
- X
- X
- X=========================== Start of TOKEN LIST DUMP ===========================
- X
- Summary: There are 245 tokens in the token list.
- X
- Line[Column]: Token Description
- X-------------------------------
- X
- X0001[01]: Text. Text scrap[Grey]="PR08: Test semantic checking of macro definitions.<010>
- X<010>
- Trip parser to be sure that we won't get any output files!<010>
- X"
- X0004[01]: @> Close name.
- X0004[03]: Text. Text scrap[Grey]="<010>
- X<010>
- X1. File macro has parameters. Error.<010>
- X"
- X0007[01]: @F File defn.
- X0007[03]: @< Open name.
- X0007[05]: Text. Text scrap[Grey]="Sloth 1"
- X0007[12]: @> Close name.
- X0007[14]: @( Open param.
- X0007[16]: @n Parameter. Parameterno=3.
- X0007[18]: @} Close param.
- X0007[20]: @{ Open defn.
- X0007[22]: Text. Text scrap[Grey]="Walrus"
- X0007[28]: @} Close defn.
- X0007[30]: Text. Text scrap[White]="<010>
- X"
- X0008[01]: @A New section (Level 1).
- X0008[03]: @< Open name.
- X0008[05]: Text. Text scrap[Grey]="Error recovery point"
- X0008[25]: @> Close name.
- X0008[27]: Text. Text scrap[Grey]="<010>
- X<010>
- X2. File macro is additive. Error.<010>
- X"
- X0011[01]: @F File defn.
- X0011[03]: @< Open name.
- X0011[05]: Text. Text scrap[Grey]="Sloth 2"
- X0011[12]: @> Close name.
- X0011[14]: Text. Text scrap[Grey]="+="
- X0011[16]: @{ Open defn.
- X0011[18]: Text. Text scrap[Grey]="Walrus"
- X0011[24]: @} Close defn.
- X0011[26]: Text. Text scrap[White]="<010>
- X"
- X0012[01]: @A New section (Level 1).
- X0012[03]: @< Open name.
- X0012[05]: Text. Text scrap[Grey]="Error recovery point"
- X0012[25]: @> Close name.
- X0012[27]: Text. Text scrap[Grey]="<010>
- X<010>
- X3. File macro has too long a name. The test name has 1200 characters. Err.<010>
- Note: This test can't test the error message if the maximum length of a<010>
- macro name is less than the maximum length of a file name as the name<010>
- error is caught first.<010>
- X"
- X0019[01]: @F File defn.
- X0019[03]: @< Open name.
- X0019[05]: Text. Text scrap[Grey]="1234567890(elided by comp.sources.unix moderator)1234567890"
- X0019[1205]: @> Close name.
- X0019[1207]: @{ Open defn.
- X0019[1209]: @} Close defn.
- X0019[1211]: Text. Text scrap[White]="<010>
- X"
- X0020[01]: @A New section (Level 1).
- X0020[03]: @< Open name.
- X0020[05]: Text. Text scrap[Grey]="Error recovery point"
- X0020[25]: @> Close name.
- X0020[27]: Text. Text scrap[Grey]="<010>
- X<010>
- X4. File macro has zero or many attributes. Error.<010>
- X"
- X0023[01]: @F File defn.
- X0023[03]: @< Open name.
- X0023[05]: Text. Text scrap[Grey]="Sloth 3"
- X0023[12]: @> Close name.
- X0023[14]: @Z Zero calls.
- X0023[16]: @{ Open defn.
- X0023[18]: Text. Text scrap[Grey]="Walrus"
- X0023[24]: @} Close defn.
- X0023[26]: Text. Text scrap[White]="<010>
- X"
- X0024[01]: @A New section (Level 1).
- X0024[03]: @< Open name.
- X0024[05]: Text. Text scrap[Grey]="Error recovery point"
- X0024[25]: @> Close name.
- X0024[27]: Text. Text scrap[White]="<010>
- X<010>
- X"
- X0026[01]: @F File defn.
- X0026[03]: @< Open name.
- X0026[05]: Text. Text scrap[Grey]="Sloth 4"
- X0026[12]: @> Close name.
- X0026[14]: @M Many calls.
- X0026[16]: @{ Open defn.
- X0026[18]: Text. Text scrap[Grey]="Walrus"
- X0026[24]: @} Close defn.
- X0026[26]: Text. Text scrap[White]="<010>
- X"
- X0027[01]: @A New section (Level 1).
- X0027[03]: @< Open name.
- X0027[05]: Text. Text scrap[Grey]="Error recovery point"
- X0027[25]: @> Close name.
- X0027[27]: Text. Text scrap[White]="<010>
- X<010>
- X"
- X0029[01]: @F File defn.
- X0029[03]: @< Open name.
- X0029[05]: Text. Text scrap[Grey]="Sloth 5"
- X0029[12]: @> Close name.
- X0029[14]: @Z Zero calls.
- X0029[16]: @M Many calls.
- X0029[18]: @{ Open defn.
- X0029[20]: Text. Text scrap[Grey]="Walrus"
- X0029[26]: @} Close defn.
- X0029[28]: Text. Text scrap[White]="<010>
- X"
- X0030[01]: @A New section (Level 1).
- X0030[03]: @< Open name.
- X0030[05]: Text. Text scrap[Grey]="Error recovery point"
- X0030[25]: @> Close name.
- X0030[27]: Text. Text scrap[Grey]="<010>
- X<010>
- X5. Previous definition is full, current is additive.<010>
- X"
- X0033[01]: @$ Macro defn.
- X0033[03]: @< Open name.
- X0033[05]: Text. Text scrap[Grey]="Walrus 1"
- X0033[13]: @> Close name.
- X0033[15]: Text. Text scrap[Grey]="=="
- X0033[17]: @{ Open defn.
- X0033[19]: Text. Text scrap[Grey]="Sloth"
- X0033[24]: @} Close defn.
- X0033[26]: Text. Text scrap[White]="<010>
- X"
- X0034[01]: @$ Macro defn.
- X0034[03]: @< Open name.
- X0034[05]: Text. Text scrap[Grey]="Walrus 1"
- X0034[13]: @> Close name.
- X0034[15]: Text. Text scrap[Grey]="+="
- X0034[17]: @{ Open defn.
- X0034[19]: Text. Text scrap[Grey]="Aardvark"
- X0034[27]: @} Close defn.
- X0034[29]: Text. Text scrap[White]="<010>
- X"
- X0035[01]: @A New section (Level 1).
- X0035[03]: @< Open name.
- X0035[05]: Text. Text scrap[Grey]="Error recovery point"
- X0035[25]: @> Close name.
- X0035[27]: Text. Text scrap[Grey]="<010>
- X<010>
- X6. Previous definition is additive, current is full.<010>
- X"
- X0038[01]: @$ Macro defn.
- X0038[03]: @< Open name.
- X0038[05]: Text. Text scrap[Grey]="Walrus 2"
- X0038[13]: @> Close name.
- X0038[15]: Text. Text scrap[Grey]="+="
- X0038[17]: @{ Open defn.
- X0038[19]: Text. Text scrap[Grey]="Sloth"
- X0038[24]: @} Close defn.
- X0038[26]: Text. Text scrap[White]="<010>
- X"
- X0039[01]: @$ Macro defn.
- X0039[03]: @< Open name.
- X0039[05]: Text. Text scrap[Grey]="Walrus 2"
- X0039[13]: @> Close name.
- X0039[15]: Text. Text scrap[Grey]="=="
- X0039[17]: @{ Open defn.
- X0039[19]: Text. Text scrap[Grey]="Aardvark"
- X0039[27]: @} Close defn.
- X0039[29]: Text. Text scrap[White]="<010>
- X"
- X0040[01]: @A New section (Level 1).
- X0040[03]: @< Open name.
- X0040[05]: Text. Text scrap[Grey]="Error recovery point"
- X0040[25]: @> Close name.
- X0040[27]: Text. Text scrap[Grey]="<010>
- X<010>
- X7. Non-first body part of partial has parameter.<010>
- X"
- X0043[01]: @$ Macro defn.
- X0043[03]: @< Open name.
- X0043[05]: Text. Text scrap[Grey]="Unicorn"
- X0043[12]: @> Close name.
- X0043[14]: @( Open param.
- X0043[16]: @n Parameter. Parameterno=3.
- X0043[18]: @} Close param.
- X0043[20]: Text. Text scrap[Grey]="+="
- X0043[22]: @{ Open defn.
- X0043[24]: Text. Text scrap[Grey]="Turkey"
- X0043[30]: @} Close defn.
- X0043[32]: Text. Text scrap[White]="<010>
- X"
- X0044[01]: @$ Macro defn.
- X0044[03]: @< Open name.
- X0044[05]: Text. Text scrap[Grey]="Unicorn"
- X0044[12]: @> Close name.
- X0044[14]: @( Open param.
- X0044[16]: @n Parameter. Parameterno=3.
- X0044[18]: @} Close param.
- X0044[20]: Text. Text scrap[Grey]="+="
- X0044[22]: @{ Open defn.
- X0044[24]: Text. Text scrap[Grey]="Turkey"
- X0044[30]: @} Close defn.
- X0044[32]: Text. Text scrap[White]="<010>
- X"
- X0045[01]: @A New section (Level 1).
- X0045[03]: @< Open name.
- X0045[05]: Text. Text scrap[Grey]="Error recovery point"
- X0045[25]: @> Close name.
- X0045[27]: Text. Text scrap[Grey]="<010>
- X<010>
- X8. Zero or many attributes on non-first body part of additive.<010>
- X"
- X0048[01]: @$ Macro defn.
- X0048[03]: @< Open name.
- X0048[05]: Text. Text scrap[Grey]="Elephant"
- X0048[13]: @> Close name.
- X0048[15]: @Z Zero calls.
- X0048[17]: @M Many calls.
- X0048[19]: Text. Text scrap[Grey]="+="
- X0048[21]: @{ Open defn.
- X0048[23]: Text. Text scrap[Grey]="Turkey"
- X0048[29]: @} Close defn.
- X0048[31]: Text. Text scrap[White]="<010>
- X"
- X0049[01]: @$ Macro defn.
- X0049[03]: @< Open name.
- X0049[05]: Text. Text scrap[Grey]="Elephant"
- X0049[13]: @> Close name.
- X0049[15]: @Z Zero calls.
- X0049[17]: @M Many calls.
- X0049[19]: Text. Text scrap[Grey]="+="
- X0049[21]: @{ Open defn.
- X0049[23]: Text. Text scrap[Grey]="Turkey"
- X0049[29]: @} Close defn.
- X0049[31]: Text. Text scrap[White]="<010>
- X"
- X0050[01]: @A New section (Level 1).
- X0050[03]: @< Open name.
- X0050[05]: Text. Text scrap[Grey]="Error recovery point"
- X0050[25]: @> Close name.
- X0050[27]: Text. Text scrap[Grey]="<010>
- X<010>
- X9. Check that non-existent formal parameters are caught.<010>
- X<010>
- X"
- X0054[01]: @$ Macro defn.
- X0054[03]: @< Open name.
- X0054[05]: Text. Text scrap[Grey]="Zero"
- X0054[09]: @> Close name.
- X0054[11]: @Z Zero calls.
- X0054[13]: @{ Open defn.
- X0054[15]: Text. Text scrap[Grey]="Sloth"
- X0054[20]: @n Parameter. Parameterno=1.
- X0054[22]: Text. Text scrap[Grey]="Walrus"
- X0054[28]: @} Close defn.
- X0054[30]: Text. Text scrap[White]="<010>
- X"
- X0055[01]: @A New section (Level 1).
- X0055[03]: @< Open name.
- X0055[05]: Text. Text scrap[Grey]="Error recovery point"
- X0055[25]: @> Close name.
- X0055[27]: Text. Text scrap[White]="<010>
- X<010>
- X"
- X0057[01]: @$ Macro defn.
- X0057[03]: @< Open name.
- X0057[05]: Text. Text scrap[Grey]="One"
- X0057[08]: @> Close name.
- X0057[10]: @( Open param.
- X0057[12]: @n Parameter. Parameterno=1.
- X0057[14]: @} Close param.
- X0057[16]: @Z Zero calls.
- X0057[18]: @{ Open defn.
- X0057[20]: Text. Text scrap[Grey]="Sloth"
- X0057[25]: @n Parameter. Parameterno=2.
- X0057[27]: Text. Text scrap[Grey]="Walrus"
- X0057[33]: @} Close defn.
- X0057[35]: Text. Text scrap[White]="<010>
- X"
- X0058[01]: @A New section (Level 1).
- X0058[03]: @< Open name.
- X0058[05]: Text. Text scrap[Grey]="Error recovery point"
- X0058[25]: @> Close name.
- X0058[27]: Text. Text scrap[White]="<010>
- X<010>
- X"
- X0060[01]: @$ Macro defn.
- X0060[03]: @< Open name.
- X0060[05]: Text. Text scrap[Grey]="Many"
- X0060[09]: @> Close name.
- X0060[11]: @( Open param.
- X0060[13]: @n Parameter. Parameterno=7.
- X0060[15]: @} Close param.
- X0060[17]: @Z Zero calls.
- X0060[19]: @{ Open defn.
- X0060[21]: Text. Text scrap[Grey]="Sloth"
- X0060[26]: @n Parameter. Parameterno=8.
- X0060[28]: Text. Text scrap[Grey]="Walrus"
- X0060[34]: @} Close defn.
- X0060[36]: Text. Text scrap[White]="<010>
- X"
- X0061[01]: @A New section (Level 1).
- X0061[03]: @< Open name.
- X0061[05]: Text. Text scrap[Grey]="Error recovery point"
- X0061[25]: @> Close name.
- X0061[27]: Text. Text scrap[White]="<010>
- X"
- X0062[01]: End Of File.
- X============================ End of TOKEN LIST DUMP ============================
- X
- X
- X========================== Start of MACRO TABLE DUMP ===========================
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Elephant"
- Defined? : Yes.
- Parameters : 0
- Additive? : Yes.
- Zero Calls? : Yes.
- Many Calls? : Yes.
- Output File?: No.
- Call list :
- Macro body :
- X
- X--Start of List of Body Parts--
- This macro has 1 body part.
- Body part 1: Seqnum=4, Pos(L,C)=(48,3), Expression follows:
- X
- X---- Start of Expression ----
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Turkey"
- X------ End Text Element ------
- X
- X----- End of Expression -----
- X
- X---End of List of Body Parts---
- X
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Many"
- Defined? : Yes.
- Parameters : 7
- Additive? : No.
- Zero Calls? : Yes.
- Many Calls? : No.
- Output File?: No.
- Call list :
- Macro body :
- X
- X--Start of List of Body Parts--
- This macro has 1 body part.
- Body part 1: Seqnum=7, Pos(L,C)=(60,3), Expression follows:
- X
- X---- Start of Expression ----
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Sloth"
- X------ End Text Element ------
- X
- X
- X-- Start Parameter Element --
- Parameter number=8.
- Parameter is of macro "Many".
- X--- End Parameter Element ---
- X
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Walrus"
- X------ End Text Element ------
- X
- X----- End of Expression -----
- X
- X---End of List of Body Parts---
- X
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "One"
- Defined? : Yes.
- Parameters : 1
- Additive? : No.
- Zero Calls? : Yes.
- Many Calls? : No.
- Output File?: No.
- Call list :
- Macro body :
- X
- X--Start of List of Body Parts--
- This macro has 1 body part.
- Body part 1: Seqnum=6, Pos(L,C)=(57,3), Expression follows:
- X
- X---- Start of Expression ----
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Sloth"
- X------ End Text Element ------
- X
- X
- X-- Start Parameter Element --
- Parameter number=2.
- Parameter is of macro "One".
- X--- End Parameter Element ---
- X
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Walrus"
- X------ End Text Element ------
- X
- X----- End of Expression -----
- X
- X---End of List of Body Parts---
- X
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Sloth 1"
- Defined? : No.
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Sloth 2"
- Defined? : No.
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Sloth 3"
- Defined? : No.
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Sloth 4"
- Defined? : No.
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Sloth 5"
- Defined? : No.
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Unicorn"
- Defined? : Yes.
- Parameters : 3
- Additive? : Yes.
- Zero Calls? : No.
- Many Calls? : No.
- Output File?: No.
- Call list :
- Macro body :
- X
- X--Start of List of Body Parts--
- This macro has 1 body part.
- Body part 1: Seqnum=3, Pos(L,C)=(43,3), Expression follows:
- X
- X---- Start of Expression ----
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Turkey"
- X------ End Text Element ------
- X
- X----- End of Expression -----
- X
- X---End of List of Body Parts---
- X
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Walrus 1"
- Defined? : Yes.
- Parameters : 0
- Additive? : No.
- Zero Calls? : No.
- Many Calls? : No.
- Output File?: No.
- Call list :
- Macro body :
- X
- X--Start of List of Body Parts--
- This macro has 1 body part.
- Body part 1: Seqnum=1, Pos(L,C)=(33,3), Expression follows:
- X
- X---- Start of Expression ----
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Sloth"
- X------ End Text Element ------
- X
- X----- End of Expression -----
- X
- X---End of List of Body Parts---
- X
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Walrus 2"
- Defined? : Yes.
- Parameters : 0
- Additive? : Yes.
- Zero Calls? : No.
- Many Calls? : No.
- Output File?: No.
- Call list :
- Macro body :
- X
- X--Start of List of Body Parts--
- This macro has 1 body part.
- Body part 1: Seqnum=2, Pos(L,C)=(38,3), Expression follows:
- X
- X---- Start of Expression ----
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Sloth"
- X------ End Text Element ------
- X
- X----- End of Expression -----
- X
- X---End of List of Body Parts---
- X
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X------------------- Start of Macro Dump --------------------
- Macro Name : "Zero"
- Defined? : Yes.
- Parameters : 0
- Additive? : No.
- Zero Calls? : Yes.
- Many Calls? : No.
- Output File?: No.
- Call list :
- Macro body :
- X
- X--Start of List of Body Parts--
- This macro has 1 body part.
- Body part 1: Seqnum=5, Pos(L,C)=(54,3), Expression follows:
- X
- X---- Start of Expression ----
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Sloth"
- X------ End Text Element ------
- X
- X
- X-- Start Parameter Element --
- Parameter number=1.
- Parameter is of macro "Zero".
- X--- End Parameter Element ---
- X
- X
- X----- Start Text Element -----
- Text scrap[Grey]="Walrus"
- X------ End Text Element ------
- X
- X----- End of Expression -----
- X
- X---End of List of Body Parts---
- X
- X-------------------- End of Macro Dump ---------------------
- X
- X
- X
- X=========================== End of MACRO TABLE DUMP ============================
- X
- X
- X========================= Start of DOCUMENT LIST DUMP ==========================
- X
- X
- TEXT COMPONENT: Pos(L,C)=(1,1).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="PR08: Test semantic checking of macro definitions.<010>
- X<010>
- Trip parser to be sure that we won't get any output files!<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TEXT COMPONENT: Pos(L,C)=(4,3).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X1. File macro has parameters. Error.<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "1", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(8,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X2. File macro is additive. Error.<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "2", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(12,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X3. File macro has too long a name. The test name has 1200 characters. Err.<010>
- Note: This test can't test the error message if the maximum length of a<010>
- macro name is less than the maximum length of a file name as the name<010>
- error is caught first.<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "3", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(20,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X4. File macro has zero or many attributes. Error.<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "4", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(24,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "5", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(27,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "6", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(30,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X5. Previous definition is full, current is additive.<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- MACRO DEFINITION COMPONENT: Pos(L,C)=(33,1).
- Part 1 of macro @<Walrus 1@>.
- X
- TEXT COMPONENT: Pos(L,C)=(33,26).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "7", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(35,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X6. Previous definition is additive, current is full.<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- MACRO DEFINITION COMPONENT: Pos(L,C)=(38,1).
- Part 1 of macro @<Walrus 2@>.
- X
- TEXT COMPONENT: Pos(L,C)=(38,26).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "8", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(40,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X7. Non-first body part of partial has parameter.<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- MACRO DEFINITION COMPONENT: Pos(L,C)=(43,1).
- Part 1 of macro @<Unicorn@>.
- X
- TEXT COMPONENT: Pos(L,C)=(43,32).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "9", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(45,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X8. Zero or many attributes on non-first body part of additive.<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- MACRO DEFINITION COMPONENT: Pos(L,C)=(48,1).
- Part 1 of macro @<Elephant@>.
- X
- TEXT COMPONENT: Pos(L,C)=(48,31).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "10", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(50,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[Grey]="<010>
- X<010>
- X9. Check that non-existent formal parameters are caught.<010>
- X<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- MACRO DEFINITION COMPONENT: Pos(L,C)=(54,1).
- Part 1 of macro @<Zero@>.
- X
- TEXT COMPONENT: Pos(L,C)=(54,30).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "11", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(55,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- MACRO DEFINITION COMPONENT: Pos(L,C)=(57,1).
- Part 1 of macro @<One@>.
- X
- TEXT COMPONENT: Pos(L,C)=(57,35).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "12", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(58,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- MACRO DEFINITION COMPONENT: Pos(L,C)=(60,1).
- Part 1 of macro @<Many@>.
- X
- TEXT COMPONENT: Pos(L,C)=(60,36).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- TYPESETTER DIRECTIVE COMPONENT:
- X Section "13", Section name="Error recovery point".
- X
- TEXT COMPONENT: Pos(L,C)=(61,27).
- X
- X-- Start of Text Scrap List --
- Text scrap[White]="<010>
- X"
- X--- End of Text Scrap List ---
- X
- X
- X========================== End of DOCUMENT LIST DUMP ===========================
- X
- X
- Global Local| Input File
- X------------+-------------------------------------------------------------------
- X 1 1| PR08: Test semantic checking of macro definitions.
- X 2 2|
- X 3 3| Trip parser to be sure that we won't get any output files!
- X 4 4| @>
- X Error|.^The parser was at the top level and was expecting
- X |.^one of: {Directive, Text, Macro definition, EOF}.
- X 5 5|
- X 6 6| 1. File macro has parameters. Error.
- X 7 7| @O@<Sloth 1@>@(@3@)@{Walrus@}
- X |...^Macro definition ignored.
- X Error|................^Macros attached to output files cannot be parameterized.
- X |................^Reason: No actual parameters would be available during
- X |................^ output file generation.
- X |....................^Skipping after error to the next major construct...
- X 8 8| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 9 9|
- X 10 10| 2. File macro is additive. Error.
- X 11 11| @O@<Sloth 2@>+=@{Walrus@}
- X |...^Macro definition ignored.
- X Error|..............^Macros attached to output files cannot be additive.
- X |..............^Reason: Preventing this makes it easy to find output
- X |..............^file macros later, because there will be exactly one
- X |..............^@O declaration in the input file for each output file.
- X |..............^To do what you are trying to do, just create an additive
- X |..............^bridging macro, like this:
- X |..............^ @O@<prog.c@>@{@<Bridge@>@}
- X |..............^ @$@<Bridge@>+=@{void stringhack()...@}
- X |..............^ @$@<Bridge@>+=@{main()...@}
- X |................^Skipping after error to the next major construct...
- X 12 12| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 13 13|
- X 14 14| 3. File macro has too long a name. The test name has 1200 characters. Err.
- X 15 15| Note: This test can't test the error message if the maximum length of a
- X 16 16| macro name is less than the maximum length of a file name as the name
- X 17 17| error is caught first.
- X 18 18| @p maximum_input_line_length = infinity
- X 19 19| @O@<1234567890(elided by comp.sources.unix moderator)1234567890@>@{@}
- X Error|.....^Name is too long.
- X |.....^The maximum length of a legal name is 80 characters.
- X |.....^Skipping after error to the next major construct...
- X 20 20| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 21 21|
- X 22 22| 4. File macro has zero or many attributes. Error.
- X 23 23| @O@<Sloth 3@>@Z@{Walrus@}
- X |...^Macro definition ignored.
- X Error|..............^Macros attached to output files cannot have @Z or @M.
- X |..............^Reason: They are always called once to generate their
- X |..............^output file and they cannot be called from other macros.
- X |..............^Hence they are always called exactly once and so there
- X |..............^can be no need for @Z or @M in their declarations.
- X |................^Skipping after error to the next major construct...
- X 24 24| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 25 25|
- X 26 26| @O@<Sloth 4@>@M@{Walrus@}
- X |...^Macro definition ignored.
- X Error|..............^Macros attached to output files cannot have @Z or @M.
- X |..............^Reason: They are always called once to generate their
- X |..............^output file and they cannot be called from other macros.
- X |..............^Hence they are always called exactly once and so there
- X |..............^can be no need for @Z or @M in their declarations.
- X |................^Skipping after error to the next major construct...
- X 27 27| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 28 28|
- X 29 29| @O@<Sloth 5@>@Z@M@{Walrus@}
- X |...^Macro definition ignored.
- X Error|..............^Macros attached to output files cannot have @Z or @M.
- X |..............^Reason: They are always called once to generate their
- X |..............^output file and they cannot be called from other macros.
- X |..............^Hence they are always called exactly once and so there
- X |..............^can be no need for @Z or @M in their declarations.
- X |..................^Skipping after error to the next major construct...
- X 30 30| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 31 31|
- X 32 32| 5. Previous definition is full, current is additive.
- X 33 33| @$@<Walrus 1@>==@{Sloth@}
- X 34 34| @$@<Walrus 1@>+=@{Aardvark@}
- X Error|...^A full definition of this macro appears at line 33.
- X |...^Full and additive definitions of the same macro cannot coexist.
- X |...^Macro definition ignored.
- X |.................^Skipping after error to the next major construct...
- X 35 35| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 36 36|
- X 37 37| 6. Previous definition is additive, current is full.
- X 38 38| @$@<Walrus 2@>+=@{Sloth@}
- X 39 39| @$@<Walrus 2@>==@{Aardvark@}
- X Error|...^An additive definition of this macro appears at line 38.
- X |...^Full and additive definitions of the same macro cannot coexist.
- X |...^Macro definition ignored.
- X |.................^Skipping after error to the next major construct...
- X 40 40| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 41 41|
- X 42 42| 7. Non-first body part of partial has parameter.
- X 43 43| @$@<Unicorn@>@(@3@)+=@{Turkey@}
- X 44 44| @$@<Unicorn@>@(@3@)+=@{Turkey@}
- X |...^Macro definition ignored.
- X Error|................^The formal parameter list of an additive macro
- X |................^must be placed only in the first definition part.
- X |................^The first part of this macro appears at line 43.
- X |......................^Skipping after error to the next major construct...
- X 45 45| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 46 46|
- X 47 47| 8. Zero or many attributes on non-first body part of additive.
- X 48 48| @$@<Elephant@>@Z@M+=@{Turkey@}
- X 49 49| @$@<Elephant@>@Z@M+=@{Turkey@}
- X |...^Macro definition ignored.
- X Error|...............^@Z and @M modifiers for additive macros must
- X |...............^be placed only in the first definition part.
- X |...............^The first part of this macro appears at line 48.
- X |.....................^Skipping after error to the next major construct...
- X 50 50| @A@<Error recovery point@>
- X |.^...skipped to here after the error.
- X 51 51|
- X 52 52| 9. Check that non-existent formal parameters are caught.
- X 53 53|
- X 54 54| @$@<Zero@>@Z@{Sloth@1Walrus@}
- X Error|....................^Macro being defined has only 0 parameters.
- X 55 55| @A@<Error recovery point@>
- X 56 56|
- X 57 57| @$@<One@>@(@1@)@Z@{Sloth@2Walrus@}
- X Error|.........................^Macro being defined has only 1 parameter.
- X 58 58| @A@<Error recovery point@>
- X 59 59|
- X 60 60| @$@<Many@>@(@7@)@Z@{Sloth@8Walrus@}
- X Error|..........................^Macro being defined has only 7 parameters.
- X 61 61| @A@<Error recovery point@>
- X | <End-Of-File>
- X------------+-------------------------------------------------------------------
- X
- There were 14 Errors.
- END_OF_FILE
- if test 48225 -ne `wc -c <'answers/pr08.lis'`; then
- echo shar: \"'answers/pr08.lis'\" unpacked with wrong size!
- fi
- # end of 'answers/pr08.lis'
- fi
- if test -f 'sources/parser.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sources/parser.c'\"
- else
- echo shar: Extracting \"'sources/parser.c'\" \(47198 characters\)
- sed "s/^X//" >'sources/parser.c' <<'END_OF_FILE'
- X/*##############################################################################
- X
- XFUNNNELWEB COPYRIGHT
- X====================
- XFunnelWeb is a literate-programming macro preprocessor.
- X
- Copyright (C) 1992 Ross N. Williams.
- X
- X Ross N. Williams
- X ross@spam.adelaide.edu.au
- X 16 Lerwick Avenue, Hazelwood Park 5066, Australia.
- X
- This program is free software; you can redistribute it and/or modify
- it under the terms of Version 2 of the GNU General Public License as
- published by the Free Software Foundation.
- X
- This program is distributed WITHOUT ANY WARRANTY; without even the implied
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See Version 2 of the GNU General Public License for more details.
- X
- You should have received a copy of Version 2 of the GNU General Public
- License along with this program. If not, you can FTP the license from
- prep.ai.mit.edu/pub/gnu/COPYING-2 or write to the Free Software
- XFoundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- X
- Section 2a of the license requires that all changes to this file be
- recorded prominently in this file. Please record all changes here.
- X
- Programmers:
- X RNW Ross N. Williams ross@spam.adelaide.edu.au
- X
- Changes:
- X 07-May-1992 RNW Program prepared for release under GNU GPL V2.
- X
- X##############################################################################*/
- X
- X
- X/******************************************************************************/
- X/* PARSER.C */
- X/******************************************************************************/
- X
- X#include <setjmp.h>
- X#include "style.h"
- X
- X#include "as.h"
- X#include "data.h"
- X#include "lister.h"
- X#include "machin.h"
- X#include "mapper.h"
- X#include "memory.h"
- X#include "misc.h"
- X#include "parser.h"
- X#include "section.h"
- X#include "table.h"
- X
- X/******************************************************************************/
- X
- X#define DUMMYINT 0 /* It doesn't matter what this value is!!! */
- X#define TKPS &(p_tk->tk_ps) /* A commonly used construct. */
- X
- X/******************************************************************************/
- X
- X/* The following variables look after sections. */
- LOCVAR sn_t last_sn; /* Hierarchical section number of last section. */
- LOCVAR ps_t pssection; /* Position of last section. */
- LOCVAR p_dc_t p_secdc; /* Pointer to current section document component. */
- LOCVAR tk_t *p_tk; /* Pointer to the current token (a structure). */
- LOCVAR ulong sequence; /* Current sequence number. */
- LOCVAR jmp_buf jmp_pos; /* Setjmp() position of main parsing loop. */
- X
- X/******************************************************************************/
- X/* Comparison Functions */
- X/******************************************************************************/
- X
- LOCAL sign cm_name P_((name_t *,name_t *));
- LOCAL sign cm_name(name1,name2)
- X/* Compares two names and returns: */
- X/* -1 if name1 < name2 */
- X/* 0 if name1 = name2 */
- X/* 1 if name1 > name2 */
- X/* Provides a full ordering on the set of names. */
- name_t *name1;
- name_t *name2;
- X{
- X return signof(strcmp(&(*name1)[0],&(*name2)[0]));
- X}
- X
- X/******************************************************************************/
- X
- LOCAL sign eq_txst P_((p_scls_t,char *));
- LOCAL sign eq_txst(p_scls,p_str)
- X/* The first argument is a list of text scraps. */
- X/* The second argument is an ordinary string. */
- X/* Returns TRUE iff the two are identical. Otherwise FALSE. */
- p_scls_t p_scls;
- char *p_str;
- X{
- X /* To compare the scrap list with the string, we run through the scrap list */
- X /* comparing the bytes its scraps yield progressively with the string. */
- X /* The two scanning groups are (p_scls,p_sc,p_ch) and p_str. */
- X sc_t *p_sc;
- X
- X ls_fir(p_scls);
- X ls_nxt(p_scls,PPV &p_sc);
- X while (p_sc!=NULL)
- X {
- X /* The loop body compares a single scrap pointed to by p_sc. */
- X char *p_ch;
- X for (p_ch=p_sc->sc_first; p_ch<=p_sc->sc_last; p_ch++)
- X {
- X if (*p_str==EOS || *p_str != *p_ch) return FALSE;
- X p_str++;
- X }
- X ls_nxt(p_scls,PPV &p_sc);
- X }
- X return *p_str==EOS;
- X}
- X
- X/******************************************************************************/
- X/* Parsing Primitives */
- X/******************************************************************************/
- X/* The following functions provide the basic parsing primitives used by the */
- X/* main parsing routines. */
- X/******************************************************************************/
- X
- LOCAL void next_tk P_((bool));
- LOCAL void next_tk(iseoferr)
- X/* This function reads the next token from the token list and places a */
- X/* pointer to the token (structure) in the global variable "token". */
- X/* The "iseoferr" determines whether a fuss should be made if the next token */
- X/* fetched is TK_EOF. If iseoferr==TRUE and the next token is TK_EOF, next_tk */
- X/* jumps to the main parsing loop. */
- bool iseoferr;
- X{
- X ls_nxt(token_list,PPV &p_tk);
- X as_cold(p_tk!=NULL,"next_tk: Attempted to read next token at EOF.");
- X if (iseoferr && p_tk->tk_kind==TK_EOF)
- X {
- X lr_err(TKPS,"Ouch! High velocity encounter with end of file.");
- X lr_mes(TKPS,"FunnelWeb expected something else when it hit the EOF.");
- X longjmp(jmp_pos,DUMMYINT); /* Jump up to the main parsing loop. */
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void recover P_((void));
- LOCAL void recover()
- X/* Parsing functions call this function at points where a syntax error has */
- X/* has occurred that it is unlikely that the particular parsing function will */
- X/* be able to recover from on its own. In these situations, the parser */
- X/* resorts to a course grained syntactic error-recovery implemented by this */
- X/* function. The goal of the error recovery system is to skip tokens until */
- X/* the next major outer-level-syntax structure is encountered. These are: */
- X/* - A new section (@A etc.). */
- X/* - A macro definition (@$ or @O). */
- X/* - End of file. */
- X/* Once one of these three is found, "recover" raises the syntax exception */
- X/* which sends control to the main parsing loop which is the correct place */
- X/* to deal with a new, major syntactic construct. */
- X{
- X lr_mes(TKPS,"Skipping after error to the next major construct...");
- X
- X /* Skip to one of TK_NSEC,... */
- X while (TRUE)
- X {
- X tk_k_t k = p_tk->tk_kind;
- X if (k==TK_NSEC || k==TK_MDEF || k==TK_FDEF || k==TK_EOF) break;
- X next_tk(FALSE);
- X }
- X
- X /* Keep the user informed. */
- X lr_mes(TKPS,"...skipped to here after the error.");
- X
- X /* Jump up to the main parsing loop. */
- X longjmp(jmp_pos,DUMMYINT);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void genexerr P_((tk_k_t));
- LOCAL void genexerr(tk_kind)
- X/* Genexerr stands for GENerate EXpecting ERRor. */
- X/* Given a token kind, genexerr issues an error saying that the specified */
- X/* kind of token was expected. It then invokes recover() for error recovery. */
- tk_k_t tk_kind;
- X{
- X switch (tk_kind)
- X {
- X /* Note: Not all token kinds are listed here. Only those token kinds that */
- X /* are passed to pr_token and check_tk by the main parsing routines are */
- X /* included here. There are some tokens that one never expects! */
- X case TK_NSEC: lr_err(TKPS,"Expecting '@*'."); break;
- X case TK_ONAM: lr_err(TKPS,"Expecting '@<'."); break;
- X case TK_ODEF: lr_err(TKPS,"Expecting '@{'."); break;
- X case TK_CDEF: lr_err(TKPS,"Expecting '@}'."); break;
- X case TK_EMPH: lr_err(TKPS,"Expecting '@/'."); break;
- X case TK_CPAR: lr_err(TKPS,"Expecting '@)'."); break;
- X case TK_QUOT: lr_err(TKPS,"Expecting '@\"'."); break;
- X case TK_PARM: lr_err(TKPS,"Expecting one of [@1..@9]." ); break;
- X case TK_TEXT: lr_err(TKPS,"Expecting a text character."); break;
- X default: as_bomb("genexerr: Case defaulted.");
- X }
- X recover();
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_token P_((tk_k_t));
- LOCAL void pr_token(tk_kind)
- X/* Parses a single token of the specified kind. */
- X/* If the token is of the specified kind, gets the next token. */
- X/* If the token is not of the specified kind, generates an "expecting" error. */
- tk_k_t tk_kind;
- X{
- X if (p_tk->tk_kind != tk_kind)
- X genexerr(tk_kind);
- X next_tk(TRUE);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void check_tk P_((tk_k_t));
- LOCAL void check_tk(tk_kind)
- X/* Same as pr_token, but only checks that the token is OK. Does not move on. */
- tk_k_t tk_kind;
- X{
- X if (p_tk->tk_kind != tk_kind)
- X genexerr(tk_kind);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void ass_tk P_((tk_k_t));
- LOCAL void ass_tk(tk_kind)
- X/* Aborts the program if the current token is not of the specified kind. */
- X/* This function is intended to perform internal consistency checks, and */
- X/* should not be considered to be part of the parsing operation. */
- tk_k_t tk_kind;
- X{
- X as_cold(p_tk->tk_kind==tk_kind,"Parser.ass_tk: Incorrect token.");
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void ass_tks P_((tk_k_t,tk_k_t));
- LOCAL void ass_tks(tk_kind1,tk_kind2)
- X/* Same as ass_tk except it allows a choice of two token kinds. */
- tk_k_t tk_kind1;
- tk_k_t tk_kind2;
- X{
- X as_cold((p_tk->tk_kind == tk_kind1) || (p_tk->tk_kind == tk_kind2),
- X "Parser.ass_tks: Token is neither of two allowables.");
- X}
- X
- X/******************************************************************************/
- X/* Main Parsing Functions */
- X/******************************************************************************/
- X
- X/* The parse expression procedure is the only procedure for which a forward */
- X/* declaration is required. This is a product of the recursive definition of */
- X/* a FunnelWeb expression. */
- LOCAL void pr_exp P_((p_ells_t *,p_ma_t));
- X
- X/******************************************************************************/
- X
- LOCAL void pr_text P_((p_scls_t *,bool *));
- LOCAL void pr_text(pp_scls,p_white)
- X/* This function parses a sequence of zero or more text tokens (until it runs */
- X/* into a non-text token) and constructs a list of scraps containing the text */
- X/* pointed to by the tokens. In addition the function writes TRUE to its */
- X/* second argument iff all of the text scraps are whitespace. */
- p_scls_t *pp_scls;
- bool *p_white;
- X{
- X *pp_scls=ls_cre(sizeof(sc_t));
- X *p_white=TRUE;
- X
- X while (p_tk->tk_kind==TK_TEXT)
- X {
- X *p_white = *p_white && p_tk->tk_sc.sc_white;
- X ls_add(*pp_scls,PV &p_tk->tk_sc);
- X next_tk(FALSE);
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_white P_((p_scls_t *));
- LOCAL void pr_white(pp_scls)
- X/* Same as pr_text, but generates an error if the text is non-white. */
- p_scls_t *pp_scls;
- X{
- X bool iswhite;
- X ps_t ps;
- X ASSIGN(ps,p_tk->tk_ps);
- X pr_text(pp_scls,&iswhite);
- X if (!iswhite)
- X lr_err(&ps,"Expecting whitespace text.");
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_name P_((char *));
- LOCAL void pr_name(p_name)
- X/* Parses a single FunnelWeb name (e.g. "@<Sloth@>" and "@#K"). */
- char *p_name; /* Really should be of type p_name_t but this caused trouble. */
- X{
- X uword namelen = 0;
- X
- X /* Deal with the special case of a token name. */
- X if (p_tk->tk_kind==TK_NAME)
- X {
- X p_name[0]=p_tk->tk_gen;
- X p_name[1]=EOS;
- X next_tk(TRUE);
- X return;
- X }
- X
- X ass_tk(TK_ONAM);
- X next_tk(TRUE);
- X
- X while (TRUE)
- X switch (p_tk->tk_kind)
- X {
- X case TK_TEXT:
- X {
- X /* Copy the text token to the name array, checking all the time. */
- X char *p;
- X for (p=p_tk->tk_sc.sc_first; p<=p_tk->tk_sc.sc_last; p++)
- X {
- X if (*p==EOL)
- X {
- X lr_err(TKPS,"Names cannot cross lines.");
- X recover();
- X }
- X namelen++;
- X if (namelen>NAME_MAX)
- X {
- X lr_err(TKPS,"Name is too long.");
- X sprintf(linet1,
- X "The maximum length of a legal name is %lu characters.",
- X (unsigned long) NAME_MAX);
- X lr_mes(TKPS,linet1);
- X recover();
- X }
- X p_name[namelen-1] = *p;
- X }
- X next_tk(TRUE);
- X break;
- X }
- X case TK_CNAM:
- X /* We finish successfully if we hit a close name token "@>". */
- X p_name[namelen]=EOS;
- X next_tk(TRUE);
- X return;
- X default:
- X lr_err(TKPS,"Illegal character or symbol in name.");
- X recover();
- X } /* End switch */
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_dctxt P_((void));
- LOCAL void pr_dctxt()
- X/* Parse a major text chunk. */
- X{
- X dc_t dc;
- X bool dummybool;
- X ps_t pstext;
- X
- X ass_tk(TK_TEXT);
- X
- X ASSIGN(pstext,p_tk->tk_ps);
- X pr_text(&dc.dc_text,&dummybool);
- X ASSIGN(dc.dc_ps,pstext);
- X dc.dc_kind=DC_TEXT;
- X ls_add(document_list,PV &dc);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void sendtype P_((ty_k_t));
- LOCAL void sendtype(ty_kind)
- X/* Send a document component of kind typesetter directive with no attributes. */
- ty_k_t ty_kind;
- X{
- X dc_t dc;
- X ASSIGN(dc.dc_ps,p_tk->tk_ps);
- X dc.dc_kind = DC_TYPE;
- X dc.dc_ty.ty_kind=ty_kind;
- X ls_add(document_list,PV &dc);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_lit P_((void));
- LOCAL void pr_lit()
- X/* Parse a string delimited by literal typeset directives e.g. @{sloth@}. */
- X{
- X /* Check and get past opening directive. */
- X ass_tk(TK_ODEF);
- X sendtype(TY_OLIT);
- X
- X /* Move past the opening directive and parse the sandwich text. */
- X next_tk(TRUE);
- X if (p_tk->tk_kind!=TK_TEXT)
- X {
- X lr_err(TKPS,"Text expected after open literal token \"@{\".");
- X if (p_tk->tk_kind==TK_CDEF)
- X lr_mes(TKPS,"Sorry, empty literal strings are not allowed.");
- X recover();
- X }
- X pr_dctxt();
- X
- X /* Check and parse the closing directive. */
- X pr_token(TK_CDEF);
- X sendtype(TY_CLIT);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_emp P_((void));
- LOCAL void pr_emp()
- X/* Parse a string delimited by emphasis typeset directives e.g. @/sloth@/. */
- X{
- X /* Check and get past opening directive. */
- X ass_tk(TK_EMPH);
- X sendtype(TY_OEMP);
- X
- X /* Move past the opening directive and parse the sandwich text. */
- X next_tk(TRUE);
- X if (p_tk->tk_kind!=TK_TEXT)
- X {
- X lr_err(TKPS,"Text expected after open emphasise token \"@/\".");
- X if (p_tk->tk_kind==TK_EMPH)
- X lr_mes(TKPS,"Sorry, empty emphasised strings are not allowed.");
- X recover();
- X }
- X pr_dctxt();
- X
- X /* Check and parse the closing directive. */
- X pr_token(TK_EMPH);
- X sendtype(TY_CEMP);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_npag P_((void));
- LOCAL void pr_npag()
- X/* Parse a newpage token. */
- X{
- X ass_tk(TK_NPAG);
- X sendtype(TY_NPAG);
- X pr_token(TK_NPAG);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_tocs P_((void));
- LOCAL void pr_tocs()
- X/* Parse a table of contents token. */
- X{
- X ass_tk(TK_TOCS);
- X sendtype(TY_TOCS);
- X pr_token(TK_TOCS);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_skip P_((void));
- LOCAL void pr_skip()
- X/* Parse a skip token. */
- X{
- X dc_t dc;
- X ass_tk(TK_SKIP);
- X ASSIGN(dc.dc_ps,p_tk->tk_ps);
- X dc.dc_kind = DC_TYPE;
- X dc.dc_ty.ty_kind=TY_SKIP;
- X dc.dc_ty.ty_mm=p_tk->tk_gen;
- X ls_add(document_list,PV &dc);
- X pr_token(TK_SKIP);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_titl P_((void));
- LOCAL void pr_titl()
- X/* Parse a title token. Bascially moving bones from one grave to another. */
- X{
- X dc_t dc;
- X ass_tk(TK_TITL);
- X ASSIGN(dc.dc_ps,p_tk->tk_ps);
- X dc.dc_kind = DC_TYPE;
- X dc.dc_ty.ty_kind = TY_TITL;
- X dc.dc_ty.ty_font = p_tk->tk_gen / LRFT_PACK;
- X dc.dc_ty.ty_align = p_tk->tk_gen % LRFT_PACK;
- X ASSIGN(dc.dc_ty.ty_sc,p_tk->tk_sc);
- X ls_add(document_list,PV &dc);
- X pr_token(TK_TITL);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_sec P_((void));
- LOCAL void pr_sec()
- X/* Parse a new section marker ("@A.. and @*") and its optional name. */
- X{
- X ps_t secps; /* Position of this new section. */
- X ubyte level; /* Level number of new section. */
- X bool has_name; /* Set to TRUE iff the section has a name. */
- X name_t name; /* Name of the section (if it has a name). */
- X
- X /* If called, a new section marker must have been seen. */
- X ass_tk(TK_NSEC);
- X
- X /* Grab a copy of the position of the start of the section. */
- X ASSIGN(secps,p_tk->tk_ps);
- X
- X /* Grab the level number of the section marker. Move to the next token. */
- X level=p_tk->tk_gen;
- X next_tk(TRUE);
- X
- X /* Check for a discontinuity in level. */
- X if (level>sn_lev(&last_sn)+1)
- X {
- X if (sn_lev(&last_sn)==0)
- X lr_err(&secps,"The first section in a document must be an @A section.");
- X else
- X {
- X sprintf(linet1,"The next section (at line %lu) is too deep.",
- X (unsigned long) secps.ps_line);
- X lr_mes(&pssection,linet1);
- X lr_err(&secps,"This section is more than one level deeper than the last");
- X sprintf(linet1,"section (at line %lu). Example: @B followed by @D is not allowed.",
- X (unsigned long) pssection.ps_line);
- X lr_mes(&secps,linet1);
- X }
- X /* At this point we know that the section structure of the document is */
- X /* faulty and that the weaver will never be invoked. As such the */
- X /* principal concern becomes that of error recovery. The best we can do */
- X /* there is to set to the specified level regardless of how silly it is. */
- X /* This ensures that we generate section errors only relative to the */
- X /* previous section. Thus, we avoid cascades of errors, if, for example */
- X /* the user mistypes an @A at the beginning of a FunnelWeb document. */
- X /* Once an error has occurred we don't care about the actual numbers. */
- X sn_set(&last_sn,level);
- X }
- X
- X /* Actually increment the section number at the specified level. */
- X sn_inc(&last_sn,level);
- X
- X /* Record the position. */
- X ASSIGN(pssection,secps);
- X
- X /* Parse optional name (e.g. "@<Sloth@>"). */
- X if (p_tk->tk_kind==TK_ONAM || p_tk->tk_kind==TK_NAME)
- X {
- X pr_name(name);
- X has_name=TRUE;
- X }
- X else
- X {
- X strcpy(name,"No name given");
- X has_name=FALSE;
- X }
- X
- X /* Place all the information we have into a document component structure */
- X /* and add it to the document list. */
- X {
- X dc_t dc;
- X ASSIGN(dc.dc_ps,secps);
- X dc.dc_kind = DC_TYPE;
- X dc.dc_ty.ty_kind=TY_NSEC;
- X ASSIGN(dc.dc_ty.ty_sn,last_sn);
- X dc.dc_ty.ty_isnam = has_name;
- X strcpy(&dc.dc_ty.ty_name[0],&name[0]);
- X ls_add(document_list,PV &dc);
- X ls_tai(document_list,PPV &p_secdc);
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void rem_name P_((char *));
- LOCAL void rem_name(p_name)
- X/* rem_name stands for REMember NAME. rem_name accepts a pointer to a name. */
- X/* It looks up the name in the global macro table, and if the name is in the */
- X/* table performs no action. If the name isn't in the table, it creates a new */
- X/* entry for the name, filling the entry's fields with "blank" values. */
- X/* The rem_name function should not be seen as recording the definition of a */
- X/* macro. This is handled by the md_isdef field. Instead the rem_name macro */
- X/* should be viewed as just creating the space in the table for the info. */
- char * p_name; /* Really should be of type p_name_t but this caused trouble. */
- X{
- X if (!tb_itb(macro_table,PV p_name))
- X {
- X p_ma_t p_macro=(p_ma_t) mm_temp(sizeof(ma_t));
- X strcpy(&p_macro->ma_name[0],&p_name[0]);
- X p_macro->ma_calls = ls_cre(sizeof(mc_t));
- X p_macro->ma_defn.md_isdef = FALSE;
- X p_macro->ma_actn = ls_cre(sizeof(p_elll_t));
- X tb_ins(macro_table,PV p_name,PV &p_macro);
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void chk_whex P_((p_ps_t,p_ells_t,p_scls_t *));
- LOCAL void chk_whex(p_ps,p_ex,pp_white)
- X/* This function should really be a subfunction of pr_plist. However, C */
- X/* doesn't allow nested functions so we have to put it here. This function is */
- X/* called after pr_plist has just parsed an opening expression followed by */
- X/* @". This means that the expression should consist of whitespace crud. Our */
- X/* mission here is to check that it really does contain only whitespace crud */
- X/* and return a text list containing the crud. If, on the other hand, it */
- X/* contains meatier items, we have to call recover(). */
- p_ps_t p_ps; /* Position of the start of the expression. */
- p_ells_t p_ex; /* The expression that we have to check out. */
- p_scls_t *pp_white; /* The place to put the resultant whitespace list. */
- X{
- X p_el_t p_el;
- X
- X /* If the expression is empty, we can return an empty list. */
- X if (ls_len(p_ex)==0)
- X {
- X *pp_white=ls_cre(sizeof(sc_t));
- X return;
- X }
- X
- X /* If there is more than one element, there is ...trouble. */
- X if (ls_len(p_ex) > 1) goto trouble;
- X
- X /* Extract the first element of the list. */
- X ls_fir(p_ex); ls_nxt(p_ex,PPV &p_el);
- X
- X /* If it's not text, there is ...trouble. */
- X if (p_el->el_kind != EL_TEXT) goto trouble;
- X
- X /* If the text isn't lilly white, there is ...trouble. */
- X {
- X p_scls_t p_scls = p_el->el_text;
- X p_sc_t p_sc;
- X ls_fir(p_scls);
- X while (TRUE)
- X {
- X ls_nxt(p_scls,PPV &p_sc);
- X if (p_sc==NULL) break;
- X if (!p_sc->sc_white) goto trouble;
- X }
- X /* If we got this far, we know that the expression contains a single */
- X /* element and that that element is a text list and that that text */
- X /* list consists entirely of whitespace. We can now return it. */
- X *pp_white=p_scls;
- X return;
- X }
- X
- X /* We COULD start dissecting the expression and issuing detailed specific */
- X /* error messages. However, the general approach is cleaner and so a general */
- X /* error message is used. */
- X trouble:
- X lr_err( p_ps,"Everything from here...");
- X lr_mes(TKPS,"...to here should be whitespace.");
- X lr_mes(TKPS,"Use of @\" to delimit macro parameters is optional, but");
- X lr_mes(TKPS,"if they are used, any surrounding text must be white.");
- X recover();
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_plist P_((p_elll_t *, p_scll_t *, p_scll_t *,p_ma_t));
- LOCAL void pr_plist(pp_plist,p_before,p_after,p_curmac)
- X/* This function parses an optional parameter list. If the current token is */
- X/* not TK_OPAR, then it is assumed that no list is present and no tokens are */
- X/* consumed and empty lists are returned. */
- X/* The three lists returned are: */
- X/* A list of parameters each being a pointer to a list of elements. */
- X/* A list of whitespace blocks being the space before each parameter. */
- X/* A list of whitespace blocks being the space after each parameter. */
- X/* The last parameter p_curmac should be supplied by the caller and should */
- X/* contain a pointer to the macro currently being parsed. */
- p_elll_t *pp_plist;
- p_scll_t *p_before;
- p_scll_t *p_after;
- p_ma_t p_curmac;
- X{
- X /* Initialize all the result lists to empty. */
- X *pp_plist = ls_cre(sizeof(p_ells_t));
- X *p_before = ls_cre(sizeof(p_scls_t));
- X *p_after = ls_cre(sizeof(p_scls_t));
- X
- X /* The parameter list is optional. If it isn't there we assume a null one. */
- X if (p_tk->tk_kind!=TK_OPAR)
- X return;
- X next_tk(TRUE);
- X
- X /* Now parse the parameter list, one parameter during each iteration. */
- X while (TRUE)
- X {
- X ps_t exp_ps;
- X p_ells_t p_ex;
- X p_scls_t p_white;
- X
- X /* Things get a little tricky here because the double quotes around */
- X /* parameters are optional (per parameter). Thus the following calls are */
- X /* all legal (and functionally identical): */
- X /* @<Sloth@>@( @"walrus@" @, @"aardvark@" @) */
- X /* @<Sloth@>@(walrus@, @"aardvark@" @) */
- X /* @<Sloth@>@(walrus@,aardvark@) */
- X
- X /* Note the position of the start of this parameter slot. */
- X ASSIGN(exp_ps,p_tk->tk_ps);
- X
- X /* Because we face either crud text or an expression, we parse an exp. */
- X pr_exp(&p_ex,p_curmac);
- X
- X /* Now take a look at the next token. If it is @" we know that we have */
- X /* been parsing whitespace crud. If it is @, or @) we know that we have */
- X /* been parsing the parameter expression itself. */
- X if (p_tk->tk_kind==TK_COMA || p_tk->tk_kind==TK_CPAR)
- X {
- X p_scls_t p_scls = ls_cre(sizeof(sc_t));
- X ls_add(*p_before,PV &p_scls); /* Add empty whitespace to crud list. */
- X ls_add(*pp_plist,PV &p_ex); /* Add expression to parameter list. */
- X ls_add(*p_after ,PV &p_scls); /* Add empty whitespace to crud list. */
- X }
- X else
- X if (p_tk->tk_kind==TK_QUOT)
- X {
- X /* After parsing the expression we hit a @". This means that the */
- X /* expression just parsed SHOULD turn out to contain a single */
- X /* element consisting of a white space text list. */
- X chk_whex(&exp_ps,p_ex,&p_white);
- X ls_add(*p_before,PV &p_white);
- X
- X /* Get past the quote. */
- X next_tk(TRUE);
- X
- X /* Parse the expression and add it to the parameter list. */
- X pr_exp(&p_ex,p_curmac); ls_add(*pp_plist,PV &p_ex);
- X
- X /* Parse the quote to move onto the whitespace. */
- X pr_token(TK_QUOT);
- X
- X /* Parse the whitespace after the parameter. */
- X {p_scls_t p_white; pr_white(&p_white); ls_add(*p_after,PV &p_white);}
- X }
- X else
- X {lr_err(TKPS,"Expecting @\" or @, or @)."); recover();}
- X
- X /* The parameter list can now end (TK_CPAR) or continue (TK_COMA). */
- X if (p_tk->tk_kind==TK_COMA)
- X next_tk(TRUE);
- X else
- X if (p_tk->tk_kind==TK_CPAR)
- X {next_tk(TRUE);return;}
- X else
- X {lr_err(TKPS,"Expecting @, or @)."); recover();}
- X } /* End while */
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_invelt P_((p_el_t,p_ma_t));
- LOCAL void pr_invelt(p_el,p_curmac)
- X/* Parses an "invocation element" which is just FunnelWebSpeak for "macro */
- X/* call". Upon entry the current token must be TK_ONAM or TK_NAME which */
- X/* presumably is the start of a macro call. Returns a pointer to an element */
- X/* object describing the call. Does some other macro table stuff too. */
- X/* p_curmac should be supplied by the caller and should be a pointer to the */
- X/* macro currently being parsed. */
- p_el_t p_el;
- p_ma_t p_curmac;
- X{
- X name_t name; /* Name of the macro being invoked. */
- X ps_t mc_ps; /* Position of the start of the macro invocation. */
- X mc_t mc; /* Macro call object that describes the invocation. */
- X p_ma_t p_callee; /* Pointer to the macro object of the target macro. */
- X p_elll_t parlist; /* The parameter list of the invocation. */
- X p_scll_t before; /* Whitespace before each parameter in the param list. */
- X p_scll_t after; /* Whitespace after each parameter in the param list. */
- X
- X /* We shouldn't have been called unless we have seen the start of a name. */
- X ass_tks(TK_ONAM,TK_NAME);
- X
- X /* Note the position of the start of the invocation. */
- X mc_ps=p_tk->tk_ps;
- X
- X /* Parse the invocation (name and optional parameter list). */
- X pr_name(name); pr_plist(&parlist,&before,&after,p_curmac);
- X
- X /* Ensure that there is an entry for this macro name in the macro table. */
- X rem_name(name);
- X
- X /* Construct a macro call object describing the call and add it to the */
- X /* callee macro's call list. */
- X /* Note: The +1 in sequence+1 is because the sequence number is incremented */
- X /* at the end of each macro definition and we are only halfway here. */
- X mc.mc_seq = sequence+1;
- X mc.mc_ps = mc_ps;
- X mc.mc_npar = ls_len(parlist);
- X tb_loo(macro_table,PV name,PV &p_callee);
- X ls_add(p_callee->ma_calls,PV &mc);
- X
- X /* Write an invocation element describing the call to the parameter. */
- X p_el->el_kind = EL_INVC;
- X p_el->el_p_mac = p_callee;
- X p_el->el_parls = parlist;
- X p_el->el_pretx = before;
- X p_el->el_postx = after;
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_txtelt P_((p_el_t));
- LOCAL void pr_txtelt(p_el)
- X/* Parses a text element. Upon entry, the current token must be of type */
- X/* TK_TEXT. Writes a text element into its parameter. */
- p_el_t p_el;
- X{
- X p_scls_t p_scls;
- X bool dummy;
- X ass_tk(TK_TEXT);
- X pr_text(&p_scls,&dummy);
- X p_el->el_kind = EL_TEXT;
- X p_el->el_text = p_scls;
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_parelt P_((p_el_t,p_ma_t));
- LOCAL void pr_parelt(p_el,p_curmac)
- X/* Parses a parameter element (e.g. @5). Writes the resultant parameter */
- X/* element object to the first parameter. The second parameter should be */
- X/* supplied by the caller and should be a pointer to the macro being parsed. */
- p_el_t p_el;
- p_ma_t p_curmac;
- X{
- X /* We have to be sitting on a parameter token. */
- X ass_tk(TK_PARM);
- X
- X /* Complain if the parameter does not exist. */
- X if (p_tk->tk_gen > p_curmac->ma_defn.md_npar)
- X {
- X sprintf(linet1,"Macro being defined has only %lu parameter%s.",
- X (unsigned long) p_curmac->ma_defn.md_npar,
- X p_curmac->ma_defn.md_npar==1 ? "" : "s");
- X lr_err(TKPS,linet1);
- X }
- X
- X /* Write a parameter element to the function parameter. */
- X p_el->el_kind = EL_PARM;
- X p_el->el_parno = p_tk->tk_gen;
- X p_el->el_which = p_curmac;
- X
- X /* Move on to the token following the parameter token. */
- X next_tk(TRUE);
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_exp(p_ex,p_curmac)
- X/* Parses an expression and writes an expression list to the first parameter. */
- X/* The second parameter should be supplied by the user and should be a */
- X/* pointer to the macro currently being parsed. */
- p_ells_t *p_ex;
- p_ma_t p_curmac;
- X{
- X p_ells_t ex = ls_cre(sizeof(el_t));
- X
- X while (TRUE)
- X {
- X el_t el;
- X switch (p_tk->tk_kind)
- X {
- X case TK_TEXT: pr_txtelt(&el); break;
- X case TK_NAME:
- X case TK_ONAM: pr_invelt(&el,p_curmac); break;
- X case TK_PARM: pr_parelt(&el,p_curmac); break;
- X default : *p_ex=ex; return;
- X }
- X ls_add(ex,PV &el);
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_formal P_((uword *,p_ps_t));
- LOCAL void pr_formal(p_numpar,p_ps)
- X/* A FunnelWeb formal parameter list looks something like this: "@(@5@)". */
- X/* This function parses a parameter list if present and returns the number of */
- X/* parameters in the formal parameter list. The function also returns the */
- X/* position the parameter list. */
- uword *p_numpar;
- p_ps_t p_ps;
- X{
- X /* If the parameter list is absent, we default to having zero parameters and */
- X /* making the position of the parameter list the position of the next token. */
- X *p_numpar = 0;
- X *p_ps = p_tk->tk_ps;
- X
- X /* Parse the parameter list only if one is present. */
- X if (p_tk->tk_kind==TK_OPAR)
- X {
- X /* Move to the parameter token and get its number and position. */
- X next_tk(TRUE);
- X check_tk(TK_PARM);
- X *p_numpar=p_tk->tk_gen;
- X *p_ps=p_tk->tk_ps;
- X
- X /* Parse the end of the formal parameter list. */
- X next_tk(TRUE);
- X pr_token(TK_CPAR);
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_number P_((bool *,bool *));
- LOCAL void pr_number(p_iszer,p_isman)
- X/* Parses optional @Z@M after parameter list. */
- bool *p_iszer;
- bool *p_isman;
- X{
- X *p_iszer=FALSE;
- X *p_isman=FALSE;
- X
- X /* The following parse allows zero, one or both of @Z@M, but in order. */
- X
- X /* Grab an @Z if it is there. */
- X if (p_tk->tk_kind==TK_ZERO)
- X {
- X next_tk(TRUE);
- X *p_iszer=TRUE;
- X }
- X
- X /* Grab an @M too if it is there. */
- X if (p_tk->tk_kind==TK_MANY)
- X {
- X next_tk(TRUE);
- X *p_isman=TRUE;
- X }
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_equals P_((bool *,p_ps_t));
- LOCAL void pr_equals(isadd,p_ps)
- X/* Parses optional "==" or "+=". Sets *isadd==TRUE iff "+=" parsed else FALSE.*/
- X/* Sets *p_ps to the position of the equals. */
- bool *isadd;
- p_ps_t p_ps;
- X{
- X p_scls_t p_scls;
- X bool dummy;
- X
- X /* Grab a copy of the position of the equals (even if it is not there) . */
- X ASSIGN(*p_ps,p_tk->tk_ps);
- X
- X /* If the equals isn't there, we default to FALSE. */
- X *isadd=FALSE;
- X if (p_tk->tk_kind!=TK_TEXT) return;
- X
- X /* Parse text tokens producing a text list. */
- X pr_text(&p_scls,&dummy);
- X
- X /* Compare the text list with the assignment constant strings. */
- X if (eq_txst(p_scls,"==")) {*isadd=FALSE; ls_des(p_scls); return;}
- X if (eq_txst(p_scls,"+=")) {*isadd=TRUE; ls_des(p_scls); return;}
- X
- X lr_err(p_ps,"Expecting \"==@{\" or \"+=@{\" or just \"@{\".");
- X lr_mes(p_ps,"(or @Z or @M if they have not already appeared).");
- X lr_mes(p_ps,"Note: FunnelWeb is intolerant of spaces at this point.");
- X ls_des(p_scls);
- X recover();
- X}
- X
- X/******************************************************************************/
- X
- LOCAL bool checkdef P_((p_ma_t,bool,ulong,bool,bool,bool,
- X p_ps_t,p_ps_t,p_ps_t,p_ps_t));
- LOCAL bool checkdef (p_ma,is_file,numpar,iszer,isman,isadd,
- X p_psnam,p_psfor,p_pseql,p_psnum)
- X/* This function performs all sorts of checks on a macro definition. */
- X/* If there is anything wrong, it generates and error and calls recover(). */
- X/* This would be best as a local function but because C doesn't have local */
- X/* functions we have to use millions of parameters instead. */
- p_ma_t p_ma;
- bool is_file;
- ulong numpar;
- bool iszer;
- bool isman;
- bool isadd;
- p_ps_t p_psnam;
- p_ps_t p_psfor;
- p_ps_t p_pseql;
- p_ps_t p_psnum;
- X{
- X bool semerr = FALSE;
- X
- X /* CHECK INTERNAL INCONSISTENCIES */
- X /* ------------------------------ */
- X /* Complain if a file macro has a parameter list. */
- X if (is_file && numpar>0)
- X {
- X lr_err(p_psfor,"Macros attached to output files cannot be parameterized.");
- X lr_mes(p_psfor,"Reason: No actual parameters would be available during");
- X lr_mes(p_psfor," output file generation.");
- X semerr=TRUE;
- X }
- X
- X /* Complain if a file macro is declared additive. */
- X if (is_file && isadd)
- X {
- X lr_err(p_pseql,"Macros attached to output files cannot be additive.");
- X lr_mes(p_pseql,"Reason: Preventing this makes it easy to find output");
- X lr_mes(p_pseql,"file macros later, because there will be exactly one");
- X lr_mes(p_pseql,"@O declaration in the input file for each output file.");
- X lr_mes(p_pseql,"To do what you are trying to do, just create an additive");
- X lr_mes(p_pseql,"bridging macro, like this:");
- X lr_mes(p_pseql," @O@<prog.c@>@{@<Bridge@>@}");
- X lr_mes(p_pseql," @$@<Bridge@>+=@{void stringhack()...@}");
- X lr_mes(p_pseql," @$@<Bridge@>+=@{main()...@}");
- X semerr=TRUE;
- X }
- X
- X /* Complain if a file macro has a name that is too long. */
- X if (is_file && strlen(&p_ma->ma_name[0])>FILENAME_MAX)
- X {
- X lr_err(p_psnam,
- X "File macro's name is longer than the maximum permissible filename length.");
- X sprintf(linet1,"Maximum filename length is %lu characters.",
- X (unsigned long) FILENAME_MAX);
- X lr_mes(p_psnam,linet1);
- X semerr=TRUE;
- X }
- X
- X /* Complain if a file macro has "zero" or "many" attributes. */
- X if (is_file && (iszer || isman))
- X {
- X lr_err(p_psnum,"Macros attached to output files cannot have @Z or @M.");
- X lr_mes(p_psnum,"Reason: They are always called once to generate their");
- X lr_mes(p_psnum,"output file and they cannot be called from other macros.");
- X lr_mes(p_psnum,"Hence they are always called exactly once and so there");
- X lr_mes(p_psnum,"can be no need for @Z or @M in their declarations.");
- X semerr=TRUE;
- X }
- X
- X /* COMPARE WITH EARLIER DEFINITIONS */
- X /* -------------------------------- */
- X /* Don't do this section if no previous definition exists. */
- X if (!p_ma->ma_defn.md_isdef) goto finish;
- X
- X /* Assert: An earlier definition of this macro exists. */
- X
- X /* Old definition is a full definition, not admitting partial ones now. */
- X if (!p_ma->ma_defn.md_isadd)
- X {
- X if (isadd)
- X {
- X sprintf(linet1,"A full definition of this macro appears at line %lu.",
- X (ulong) p_ma->ma_defn.md_ps.ps_line);
- X lr_err(p_psnam,linet1);
- X lr_mes(p_psnam,"Full and additive definitions of the same macro cannot coexist.");
- X }
- X else
- X {
- X sprintf(linet1,"This macro is already fully defined (at line %lu).",
- X (ulong) p_ma->ma_defn.md_ps.ps_line);
- X lr_err(p_psnam,linet1);
- X }
- X semerr=TRUE;
- X }
- X
- X /* Old definition is partial but new definition is full. */
- X if (p_ma->ma_defn.md_isadd && !isadd)
- X {
- X sprintf(linet1,"An additive definition of this macro appears at line %lu.",
- X (ulong) p_ma->ma_defn.md_ps.ps_line);
- X lr_err(p_psnam,linet1);
- X lr_mes(p_psnam,"Full and additive definitions of the same macro cannot coexist.");
- X semerr=TRUE;
- X }
- X
- X /* Make sure that non-first body parts of additive macros do not have params.*/
- X if (isadd && (numpar>0))
- X {
- X lr_err(p_psfor,"The formal parameter list of an additive macro");
- X lr_mes(p_psfor,"must be placed only in the first definition part.");
- X sprintf(linet1,"The first part of this macro appears at line %lu.",
- X (ulong) p_ma->ma_defn.md_ps.ps_line);
- X lr_mes(p_psfor,linet1);
- X semerr=TRUE;
- X }
- X
- X /* Complain if number attributes are being attached to an additive. */
- X if (isadd && (iszer || isman))
- X {
- X lr_err(p_psnum,"@Z and @M modifiers for additive macros must");
- X lr_mes(p_psnum,"be placed only in the first definition part.");
- X sprintf(linet1,"The first part of this macro appears at line %lu.",
- X (ulong) p_ma->ma_defn.md_ps.ps_line);
- X lr_mes(p_psnum,linet1);
- X semerr=TRUE;
- X }
- X
- X finish:
- X if (semerr)
- X {
- X lr_mes(p_psnam,"Macro definition ignored.");
- X recover();
- X }
- X return TRUE;
- X}
- X
- X/******************************************************************************/
- X
- LOCAL void pr_macro P_((void));
- LOCAL void pr_macro()
- X/* This function parses a single macro definition. Upon entry, the current */
- X/* token must be either TK_MDEF or TK_FDEF. */
- X{
- X ps_t ps_mac; /* Position of start of the macro definition. */
- X bool is_file; /* TRUE iff definition starts with @O instead of @$. */
- X name_t name; /* The macro name appearing in this definition. */
- X p_ma_t p_ma; /* Pointer to the macro record corresponding to 'name'. */
- X ps_t ps_name; /* Position of the macro name. */
- X ps_t ps_form; /* Position of the formal parameter list. */
- X ps_t ps_equal; /* Position of the equals. */
- X ps_t ps_num; /* Position of number attributes. */
- X uword numpar; /* Number of parameters in formal parameter list. */
- X bool iszer; /* TRUE iff macro is allowed to be called zero times. */
- X bool isman; /* TRUE iff macro is allowed to be called more than once. */
- X bool isadd; /* TRUE iff equals parsed here is "+=" not "==". */
- X p_ells_t ex; /* Expression constituting this macro body part. */
- X bool hasname; /* TRUE iff current section already has a name. */
- X
- X /* We should not have got in here without seeing a definition token. */
- X ass_tks(TK_MDEF,TK_FDEF);
- X
- X /* Grab a copy of the position of the start of the macro. */
- X ASSIGN(ps_mac,p_tk->tk_ps);
- X
- X /* If we have seen a macro definition token then it means that the user is */
- X /* TRYING to define a macro. The macro may or may not provoke errors. In */
- X /* either case though we do not want to hassle the user with errors about */
- X /* nameless sections not containing macros if it is obvious that an attempt */
- X /* to define a macro has been made. So here we set the name flag after */
- X /* having a look at it so we can use its value later. */
- X if (sn_lev(&last_sn)>0)
- X {
- X as_cold(p_secdc->dc_kind==DC_TYPE,"pr_macro: section processing error (1).");
- X as_cold(p_secdc->dc_ty.ty_kind==TY_NSEC,"pr_macro: section processing error (2).");
- X hasname=p_secdc->dc_ty.ty_isnam;
- X p_secdc->dc_ty.ty_isnam=TRUE;
- X }
- X
- X /* Record whether the macro is attached to an product file. */
- X is_file= (p_tk->tk_kind==TK_FDEF);
- X
- X /* Parse the macro name. Record its position. Ensure that there is an entry */
- X /* in the macro table for this macro name (i.e. create one if not there). */
- X next_tk(TRUE);
- X if (p_tk->tk_kind!=TK_ONAM && p_tk->tk_kind!=TK_NAME)
- X {
- X lr_err(TKPS,"Macro name expected (@<...@> or @#c).");
- X recover();
- X }
- X ps_name=p_tk->tk_ps;
- X pr_name (name);
- X rem_name(name);
- X tb_loo(macro_table,PV name,PV &p_ma);
- X
- X /* Parse the optional formal parameter list and the equals. */
- X /* Extract positioning and other information. */
- X pr_formal(&numpar,&ps_form );
- X ASSIGN(ps_num,p_tk->tk_ps);
- X pr_number(&iszer, &isman);
- X pr_equals(&isadd ,&ps_equal);
- X
- X /* Perform semantic checks on whether this definition is valid. */
- X checkdef(p_ma,is_file,numpar,iszer,isman,isadd,
- X &ps_name,&ps_form,&ps_equal,&ps_num);
- X
- X /* If we have got this far, we know that we have parsed a valid macro */
- X /* definition except possibly for the actual expression body. */
- X /* If this is the first definition of this macro, establish its definition. */
- X if (!p_ma->ma_defn.md_isdef)
- X {
- X p_ma->ma_defn.md_isdef = TRUE;
- X ASSIGN(p_ma->ma_defn.md_ps,ps_mac);
- X p_ma->ma_defn.md_npar = numpar;
- X p_ma->ma_defn.md_isadd = isadd;
- X p_ma->ma_defn.md_iszer = iszer;
- X p_ma->ma_defn.md_isman = isman;
- X p_ma->ma_defn.md_isfil = is_file;
- X p_ma->ma_defn.md_body = ls_cre(sizeof(bp_t));
- X if (is_file) tb_ins(file_table,PV name,PV &p_ma);
- X }
- X
- X /* Parse the body of this macro definition. */
- X pr_token(TK_ODEF); pr_exp(&ex,p_ma); pr_token(TK_CDEF);
- X
- X /* We are now clear to execute the effects of the macro on our tables. */
- X /* First we bump up the sequence number. */
- X sequence++;
- X
- X {
- X /* Construct a body part object containing the information in this */
- X /* definition and append it to the list of body parts in the macro record. */
- X bp_t bp;
- X bp.bp_ex = ex;
- X bp.bp_seq = sequence;
- X bp.bp_ps = ps_name;
- X ls_add(p_ma->ma_defn.md_body,PV &bp);
- X }
- X
- X {
- X /* Construct a document component object for this definition and append it */
- X /* to the global document component list. */
- X dc_t dc;
- X ASSIGN(dc.dc_ps,ps_mac);
- X dc.dc_kind = DC_MACR;
- X dc.dc_p_ma = p_ma;
- X dc.dc_part = ls_len(p_ma->ma_defn.md_body);
- X ls_add(document_list,PV &dc);
- X }
- X
- X /* Sections without names inherit the name of their first macro. */
- X if (sn_lev(&last_sn)>0 && !hasname)
- X strcpy(&p_secdc->dc_ty.ty_name[0],name);
- X}
- X
- X/******************************************************************************/
- X
- XEXPORT void parser()
- X/* This is the main parser function. This function contains parser */
- X/* initialization as well as the main parsing loop to which control is */
- X/* returned (by recover()) when an error occurs. */
- X{
- X /* Create the lists and tables generated by the parser. */
- X macro_table = tb_cre (sizeof(name_t),sizeof(p_ma_t),(p_kycm_t) cm_name);
- X file_table = tb_cre (sizeof(name_t),sizeof(p_ma_t),(p_kycm_t) cm_name);
- X document_list= ls_cre (sizeof(dc_t));
- X
- X /* Initialize the section number counter. */
- X sequence = 0;
- X sn_ini(&last_sn);
- X p_secdc = NULL;
- X
- X /* Prime the scanning of the token list. */
- X ls_fir(token_list);
- X next_tk(FALSE);
- X
- X /* This is where we longjmp back to after hitting a nasty syntax error. */
- X /* We don't actually have to test dummyint, as our control state is no */
- X /* different after a syntax error has occurred. Example: We try to parse */
- X /* a macro but there is a syntax error. So we skip to the start of the */
- X /* next macro and then longjmp back to here ready to parse the next */
- X /* macro. Thus, there is no need to a fork test. */
- X (void) setjmp(jmp_pos);
- X
- X /* This is the main parser loop which parses major syntactic chunks. */
- X while (p_tk->tk_kind != TK_EOF)
- X switch (p_tk->tk_kind)
- X {
- X case TK_NSEC: pr_sec (); break;
- X case TK_TEXT: pr_dctxt(); break;
- X case TK_MDEF: pr_macro(); break;
- X case TK_FDEF: pr_macro(); break;
- X case TK_ODEF: pr_lit (); break;
- X case TK_EMPH: pr_emp (); break;
- X case TK_NPAG: pr_npag (); break;
- X case TK_TOCS: pr_tocs (); break;
- X case TK_SKIP: pr_skip (); break;
- X case TK_TITL: pr_titl (); break;
- X default:
- X lr_err(TKPS,"The parser was at the top level and was expecting");
- X lr_mes(TKPS,"one of: {Directive, Text, Macro definition, EOF}.");
- X next_tk(FALSE);
- X break;
- X }
- X
- X}
- X
- X/******************************************************************************/
- X/* End of PARSER.C */
- X/******************************************************************************/
- END_OF_FILE
- if test 47198 -ne `wc -c <'sources/parser.c'`; then
- echo shar: \"'sources/parser.c'\" unpacked with wrong size!
- fi
- # end of 'sources/parser.c'
- fi
- echo shar: End of archive 15 \(of 20\).
- cp /dev/null ark15isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 20 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-