lex.c
上传用户:itx_2006
上传日期:2007-01-06
资源大小:493k
文件大小:22k
源码类别:

编译器/解释器

开发平台:

Others

  1. /*
  2.  * lex.c -- Generate all of the lexical type files: parser.dlg tokens.h
  3.  *
  4.  * SOFTWARE RIGHTS
  5.  *
  6.  * We reserve no LEGAL rights to the Purdue Compiler Construction Tool
  7.  * Set (PCCTS) -- PCCTS is in the public domain.  An individual or
  8.  * company may do whatever they wish with source code distributed with
  9.  * PCCTS or the code generated by PCCTS, including the incorporation of
  10.  * PCCTS, or its output, into commerical software.
  11.  *
  12.  * We encourage users to develop software with PCCTS.  However, we do ask
  13.  * that credit is given to us for developing PCCTS.  By "credit",
  14.  * we mean that if you incorporate our source code into one of your
  15.  * programs (commercial product, research project, or otherwise) that you
  16.  * acknowledge this fact somewhere in the documentation, research report,
  17.  * etc...  If you like PCCTS and have developed a nice tool with the
  18.  * output, please mention that you developed it using PCCTS.  In
  19.  * addition, we ask that this header remain intact in our source code.
  20.  * As long as these guidelines are kept, we expect to continue enhancing
  21.  * this system and expect to make other tools available as they are
  22.  * completed.
  23.  *
  24.  * ANTLR 1.33
  25.  * Terence Parr
  26.  * Parr Research Corporation
  27.  * with Purdue University and AHPCRC, University of Minnesota
  28.  * 1989-1998
  29.  */
  30. #include <stdio.h>
  31. #include <ctype.h>
  32. /* MR1                                                 */
  33. /* MR1  10-Apr-97  MR1 Replace use of __STDC__ with __USE_PROTOS     */
  34. /* MR1                                                         */
  35. #include "pcctscfg.h"
  36. #include "set.h"
  37. #include "syn.h"
  38. #include "hash.h"
  39. #include "generic.h"
  40. #define DLGErrorString "invalid token"
  41. /* Generate a complete lexical description of the lexemes found in the grammar */
  42. void
  43. #ifdef __USE_PROTOS
  44. genLexDescr( void )
  45. #else
  46. genLexDescr( )
  47. #endif
  48. {
  49. ListNode *p;
  50. FILE *dlgFile = fopen(OutMetaName(DlgFileName), "w");
  51. require(dlgFile!=NULL, eMsg1("genLexFile: cannot open %s", OutMetaName(DlgFileName)) );
  52. #if SPECIAL_FOPEN
  53. special_fopen_actions(OutMetaName(DlgFileName));              /* MR1 */
  54. #endif
  55. fprintf(dlgFile, "<<n");
  56. fprintf(dlgFile, "/* %s -- DLG Description of scannern", DlgFileName);
  57. fprintf(dlgFile, " *n");
  58. fprintf(dlgFile, " * Generated from:");
  59. {int i; for (i=0; i<NumFiles; i++) fprintf(dlgFile, " %s", FileStr[i]);}
  60. fprintf(dlgFile, "n");
  61. fprintf(dlgFile, " *n");
  62. fprintf(dlgFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1998n");
  63. fprintf(dlgFile, " * Purdue University Electrical Engineeringn");
  64. fprintf(dlgFile, " * With AHPCRC, University of Minnesotan");
  65. fprintf(dlgFile, " * ANTLR Version %sn", Version);
  66. fprintf(dlgFile, " */nn");
  67.     fprintf(dlgFile, "#define ANTLR_VERSION %sn", VersionDef);
  68.     if (FirstAction != NULL ) dumpAction( FirstAction, dlgFile, 0, -1, 0, 1 );  /* MR11 */
  69. if ( GenCC )
  70. {
  71. if ( !UserDefdTokens ) fprintf(dlgFile, "#include "%s"n", DefFileName);
  72. else fprintf(dlgFile, "#include %sn", UserTokenDefsFile);
  73. fprintf(dlgFile, "#include "%s"n", ATOKEN_H);
  74. if ( GenAST ) fprintf(dlgFile, "#include "%s"n", ASTBASE_H);
  75. if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
  76. }
  77. else
  78. {
  79. fprintf(dlgFile, "#include "pcctscfg.h"n");
  80. fprintf(dlgFile, "#include PCCTS_STDIO_Hn");
  81. if ( strcmp(ParserName, DefaultParserName)!=0 )
  82. fprintf(dlgFile, "#define %s %sn", DefaultParserName, ParserName);
  83. if ( strcmp(ParserName, DefaultParserName)!=0 )
  84. fprintf(dlgFile, "#include "%s"n", RemapFileName);
  85. if ( HdrAction != NULL ) dumpAction( HdrAction, dlgFile, 0, -1, 0, 1 );
  86. if ( FoundGuessBlk )
  87. {
  88. fprintf(dlgFile, "#define ZZCAN_GUESSn");
  89. fprintf(dlgFile, "#include PCCTS_SETJMP_Hn");
  90. }
  91. if ( OutputLL_k > 1 ) fprintf(dlgFile, "#define LL_K %dn", OutputLL_k);
  92. if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOKn");
  93. fprintf(dlgFile, "#include "antlr.h"n");
  94. if ( GenAST ) {
  95. fprintf(dlgFile, "#include "ast.h"n");
  96. }
  97. if ( UserDefdTokens )
  98. fprintf(dlgFile, "#include %sn", UserTokenDefsFile);
  99. /* still need this one as it has the func prototypes */
  100. fprintf(dlgFile, "#include "%s"n", DefFileName);
  101. fprintf(dlgFile, "#include "dlgdef.h"n");
  102. fprintf(dlgFile, "LOOKAHEADn");
  103. fprintf(dlgFile, "void zzerraction()n");
  104. fprintf(dlgFile, "{n");
  105. fprintf(dlgFile, "t(*zzerr)("%s");n", DLGErrorString);
  106. fprintf(dlgFile, "tzzadvance();n");
  107. fprintf(dlgFile, "tzzskip();n");
  108. fprintf(dlgFile, "}n");
  109. }
  110. fprintf(dlgFile, ">>nn");
  111. /* dump all actions */
  112. /* MR1                                     */
  113. /* MR1  11-Apr-97 Provide mechanism for inserting code into DLG class     */
  114. /* MR1         via <<%%lexmember ....>> & <<%%lexprefix ...>>            */
  115. /* MR1                      */
  116.           if (LexActions != NULL) {
  117.             for (p = LexActions->next; p!=NULL; p=p->next)
  118. {
  119. /* MR1 */ fprintf(dlgFile, "<<%%%%lexactionn");
  120. dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
  121. fprintf(dlgFile, ">>nn");
  122. }
  123.   };
  124. /* MR1 */ if (GenCC) {
  125. /* MR1 */   fprintf(dlgFile,"<<%%%%parserclass %s>>nn",CurrentClassName);
  126. /* MR1 */ };
  127. /* MR1 */ if (LexPrefixActions != NULL) {
  128. /* MR1 */   for (p = LexPrefixActions->next; p!=NULL; p=p->next)
  129. /* MR1 */       {
  130. /* MR1 */               fprintf(dlgFile, "<<%%%%lexprefixn");
  131. /* MR1 */               dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
  132. /* MR1 */               fprintf(dlgFile, ">>nn");
  133. /* MR1 */       }
  134. /* MR1 */ };
  135. /* MR1 */ if (LexMemberActions != NULL) {
  136. /* MR1 */   for (p = LexMemberActions->next; p!=NULL; p=p->next)
  137. /* MR1 */       {
  138. /* MR1 */               fprintf(dlgFile, "<<%%%%lexmembern");
  139. /* MR1 */               dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
  140. /* MR1 */               fprintf(dlgFile, ">>nn");
  141. /* MR1 */       }
  142. /* MR1 */ };
  143. /* dump all regular expression rules/actions (skip sentinel node) */
  144. if ( ExprOrder == NULL ) {
  145. warnNoFL("no regular expressions found in grammar");
  146. }
  147. else dumpLexClasses(dlgFile);
  148. fprintf(dlgFile, "%%%%n");
  149. fclose( dlgFile );
  150. }
  151. /* For each lexical class, scan ExprOrder looking for expressions
  152.  * in that lexical class.  Print out only those that match.
  153.  * Each element of the ExprOrder list has both an expr and an lclass
  154.  * field.
  155.  */
  156. void
  157. #ifdef __USE_PROTOS
  158. dumpLexClasses( FILE *dlgFile )
  159. #else
  160. dumpLexClasses( dlgFile )
  161. FILE *dlgFile;
  162. #endif
  163. {
  164. int i;
  165. TermEntry *t;
  166. ListNode *p;
  167. Expr *q;
  168. for (i=0; i<NumLexClasses; i++)
  169. {
  170. fprintf(dlgFile, "n%%%%%snn", lclass[i].classnum);
  171. for (p=ExprOrder->next; p!=NULL; p=p->next)
  172. {
  173. q = (Expr *) p->elem;
  174. if ( q->lclass != i ) continue;
  175. lexmode(i);
  176. t = (TermEntry *) hash_get(Texpr, q->expr);
  177. require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) );
  178. if ( t->token == EpToken ) continue;
  179. fprintf(dlgFile, "%snt<<n", StripQuotes(q->expr));
  180. /* replace " killed by StripQuotes() */
  181. q->expr[ strlen(q->expr) ] = '"';
  182. if ( !GenCC ) {
  183. if ( TokenString(t->token) != NULL )
  184. fprintf(dlgFile, "ttNLA = %s;n", TokenString(t->token));
  185. else
  186. fprintf(dlgFile, "ttNLA = %d;n", t->token);
  187. }
  188. if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 );
  189. if ( GenCC ) {
  190. if ( TokenString(t->token) != NULL )
  191. fprintf(dlgFile, "ttreturn %s;n", TokenString(t->token));
  192. else
  193. fprintf(dlgFile, "ttreturn (ANTLRTokenType)%d;n", t->token);
  194. }
  195. fprintf(dlgFile, "t>>nn");
  196. }
  197. }
  198. }
  199. /* Strip the leading path (if any) from a filename */
  200. char *
  201. #ifdef __USE_PROTOS
  202. StripPath( char *fileName )
  203. #else
  204. StripPath( fileName )
  205. char *fileName;
  206. #endif
  207. {
  208. char *p;
  209. static char dirSym[2] = DirectorySymbol;
  210. if(NULL != (p = strrchr(fileName, dirSym[0])))
  211. p++;
  212. else
  213. p = fileName;
  214. return(p);
  215. }
  216. /* Generate a list of #defines && list of struct definitions for
  217.  * aggregate retv's */
  218. void
  219. #ifdef __USE_PROTOS
  220. genDefFile( void )
  221. #else
  222. genDefFile( )
  223. #endif
  224. {
  225. int i;
  226. /* If C++ mode and #tokdef used, then don't need anything in here since
  227.  * C++ puts all definitions in the class file name.
  228.  */
  229. if ( GenCC && UserTokenDefsFile ) return;
  230.     if ( MR_Inhibit_Tokens_h_Gen) return;
  231. DefFile = fopen(OutMetaName(DefFileName), "w");
  232. require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) );
  233. #if SPECIAL_FOPEN
  234. special_fopen_actions(OutMetaName(DefFileName));              /* MR1 */
  235. #endif
  236. fprintf(DefFile, "#ifndef %sn", StripPath(gate_symbol(DefFileName)));
  237. fprintf(DefFile, "#define %sn", StripPath(gate_symbol(DefFileName)));
  238. fprintf(DefFile, "/* %s -- List of labelled tokens and stuffn", DefFileName);
  239. fprintf(DefFile, " *n");
  240. fprintf(DefFile, " * Generated from:");
  241. for (i=0; i<NumFiles; i++) fprintf(DefFile, " %s", FileStr[i]);
  242. fprintf(DefFile, "n");
  243. fprintf(DefFile, " *n");
  244. fprintf(DefFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1998n");
  245. fprintf(DefFile, " * Purdue University Electrical Engineeringn");
  246. fprintf(DefFile, " * ANTLR Version %sn", Version);
  247. fprintf(DefFile, " */n");
  248. if ( !GenCC && LexGen ) {
  249. fprintf(DefFile,"#define zzEOF_TOKEN %dn",
  250. TokenInd!=NULL?TokenInd[EofToken]:EofToken);
  251. }
  252. if ( !UserDefdTokens )
  253. {
  254. int first=1;
  255. if ( GenCC ) fprintf(DefFile, "enum ANTLRTokenType {n");
  256. for (i=1; i<TokenNum; i++)
  257. {
  258. /* Don't do EpToken or expr w/o labels */
  259. if ( TokenString(i)!=NULL && i != EpToken )
  260. {
  261. TermEntry *p;
  262. if ( WarningLevel>1 )
  263. {
  264. int j;
  265. /* look in all lexclasses for the reg expr */
  266. /* MR10  Derek Pappas                                                */
  267. /* MR10     A #tokclass doesn't have associated regular expressiones */
  268. /* MR10        so don't warn user about it's omission                */
  269.                     p = (TermEntry *) hash_get(Tname, TokenString(i));
  270.                     if (p != NULL && ! p->classname) {
  271.      for (j=0; j<NumLexClasses; j++)
  272.      {
  273.      lexmode(j);
  274.      if ( ExprString(i)!=NULL ) break;
  275.      }
  276.      if ( j>=NumLexClasses )
  277.      {
  278.      warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i)));
  279.      }
  280.                     };
  281. }
  282. require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL,
  283. "token not in sym tab when it should be");
  284. if ( !p->classname )
  285. {
  286. if ( GenCC ) {
  287. if ( !first ) fprintf(DefFile, ",n");
  288. first = 0;
  289. fprintf(DefFile, "t%s=%d", TokenString(i), i);
  290. }
  291. else
  292. fprintf(DefFile, "#define %s %dn", TokenString(i), i);
  293. }
  294. }
  295. }
  296. /* MR1                                     */
  297. /* MR1  10-Apr-97 133MR1 Prevent use of varying sizes of integer     */
  298. /* MR1 for the enum ANTLRTokenType                             */
  299. /* MR1            */
  300. if ( GenCC ) {                                  /* MR1 */
  301.      if ( !first ) fprintf(DefFile, ",n");                  /* MR14 */
  302.      fprintf(DefFile, "tDLGminToken=0");                    /* MR1 */
  303.      fprintf(DefFile, ",ntDLGmaxToken=9999};n");          /* MR1 */
  304.                 };                              /* MR1 */
  305. }
  306. if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag);
  307. fprintf(DefFile, "n#endifn");
  308. }
  309. void
  310. #ifdef __USE_PROTOS
  311. GenRemapFile( void )
  312. #else
  313. GenRemapFile( )
  314. #endif
  315. {
  316. if ( strcmp(ParserName, DefaultParserName)!=0 )
  317. {
  318. FILE *f;
  319. int i;
  320. f = fopen(OutMetaName(RemapFileName), "w");
  321. require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) );
  322. #ifdef SPECIAL_FOPEN
  323. special_fopen_actions(OutMetaName(RemapFileName));           /* MR1 */
  324. #endif
  325. fprintf(f, "/* %s -- List of symbols to remapn", RemapFileName);
  326. fprintf(f, " *n");
  327. fprintf(f, " * Generated from:");
  328. for (i=0; i<NumFiles; i++) fprintf(f, " %s", FileStr[i]);
  329. fprintf(f, "n");
  330. fprintf(f, " *n");
  331. fprintf(f, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-1998n");
  332. fprintf(f, " * Purdue University Electrical Engineeringn");
  333. fprintf(f, " * ANTLR Version %sn", Version);
  334. fprintf(f, " */n");
  335. GenRuleFuncRedefs(f, SynDiag);
  336. GenPredefinedSymbolRedefs(f);
  337. if ( GenAST ) GenASTSymbolRedefs(f);
  338. GenSetRedefs(f);
  339. fclose(f);
  340. }
  341. }
  342. /* Generate a bunch of #defines that rename all functions to be "ParserName_func" */
  343. void
  344. #ifdef __USE_PROTOS
  345. GenRuleFuncRedefs( FILE *f, Junction *p )
  346. #else
  347. GenRuleFuncRedefs( f, p )
  348. FILE *f;
  349. Junction *p;
  350. #endif
  351. {
  352. fprintf(f, "n/* rename rule functions to be 'ParserName_func' */n");
  353. while ( p!=NULL )
  354. {
  355. fprintf(f, "#define %s %s_%sn", p->rname, ParserName, p->rname);
  356. p = (Junction *)p->p2;
  357. }
  358. }
  359. /* Generate a bunch of #defines that rename all standard symbols to be
  360.  * "ParserName_symbol".  The list of standard symbols to change is in
  361.  * globals.c.
  362.  */
  363. void
  364. #ifdef __USE_PROTOS
  365. GenPredefinedSymbolRedefs( FILE *f )
  366. #else
  367. GenPredefinedSymbolRedefs( f )
  368. FILE *f;
  369. #endif
  370. {
  371. char **p;
  372. fprintf(f, "n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */n");
  373. for (p = &StandardSymbols[0]; *p!=NULL; p++)
  374. {
  375. fprintf(f, "#define %s %s_%sn", *p, ParserName, *p);
  376. }
  377. }
  378. /* Generate a bunch of #defines that rename all AST symbols to be
  379.  * "ParserName_symbol".  The list of AST symbols to change is in
  380.  * globals.c.
  381.  */
  382. void
  383. #ifdef __USE_PROTOS
  384. GenASTSymbolRedefs( FILE *f )
  385. #else
  386. GenASTSymbolRedefs( f )
  387. FILE *f;
  388. #endif
  389. {
  390. char **p;
  391. fprintf(f, "n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */n");
  392. for (p = &ASTSymbols[0]; *p!=NULL; p++)
  393. {
  394. fprintf(f, "#define %s %s_%sn", *p, ParserName, *p);
  395. }
  396. }
  397. /* redefine all sets generated by ANTLR; WARNING:  'zzerr', 'setwd' must match
  398.  * use in bits.c (DumpSetWd() etc...)
  399.  */
  400. void
  401. #ifdef __USE_PROTOS
  402. GenSetRedefs( FILE *f )
  403. #else
  404. GenSetRedefs( f )
  405. FILE *f;
  406. #endif
  407. {
  408. int i;
  409. for (i=1; i<=wordnum; i++)
  410. {
  411. fprintf(f, "#define setwd%d %s_setwd%dn", i, ParserName, i);
  412. }
  413. for (i=1; i<=esetnum; i++)
  414. {
  415. fprintf(f, "#define zzerr%d %s_err%dn", i, ParserName, i);
  416. }
  417. }
  418. /* Find all return types/parameters that require structs and def
  419.  * all rules with ret types.
  420.  */
  421. void
  422. #ifdef __USE_PROTOS
  423. GenRulePrototypes( FILE *f, Junction *p )
  424. #else
  425. GenRulePrototypes( f, p )
  426. FILE *f;
  427. Junction *p;
  428. #endif
  429. {
  430. int i;
  431. i = 1;
  432. while ( p!=NULL )
  433. {
  434. if ( p->ret != NULL )
  435. {
  436. if ( HasComma(p->ret) )
  437. {
  438. DumpRetValStruct(f, p->ret, i);
  439. }
  440. fprintf(f, "n#ifdef __USE_PROTOSn");
  441. if ( HasComma(p->ret) )
  442. {
  443. fprintf(f, "extern struct _rv%d", i);
  444. }
  445. else
  446. {
  447. fprintf(f, "extern ");
  448. DumpType(p->ret, f);
  449. }
  450. fprintf(f, " %s%s(", RulePrefix, p->rname);
  451. DumpANSIFunctionArgDef(f,p);
  452. fprintf(f, ";n");
  453. #ifdef OLD
  454. if ( p->pdecl != NULL || GenAST )
  455. {
  456. if ( GenAST ) {
  457. fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
  458. }
  459. if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  460. }
  461. else fprintf(f, "void");
  462. fprintf(f, ");n");
  463. #endif
  464. fprintf(f, "#elsen");
  465. if ( HasComma(p->ret) )
  466. {
  467. fprintf(f, "extern struct _rv%d", i);
  468. }
  469. else
  470. {
  471. fprintf(f, "extern ");
  472. DumpType(p->ret, f);
  473. }
  474. fprintf(f, " %s%s();n", RulePrefix, p->rname);
  475. fprintf(f, "#endifn");
  476. }
  477. else
  478. {
  479. fprintf(f, "n#ifdef __USE_PROTOSn");
  480. fprintf(f, "void %s%s(", RulePrefix, p->rname);
  481. DumpANSIFunctionArgDef(f,p);
  482. fprintf(f, ";n");
  483. #ifdef OLD
  484. if ( p->pdecl != NULL || GenAST )
  485. {
  486. if ( GenAST ) {
  487. fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
  488. }
  489. if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  490. }
  491. else fprintf(f, "void");
  492. fprintf(f, ");n");
  493. #endif
  494. fprintf(f, "#elsen");
  495. fprintf(f, "extern void %s%s();n", RulePrefix, p->rname);
  496. fprintf(f, "#endifn");
  497. }
  498. i++;
  499. p = (Junction *)p->p2;
  500. }
  501. }
  502. /* Define all rules in the class.h file; generate any required
  503.  * struct definitions first, however.
  504.  */
  505. void
  506. #ifdef __USE_PROTOS
  507. GenRuleMemberDeclarationsForCC( FILE *f, Junction *q )
  508. #else
  509. GenRuleMemberDeclarationsForCC( f, q )
  510. FILE *f;
  511. Junction *q;
  512. #endif
  513. {
  514. Junction *p = q;
  515. int i;
  516. fprintf(f, "private:n");
  517. /* Dump dflt handler declaration */
  518. fprintf(f, "tvoid zzdflthandlers( int _signal, int *_retsignal );nn");
  519. fprintf(f, "public:n");
  520. /* Dump return value structs */
  521. i = 1;
  522. while ( p!=NULL )
  523. {
  524. if ( p->ret != NULL )
  525. {
  526. if ( HasComma(p->ret) )
  527. {
  528. DumpRetValStruct(f, p->ret, i);
  529. }
  530. }
  531. i++;
  532. p = (Junction *)p->p2;
  533. }
  534. /* Dump member func defs && CONSTRUCTOR */
  535. fprintf(f, "t%s(ANTLRTokenBuffer *input);n", CurrentClassName);
  536. /*
  537. fprintf(f, "t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);n",
  538.    CurrentClassName);
  539. */
  540. i = 1;
  541. p = q;
  542. while ( p!=NULL )
  543. {
  544. if ( p->ret != NULL )
  545. {
  546. if ( HasComma(p->ret) )
  547. {
  548. fprintf(f, "tstruct _rv%d", i);
  549. }
  550. else
  551. {
  552. fprintf(f, "t");
  553. DumpType(p->ret, f);
  554. }
  555. fprintf(f, " %s%s(",RulePrefix,p->rname);
  556. DumpANSIFunctionArgDef(f,p);
  557. fprintf(f, ";n");
  558. #ifdef OLD
  559. if ( p->pdecl != NULL || GenAST )
  560. {
  561. if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
  562. if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  563. }
  564. fprintf(f, ");n");
  565. #endif
  566. }
  567. else
  568. {
  569. fprintf(f, "tvoid %s%s(",RulePrefix,p->rname);
  570. DumpANSIFunctionArgDef(f,p);
  571. fprintf(f, ";n");
  572. #ifdef OLD
  573. if ( p->pdecl != NULL || GenAST )
  574. {
  575. if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
  576. if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  577. }
  578. fprintf(f, ");n");
  579. #endif
  580. }
  581. i++;
  582. p = (Junction *)p->p2;
  583. }
  584. }
  585. /* Given a list of ANSI-style parameter declarations, print out a
  586.  * comma-separated list of the symbols (w/o types).
  587.  * Basically, we look for a comma, then work backwards until start of
  588.  * the symbol name.  Then print it out until 1st non-alnum char.  Now,
  589.  * move on to next parameter.
  590.  *
  591.  */
  592. /* MR5  Jan Mikkelsen 26-May-97 - added initalComma parameter              */
  593. void
  594. #ifdef __USE_PROTOS
  595. DumpListOfParmNames( char *pdecl, FILE *output, int initialComma )  /* MR5 */
  596. #else
  597. DumpListOfParmNames( pdecl, output, initialComma )     /* MR5 */
  598. char *pdecl;                        /* MR5 */
  599. FILE *output;                             /* MR5 */
  600. int initialComma;                                         /* MR5 */
  601. #endif
  602. {
  603. int firstTime = 1, done = 0;
  604. require(output!=NULL, "DumpListOfParmNames: NULL parm");
  605. if ( pdecl == NULL ) return;
  606. while ( !done )
  607. {
  608. if ( !firstTime || initialComma ) putc(',', output);        /* MR5 */
  609. done = DumpNextNameInDef(&pdecl, output);
  610. firstTime = 0;
  611. }
  612. }
  613. /* given a list of parameters or return values, dump the next
  614.  * name to output.  Return 1 if last one just printed, 0 if more to go.
  615.  */
  616. int
  617. #ifdef __USE_PROTOS
  618. DumpNextNameInDef( char **q, FILE *output )
  619. #else
  620. DumpNextNameInDef( q, output )
  621. char **q;
  622. FILE *output;
  623. #endif
  624. {
  625. char *p = *q; /* where did we leave off? */
  626. int done=0;
  627. while ( *p!='' && *p!=',' ) p++; /* find end of decl */
  628. if ( *p == '' ) done = 1;
  629. while ( !isalnum(*p) && *p!='_' ) --p; /* scan back until valid var character */
  630. while ( isalnum(*p) || *p=='_' ) --p; /* scan back until beginning of variable */
  631. p++; /* move to start of variable */
  632. while ( isalnum(*p) || *p=='_'  ) {putc(*p, output); p++;}
  633. while ( *p!='' && *p!=',' ) p++; /* find end of decl */
  634. p++; /* move past this parameter */
  635. *q = p; /* record where we left off */
  636. return done;
  637. }
  638. /* Given a list of ANSI-style parameter declarations, dump K&R-style
  639.  * declarations, one per line for each parameter.  Basically, convert
  640.  * comma to semi-colon, newline.
  641.  */
  642. void
  643. #ifdef __USE_PROTOS
  644. DumpOldStyleParms( char *pdecl, FILE *output )
  645. #else
  646. DumpOldStyleParms( pdecl, output )
  647. char *pdecl;
  648. FILE *output;
  649. #endif
  650. {
  651. require(output!=NULL, "DumpOldStyleParms: NULL parm");
  652. if ( pdecl == NULL ) return;
  653. while ( *pdecl != '' )
  654. {
  655. if ( *pdecl == ',' )
  656. {
  657. pdecl++;
  658. putc(';', output); putc('n', output);
  659. while ( *pdecl==' ' || *pdecl=='t' || *pdecl=='n' ) pdecl++;
  660. }
  661. else {putc(*pdecl, output); pdecl++;}
  662. }
  663. putc(';', output);
  664. putc('n', output);
  665. }
  666. /* Take in a type definition (type + symbol) and print out type only */
  667. void
  668. #ifdef __USE_PROTOS
  669. DumpType( char *s, FILE *f )
  670. #else
  671. DumpType( s, f )
  672. char *s;
  673. FILE *f;
  674. #endif
  675. {
  676. char *p, *end;
  677. require(s!=NULL, "DumpType: invalid type string");
  678. p = &s[strlen(s)-1]; /* start at end of string and work back */
  679. /* MR11 */
  680. /* scan back until valid variable character */
  681. while ( !isalnum(*p) && *p!='_' ) --p;
  682. /* scan back until beginning of variable */
  683. while ( isalnum(*p) || *p=='_' ) --p;
  684. if ( p<=s )
  685. {
  686. warnNoFL(eMsg1("invalid parameter/return value: '%s'",s));
  687. return;
  688. }
  689. end = p; /* here is where we stop printing alnum */
  690. p = s;
  691. while ( p!=end ) {putc(*p, f); p++;} /* dump until just before variable */
  692. while ( *p!='' )  /* dump rest w/o variable */
  693. {
  694. if ( !isalnum(*p) && *p!='_' ) putc(*p, f);
  695. p++;
  696. }
  697. }
  698. /* check to see if string e is a word in string s */
  699. int
  700. #ifdef __USE_PROTOS
  701. strmember( char *s, char *e )
  702. #else
  703. strmember( s, e )
  704. char *s;
  705. char *e;
  706. #endif
  707. {
  708.     register char *p;
  709.     require(s!=NULL&&e!=NULL, "strmember: NULL string");
  710.     if ( *e=='' ) return 1;   /* empty string is always member */
  711.     do {
  712. while ( *s!='' && !isalnum(*s) && *s!='_' )
  713. ++s;
  714. p = e;
  715. while ( *p!='' && *p==*s ) {p++; s++;}
  716. if ( *p=='' ) {
  717.     if ( *s=='' ) return 1;
  718.     if ( !isalnum (*s) && *s != '_' ) return 1;
  719. }
  720. while ( isalnum(*s) || *s == '_' )
  721. ++s;
  722.     } while ( *s!='' );
  723.     return 0;
  724. }
  725. int
  726. #ifdef __USE_PROTOS
  727. HasComma( char *s )
  728. #else
  729. HasComma( s )
  730. char *s;
  731. #endif
  732. {
  733. while (*s!='')
  734. if ( *s++ == ',' ) return 1;
  735. return 0;
  736. }
  737. void
  738. #ifdef __USE_PROTOS
  739. DumpRetValStruct( FILE *f, char *ret, int i )
  740. #else
  741. DumpRetValStruct( f, ret, i )
  742. FILE *f;
  743. char *ret;
  744. int i;
  745. #endif
  746. {
  747. fprintf(f, "nstruct _rv%d {n", i);
  748. while ( *ret != '' )
  749. {
  750.  while ( *ret==' ' || *ret=='t' ) ret++; /* ignore white */
  751.  putc('t', f);
  752.  while ( *ret!=',' && *ret!='' ) {putc(*ret,f); ret++;}
  753.  if ( *ret == ',' ) {putc(';', f); putc('n', f); ret++;}
  754. }
  755. fprintf(f, ";n};n");
  756. }
  757. /* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */
  758. char *
  759. #ifdef __USE_PROTOS
  760. StripQuotes( char *s )
  761. #else
  762. StripQuotes( s )
  763. char *s;
  764. #endif
  765. {
  766. if ( *s == '"' )
  767. {
  768. s[ strlen(s)-1 ] = '';    /* remove last quote */
  769. return( s+1 ); /* return address past initial quote */
  770. }
  771. return( s );
  772. }