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