8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / lib / libpp / common / pp.3
blob988185bd24ae34e17139907892db5642871fcc04
1 .fp 5 CW
2 .de L           \" literal font
3 .ft 5
4 .if !\a\\$1\a\a \&\\$1 \\$2 \\$3 \\$4 \\$5 \\$6 \f1
5 ..
6 .de LR
7 .}S 5 1 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
8 ..
9 .de RL
10 .}S 1 5 \& "\\$1" "\\$2" "\\$3" "\\$4" "\\$5" "\\$6"
12 .de EX          \" start example
13 .ta 1i 2i 3i 4i 5i 6i
14 .PP
15 .RS 
16 .PD 0
17 .ft 5
18 .nf
20 .de EE          \" end example
21 .fi
22 .ft
23 .PD
24 .RE
25 .PP
27 .TH PP 3
28 .SH NAME \" @(#)pp.3 (gsf@research.att.com) 04/01/92
29 pp \- ANSI C preprocessor library
30 .SH SYNOPSIS
31 .EX
32 :PACKAGE: ast
33 #include <pp.h>
34 %include "pptokens.yacc
35 \-lpp
36 .EE
37 .SH DESCRIPTION
38 The
39 .I pp
40 library provides a tokenizing implementation of the C language preprocessor
41 and supports K&R (Reiser), ANSI and C++ dialects.
42 The preprocessor is comprised of 12 public functions,
43 a global character class table accessed by macros, and
44 a single global struct with 10 public elements.
45 .PP
46 .I pp
47 operates in two modes.
48 .I Standalone
49 mode is used to implement the traditional standalone C preprocessor.
50 .I Tokeinizing
51 mode provides a function interface to a stream of preprocessed tokens.
52 .I pp
53 is by default ANSI; the only default predefined symbols are
54 .L __STDC__
55 and
56 .LR __STDPP__ .
57 Dialects (K&R, C++) and local conventions are determined by
58 compiler specific
59 .IR probe (1)
60 information that is included at runtime.
61 The
62 .I probe
63 information can be overridden by providing a file
64 .L pp_default.h
65 with pragmas and definitions for each compiler implementation.
66 This file is usually located in the compiler specific
67 default include directory.
68 .PP
69 Directive, command line argument, option and pragma syntax is described in
70 .IR cpp (1).
71 .I pp
72 specific semantics are described below.
73 Most semantic differences with standard or classic implementations are in the
74 form of optimizations.
75 .PP
76 Options and pragmas map to
77 .L ppop
78 function calls described below.
79 For the remaining descriptions,
80 ``setting \f5ppop(PP_\fP\fIoperation\fP\f5)\fP''
81 is a shorthand for calling
82 .L ppop
83 with the arguments appropriate for
84 \f5PP_\fP\fIoperation\fP.
85 .PP
86 The library interface describes only the public functions and struct elements.
87 Static structs and pointers to structs are provided by the library.
88 The user should not attempt to allocate structs.
89 In particular,
90 .L sizeof
91 is meaningless for
92 .I pp
93 supplied structs.
94 .PP
95 The global struct
96 .L pp
97 provides readonly information.
98 Any changes to
99 .L pp
100 must be done using the functions described below.
101 .L pp
102 has the following public elements:
104 .L "char* version"
106 .I pp
107 implementaion version string.
109 .L "char* lineid"
110 The current line sync directive name.
111 Used for standalone line sync output.
112 The default value is the empty string.
113 See the
114 .L ppline
115 function below.
117 .L "char* outfile"
118 The current output file name.
120 .L "char* pass"
121 The pragma pass name for
122 .I pp.
123 The default value is
124 .LR pp .
126 .L "char* token"
127 The string representation for the current input token.
129 .L "int flags"
130 The inclusive or of:
133 .L PP_comment
134 Set if 
135 .L ppop(PP_COMMENT)
136 was set.
138 .L PP_compatibility
139 Set if 
140 .L ppop(PP_COMPATIBILITY)
141 was set.
143 .L PP_linefile
144 Set if standalone line syncs require a file argument.
146 .L PP_linetype
147 Set if standalone line syncs require a third argument.
148 The third argument is
149 .L 1
150 for include file push,
151 .L 2
152 for include file pop and null otherwise.
154 .L PP_strict
155 Set if 
156 .L ppop(PP_STRICT)
157 was set.
159 .L PP_transition
160 Set if 
161 .L ppop(PP_TRANSITION)
162 was set.
165 .L "struct ppdirs* lcldirs"
166 The list of directories to be searched for "..." include files.
167 If the first directory name is "" then it is replaced by the
168 directory of the including file at include time.
169 The public elements of
170 .L "struct ppdirs"
171 are:
174 .L "char* name"
175 The directory pathname.
177 .L "struct ppdirs* next"
178 The next directory,
179 .L 0
180 if it is the last in the list.
183 .L "struct ppdirs* stddirs"
184 .L pp.stddirs\->next
185 is the list of directories to be searched for <...> include files.
186 This list may be
187 .LR 0 .
189 .L "struct ppsymbol* symbol"
191 .L ppop(PP_COMPILE)
192 was set then
193 .L pp.symbol
194 points to the symbol table entry for the current identifier token.
195 .L pp.symbol
196 is undefined for non-identifier tokens.
197 Once defined, an identifier will always have the same
198 .L ppsymbol
199 pointer.
201 .L ppop(PP_NOHASH)
202 was also set then
203 .L pp.symbol
204 is defined for macro and keyword tokens and
205 .L 0
206 for all other identifiers.
207 The elements of
208 .L "struct ppsymbol"
209 are:
212 .L "char* name"
213 The identifier name.
215 .L "int flags"
216 The inclusive or of the following flags:
217 .PD 0
220 .L SYM_ACTIVE
221 Currently being expanded.
223 .L SYM_BUILTIN
224 Builtin macro.
226 .L SYM_DISABLED
227 Macro expansion currently disabled.
229 .L SYM_FUNCTION
230 Function-like macro.
232 .L SYM_INIT
233 Initialization macro.
235 .L SYM_KEYWORD
236 Keyword identifier.
238 .L SYM_LOADED
239 Loaded checkpoint macro.
241 .L SYM_MULTILINE
242 .L #macdef
243 macro.
245 .L SYM_NOEXPAND
246 No identifiers in macro body.
248 .L SYM_PREDEFINED
249 Predefined macro.
251 .L SYM_PREDICATE
252 Also a
253 .L #assert
254 predicate.
256 .L SYM_READONLY
257 Readonly macro.
259 .L SYM_REDEFINE
260 Ok to redefine.
262 .L SYM_VARIADIC
263 Variadic function-like macro.
265 .L SYM_UNUSED
266 First unused symbol flag bit index.
267 The bits from
268 .L (1<<SYM_UNUSED)
269 on are initially unset and may be set by the user.
273 .L "struct ppmacro* macro"
274 Non-zero if the identifier is a macro.
275 .L "int macro\->arity"
276 is the number of formal arguments for function-like macros and
277 .L "char* macro\->value"
278 is the macro definition value, a
279 .L 0
280 terminated string that may contain internal mark sequences.
282 .L "char* value"
283 Initially set to
284 .L 0
285 and never modified by
286 .IR pp .
287 This field may be set by the user.
290 .L "Hash_table_t* symtab"
291 The macro and identifier
292 .L "struct ppsymbol"
293 hash table.
295 .IR hash (3)
296 routines may be used to examine the table, with the exception that the
297 following macros must be used for individual
298 .L pp.symtab
299 symbol lookup:
302 .L "struct ppsymbol* ppsymget(Hash_table_t* table, char* name)"
303 Return the
304 .L ppsymbol
305 pointer for
306 .LR name ,
307 0 if
308 .L name
309 not defined.
311 .L "struct ppsymbol* ppsymset(Hash_table_t* table, char* name)"
312 Return the
313 .L ppsymbol
314 pointer for
315 .LR name .
317 .L name
318 is not defined then allocate and return a new
319 .L ppsymbol
320 for it.
324 Error messages are reported using
325 .IR error (3)
326 and the following globals relate to
327 .IR pp :
329 .L "int error_info.errors"
330 The level 2 error count.
331 Error levels above 2 cause immediate exit.
333 .L error_info.errors
334 is non-zero then the user program exit status should also be non-zero.
336 .L "char* error_info.file"
337 The current input file name.
339 .L "int error_info.line"
340 The current input line number.
342 .L "int error_info.trace"
343 The debug trace level,
344 .L 0
345 by default.
346 Larger negative numbers produce more trace information.
347 Enabled when the user program is linked with the
348 .B \-g
349 .IR cc (1)
350 option.
352 .L "int error_info.warnings"
353 The level 1 error count.
354 Warnings do not affect the exit status.
356 The functions are:
358 .L "extern int ppargs(char** argv, int last);"
359 Passed to
360 .IR optjoin (3)
361 to parse
362 .IR cpp (1)
363 style options and arguments.
364 The user may also supply application specific option parsers.
365 Also handles non-standard options like the sun
366 .L \-undef
367 and GNU
368 .LR \-trigraphs .
369 Hello in there, ever here of
370 .IR getopt (3)?
372 .L "extern void ppcpp(void);"
373 This is the standalone
374 .IR cpp (1)
375 entry point.
376 .L ppcpp
377 consumes all of the input and writes the preprocessed text to the output.
378 A single call to
379 .L ppcpp
380 is equivalent to, but more efficient than:
382     ppop(PP_SPACEOUT, 1);
383     while (pplex())
384         ppprintf(" %s", pp.token);
387 .L "extern int ppcomment(char* head, char* comment, char* tail, int line);"
388 The default comment handler that passes comments to the output.
389 May be used as an argument to
390 .LR ppop(PP_COMMENT) ,
391 or the user may supply an application specific handler.
392 .L head
393 is the comment head text,
394 .L "/*"
395 for C and
396 .L "//"
397 for C++,
398 .L comment
399 is the comment body,
400 .L tail
401 is the comment tail text,
402 .L "*/"
403 for C and
404 .B newline
405 for C++, and
406 .L line
407 is the comment starting line number.
409 .L "extern void pperror(int level, char* format, ...);"
410 Equivalent to
411 .IR error (3).
413 .I pp
414 error and warning messages pass through
415 .LR pperror .
416 The user may link with an application specific
417 .L pperror
418 to override the library default.
420 .L "extern int ppincref(char* parent, char* file, int line, int push);"
421 The default include reference handler that outputs
422 .L file
423 to the standard error.
424 May be used as an argument to the
425 .LR ppop(PP_INCREF) ,
426 or the user may supply an application specific handler.
427 .L parent
428 is the including file name,
429 .L file
430 is the current include file name,
431 .L line
432 is the current line number in
433 .LR file ,
434 and 
435 .L push
436 is non-zero if
437 .L file
438 is being pushed or
439 .L 0
440 if file is being popped.
442 .L "extern void ppinput(char* buffer, char* file, int line);"
443 Pushes the
444 .L 0
445 terminated
446 .L buffer
447 on the
448 .I pp
449 input stack.
450 .L file
451 is the pseudo file name used in line syncs for
452 .L buffer
454 .L line
455 is the starting line number.
457 .L "int pplex(void)"
458 Returns the token type of the next input token.
459 .L pp.token
460 and where applicable
461 .L pp.symbol
462 are updated to refer to the new token.
463 The token type constants are defined in
464 .L pp.h
466 .L #include
468 .L pp.yacc
470 .IR yacc (1)
471 .LR %include .
472 The token constant names match
473 .LR T_[A-Z_]* ;
474 some are encoded by oring with
475 .L N_[A-Z_]*
476 tokens.
478 The numeric constant tokens and encodings are:
480     T_DOUBLE          (N_NUMBER|N_REAL)
481     T_DOUBLE_L        (N_NUMBER|N_REAL|N_LONG)
482     T_FLOAT           (N_NUMBER|N_REAL|N_FLOAT)
483     T_DECIMAL         (N_NUMBER)
484     T_DECIMAL_L       (N_NUMBER|N_LONG)
485     T_DECIMAL_U       (N_NUMBER|N_UNSIGNED)
486     T_DECIMAL_UL      (N_NUMBER|N_UNSIGNED|N_LONG)
487     T_OCTAL           (N_NUMBER|N_OCTAL)
488     T_OCTAL_L         (N_NUMBER|N_OCTAL|N_LONG)
489     T_OCTAL_U         (N_NUMBER|N_OCTAL|N_UNSIGNED)
490     T_OCTAL_UL        (N_NUMBER|N_OCTAL|N_UNSIGNED|N_LONG)
491     T_HEXADECIMAL     (N_NUMBER|N_HEXADECIMAL)
492     T_HEXADECIMAL_L   (N_NUMBER|N_HEXADECIMAL|N_LONG)
493     T_HEXADECIMAL_U   (N_NUMBER|N_HEXADECIMAL|N_UNSIGNED)
494     T_HEXADECIMAL_UL  (N_NUMBER|N_HEXADECIMAL|N_UNSIGNED|N_LONG)
496 The normal C tokens are:
498     T_ID              \fIC identifier\fP
499     T_INVALID         \fIinvalid token\fP
500     T_HEADER          <..>
501     T_CHARCONST       '..'
502     T_WCHARCONST      L'..'
503     T_STRING          ".."
504     T_WSTRING         L".."
505     T_PTRMEM          ->
506     T_ADDADD          ++
507     T_SUBSUB          --
508     T_LSHIFT          <<
509     T_RSHIFT          >>
510     T_LE              <=
511     T_GE              >=
512     T_EQ              ==
513     T_NE              !=
514     T_ANDAND          &&
515     T_OROR            ||
516     T_MPYEQ           *=
517     T_DIVEQ           /=
518     T_MODEQ           %=
519     T_ADDEQ           +=
520     T_SUBEQ           -=
521     T_LSHIFTEQ        <<=
522     T_RSHIFTEQ        >>=
523     T_ANDEQ           &=
524     T_XOREQ           ^=
525     T_OREQ            |=
526     T_TOKCAT          ##
527     T_VARIADIC        ...
528     T_DOTREF          .*    [\fIif\fP PP_PLUSPLUS]
529     T_PTRMEMREF       ->*   [\fIif\fP PP_PLUSPLUS]
530     T_SCOPE           ::    [\fIif\fP PP_PLUSPLUS]
531     T_UMINUS          \fIunary minus\fP
534 .L ppop(PP_COMPILE)
535 was set then the keyword tokens are also defined.
536 Compiler differences and dialects are detected by the
537 .I pp
538 .IR probe (1)
539 information, and only the appropriate keywords are enabled.
540 The ANSI keyword tokens are:
542 T_AUTO          T_BREAK          T_CASE           T_CHAR
543 T_CONTINUE      T_DEFAULT        T_DO             T_DOUBLE_T
544 T_ELSE          T_EXTERN         T_FLOAT_T        T_FOR
545 T_GOTO          T_IF             T_INT            T_LONG
546 T_REGISTER      T_RETURN         T_SHORT          T_SIZEOF
547 T_STATIC        T_STRUCT         T_SWITCH         T_TYPEDEF
548 T_UNION         T_UNSIGNED       T_WHILE          T_CONST
549 T_ENUM          T_SIGNED         T_VOID           T_VOLATILE
551 and the C++ keyword tokens are:
553 T_CATCH         T_CLASS          T_DELETE         T_FRIEND
554 T_INLINE        T_NEW            T_OPERATOR       T_OVERLOAD
555 T_PRIVATE       T_PROTECTED      T_PUBLIC         T_TEMPLATE
556 T_THIS          T_THROW          T_TRY            T_VIRTUAL
558 In addition,
559 .L T_ASM
560 is recognized where appropriate.
561 Additional keyword tokens
562 .L ">= T_KEYWORD"
563 may be added using
564 .LR ppop(PP_COMPILE) .
566 Many C implementations show no restraint in adding new keywords; some
567 PC compilers have tripled the number of keywords.
568 For the most part these new keywords introduce noise constructs that
569 can be ignored for standard
570 .RI ( reasonable )
571 analysis and compilation.
572 The noise keywords fall in four syntactic categories that map into the two
573 noise keyword tokens
574 .L T_NOISE 
575 and 
576 .LR T_NOISES .
578 .L T_NOISES
579 .L pp.token
580 points to the entire noise construct, including the offending noise keyword.
581 The basic noise keyword categories are:
584 .L T_NOISE
585 The simplest noise: a single keyword that is noise in any context and maps to
586 .LR T_NOISE .
588 .L T_X_GROUP
589 A noise keyword that precedes an optional grouping construct, either
590 .L "(..)"
592 .L "{..}"
593 and maps to
594 .LR T_NOISES .
596 .L T_X_LINE
597 A noise keyword that consumes the remaining tokens in the line
598 and maps to
599 .LR T_NOISES .
601 .L T_X_STATEMENT
602 A noise keyword that consumes the tokens up to the next
603 .L ;
604 and maps to
605 .LR T_NOISES .
609 .L ppop(PP_NOISE)
611 .L "> 0"
612 then implementation specific noise constructs are mapped to either
613 .L T_NOISE
615 .L T_NOISES ,
616 otherwise if
617 .L ppop(PP_NOISE)
619 .L "< 0"
620 then noise constructs are completely ignored,
621 otherwise the unmapped grouping noise tokens
622 .L T_X_.*
623 are returned.
625 Token encodings may be tested by the following macros:
628 .L "int isnumber(int token);"
629 Non-zero if
630 .L token
631 is an integral or floating point numeric constant.
633 .L "int isinteger(int token);"
634 Non-zero if
635 .L token
636 is an integral numeric constant.
638 .L "int isreal(int token);"
639 Non-zero if
640 .L token
641 is a floating point numeric constant.
643 .L "int isassignop(int token);"
644 Non-zero if
645 .L token
646 is a C assignment operator.
648 .L "int isseparate(int token);"
649 Non-zero if
650 .L token
651 must be separated from other tokens by
652 .BR space .
654 .L "int isnoise(int token);"
655 Non-zero if
656 .L token
657 is a noise keyword.
660 .L "extern int ppline(int line, char* file);"
661 The default line sync handler that outputs line sync pragmas for the C compiler
662 front end.
663 May be used as an argument to
664 .LR ppop(PP_LINE) ,
665 or the user may supply an application specific handler.
666 .L line
667 is the line number and
668 .L file
669 is the file name.
671 .L ppop(PP_LINEID)
672 was set then the directive
673 \fB#\fP \fIlineid line \fP"\fIfile\fP" is output.
675 .L "extern int ppmacref(struct ppsymbol* symbol, char* file, int line, int type);"
676 The default macro reference handler that outputs a macro reference pragmas.
677 May be used as an argument to
678 .LR ppop(PP_MACREF) ,
679 or the user may supply an application specific handler.
680 .L symbol
681 is the macro
682 .L ppsymbol
683 pointer,
684 .L file
685 is the reference file,
686 .L line
687 is the reference line,
688 and if
689 .L type
690 is non-zero a macro value checksum is also output.
691 The pragma syntax is
692 \fB#pragma pp:macref\fP "\fIsymbol\->name\fP" \fIline checksum\fP.
694 .L "int ppop(int op, ...)"
695 .L ppop
696 is the option control interface.
697 .L op
698 determines the type(s) of the remaining argument(s).
699 Options marked by
700 .L "/*INIT*/"
701 must be done before
702 .LR PP_INIT .
705 .L "(PP_ASSERT, char* string) /*INIT*/"
706 .L string
707 is asserted as if by
708 .LR #assert .
710 .L "(PP_BUILTIN, char*(*fun)(char* buf, char* name, char* args)) /*INIT*/"
711 Installs 
712 .L fun
713 as the unknown builtin macro handler.
714 Builtin macros are of the form
715 .LR "#(name args)" .
716 .L fun 
717 is called with
718 .L name
719 set to the unknown builtin macro name and
720 .L args
721 set to the arguments.
722 .L buf
723 is a
724 .L MAXTOKEN+1
725 buffer that can be used for the
726 .L fun
727 return value.
728 .L 0
729 should be returned on error.
731 .L "(PP_COMMENT,void (*fun)(char*head,char*body,char*tail,int line) /*INIT*/"
733 .L "(PP_COMPATIBILITY, char* string) /*INIT*/"
735 .L "(PP_COMPILE, char* string) /*INIT*/"
737 .L "(PP_DEBUG, char* string) /*INIT*/"
739 .L "(PP_DEFAULT, char* string) /*INIT*/"
741 .L "(PP_DEFINE, char* string) /*INIT*/"
742 .L string
743 is defined as if by
744 .LR #define .
746 .L "(PP_DIRECTIVE, char* string) /*INIT*/"
747 The directive
748 .BI # string
749 is executed.
751 .L "(PP_DONE, char* string) /*INIT*/"
753 .L "(PP_DUMP, char* string) /*INIT*/"
755 .L "(PP_FILEDEPS, char* string) /*INIT*/"
757 .L "(PP_FILENAME, char* string) /*INIT*/"
759 .L "(PP_HOSTDIR, char* string) /*INIT*/"
761 .L "(PP_HOSTED, char* string) /*INIT*/"
763 .L "(PP_ID, char* string) /*INIT*/"
765 .L "(PP_IGNORE, char* string) /*INIT*/"
767 .L "(PP_INCLUDE, char* string) /*INIT*/"
769 .L "(PP_INCREF, char* string) /*INIT*/"
771 .L "(PP_INIT, char* string) /*INIT*/"
773 .L "(PP_INPUT, char* string) /*INIT*/"
775 .L "(PP_LINE, char* string) /*INIT*/"
777 .L "(PP_LINEFILE, char* string) /*INIT*/"
779 .L "(PP_LINEID, char* string) /*INIT*/"
781 .L "(PP_LINETYPE, char* string) /*INIT*/"
783 .L "(PP_LOCAL, char* string) /*INIT*/"
785 .L "(PP_MACREF, char* string) /*INIT*/"
787 .L "(PP_MULTIPLE, char* string) /*INIT*/"
789 .L "(PP_NOHASH, char* string) /*INIT*/"
791 .L "(PP_NOID, char* string) /*INIT*/"
793 .L "(PP_NOISE, char* string) /*INIT*/"
795 .L "(PP_OPTION, char* string) /*INIT*/"
796 The directive
797 \fB#pragma pp:\fP\fIstring\fP
798 is executed.
800 .L "(PP_OPTARG, char* string) /*INIT*/"
802 .L "(PP_OUTPUT, char* string) /*INIT*/"
804 .L "(PP_PASSNEWLINE, char* string) /*INIT*/"
806 .L "(PP_PASSTHROUGH, char* string) /*INIT*/"
808 .L "(PP_PLUSPLUS, char* string) /*INIT*/"
810 .L "(PP_PRAGMA, char* string) /*INIT*/"
812 .L "(PP_PREFIX, char* string) /*INIT*/"
814 .L "(PP_PROBE, char* string) /*INIT*/"
816 .L "(PP_READ, char* string) /*INIT*/"
818 .L "(PP_RESERVED, char* string) /*INIT*/"
820 .L "(PP_SPACEOUT, char* string) /*INIT*/"
822 .L "(PP_STANDALONE, char* string) /*INIT*/"
824 .L "(PP_STANDARD, char* string) /*INIT*/"
826 .L "(PP_STRICT, char* string) /*INIT*/"
828 .L "(PP_TEST, char* string) /*INIT*/"
830 .L "(PP_TRUNCATE, char* string) /*INIT*/"
832 .L "(PP_UNDEF, char* string) /*INIT*/"
834 .L "(PP_WARN, char* string) /*INIT*/"
837 .L "int pppragma(char* dir, char* pass, char* name, char* value, int nl);"
838 The default handler that
839 copies unknown directives and pragmas to the output.
840 May be used as an argument to
841 .LR ppop(PP_PRAGMA) ,
842 or the user may supply an application specific handler.
843 This function is most often called after directive and pragma mapping.
844 Any of the arguments may be
845 .LR 0 .
846 .L dir
847 is  the directive name,
848 .L pass
849 is the pragma pass name,
850 .L name
851 is the pragma option name,
852 .L value
853 is the pragma option value, and
854 .L nl
855 is non-zero
856 if a trailing newline is required if the pragma is copied to the output.
858 .L "int ppprintf(char* format, ...);"
860 .IR printf (3)
861 interface to the standalone
862 .I pp
863 output buffer.
864 Macros provide limited control over output buffering:
865 .L "void ppflushout()"
866 flushes the output buffer,
867 .L "void ppcheckout()"
868 flushes the output buffer if over
869 .L PPBUFSIZ
870 character are buffered,
871 .L "int pppendout()"
872 returns the number of pending character in the output buffer, and
873 .L "void ppputchar(int c)"
874 places the character
875 .L c
876 in the output buffer.
877 .SH CAVEATS
878 The ANSI mode is intended to be true to the standard.
879 The compatibility mode has been proven in practice, but there are
880 surely dark corners of some implementations that may have been omitted.
881 .SH "SEE ALSO"
882 cc(1), cpp(1), nmake(1), probe(1), yacc(1),
884 ast(3), error(3), hash(3), optjoin(3)
885 .SH AUTHOR
886 Glenn Fowler
888 (Dennis Ritchie provided the original table driven lexer.)
890 AT&T Bell Laboratories