lex.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878
  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-2001
  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. #ifdef SPECIAL_FOPEN
  53. special_fopen_actions(OutMetaName(DlgFileName)); /* MR1 */
  54. #endif
  55. fprintf(dlgFile, "<<\n");
  56. fprintf(dlgFile, "/* %s -- DLG Description of scanner\n", 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-2001\n");
  63. fprintf(dlgFile, " * Purdue University Electrical Engineering\n");
  64. fprintf(dlgFile, " * With AHPCRC, University of Minnesota\n");
  65. fprintf(dlgFile, " * ANTLR Version %s\n", Version);
  66. fprintf(dlgFile, " */\n\n");
  67. if (FirstAction != NULL ) dumpAction( FirstAction, dlgFile, 0, -1, 0, 1 ); /* MR11 MR15b */
  68. fprintf(dlgFile, "#define ANTLR_VERSION %s\n", VersionDef);
  69. if ( GenCC )
  70. {
  71. if ( !UserDefdTokens ) fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
  72. else fprintf(dlgFile, "#include %s\n", 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.h\"\n");
  81. if ( strcmp(ParserName, DefaultParserName)!=0 )
  82. fprintf(dlgFile, "#define %s %s\n", 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_GUESS\n");
  89. fprintf(dlgFile, "#include \"pccts_setjmp.h\"\n");
  90. }
  91. if ( OutputLL_k > 1 ) fprintf(dlgFile, "#define LL_K %d\n", OutputLL_k);
  92. if ( DemandLookahead ) fprintf(dlgFile, "#define DEMAND_LOOK\n");
  93. if (TraceGen) {
  94. fprintf(dlgFile,"#ifndef zzTRACE_RULES\n"); /* MR20 */
  95. fprintf(dlgFile,"#define zzTRACE_RULES\n"); /* MR20 */
  96. fprintf(dlgFile,"#endif\n"); /* MR22 */
  97. };
  98. fprintf(dlgFile, "#include \"antlr.h\"\n");
  99. if ( GenAST ) {
  100. fprintf(dlgFile, "#include \"ast.h\"\n");
  101. }
  102. if ( UserDefdTokens )
  103. fprintf(dlgFile, "#include %s\n", UserTokenDefsFile);
  104. /* still need this one as it has the func prototypes */
  105. fprintf(dlgFile, "#include \"%s\"\n", DefFileName);
  106. fprintf(dlgFile, "#include \"dlgdef.h\"\n");
  107. fprintf(dlgFile, "LOOKAHEAD\n");
  108. fprintf(dlgFile, "\n");
  109. fprintf(dlgFile, "void\n");
  110. fprintf(dlgFile, "#ifdef __USE_PROTOS\n");
  111. fprintf(dlgFile, "zzerraction(void)\n");
  112. fprintf(dlgFile, "#else\n");
  113. fprintf(dlgFile, "zzerraction()\n");
  114. fprintf(dlgFile, "#endif\n");
  115. fprintf(dlgFile, "{\n");
  116. fprintf(dlgFile, "\t(*zzerr)(\"%s\");\n", DLGErrorString);
  117. fprintf(dlgFile, "\tzzadvance();\n");
  118. fprintf(dlgFile, "\tzzskip();\n");
  119. fprintf(dlgFile, "}\n");
  120. }
  121. fprintf(dlgFile, ">>\n\n");
  122. /* dump all actions */
  123. /* MR1 */
  124. /* MR1 11-Apr-97 Provide mechanism for inserting code into DLG class */
  125. /* MR1 via <<%%lexmember ....>> & <<%%lexprefix ...>> */
  126. /* MR1 */
  127. if (LexActions != NULL) {
  128. for (p = LexActions->next; p!=NULL; p=p->next)
  129. {
  130. /* MR1 */ fprintf(dlgFile, "<<%%%%lexaction\n");
  131. dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
  132. fprintf(dlgFile, ">>\n\n");
  133. }
  134. };
  135. /* MR1 */ if (GenCC) {
  136. /* MR1 */ fprintf(dlgFile,"<<%%%%parserclass %s>>\n\n",CurrentClassName);
  137. /* MR1 */ };
  138. /* MR1 */ if (LexPrefixActions != NULL) {
  139. /* MR1 */ for (p = LexPrefixActions->next; p!=NULL; p=p->next)
  140. /* MR1 */ {
  141. /* MR1 */ fprintf(dlgFile, "<<%%%%lexprefix\n");
  142. /* MR1 */ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
  143. /* MR1 */ fprintf(dlgFile, ">>\n\n");
  144. /* MR1 */ }
  145. /* MR1 */ };
  146. /* MR1 */ if (LexMemberActions != NULL) {
  147. /* MR1 */ for (p = LexMemberActions->next; p!=NULL; p=p->next)
  148. /* MR1 */ {
  149. /* MR1 */ fprintf(dlgFile, "<<%%%%lexmember\n");
  150. /* MR1 */ dumpAction( (char *)p->elem, dlgFile, 0, -1, 0, 1 );
  151. /* MR1 */ fprintf(dlgFile, ">>\n\n");
  152. /* MR1 */ }
  153. /* MR1 */ };
  154. /* dump all regular expression rules/actions (skip sentinel node) */
  155. if ( ExprOrder == NULL ) {
  156. warnNoFL("no regular expressions found in grammar");
  157. }
  158. else dumpLexClasses(dlgFile);
  159. fprintf(dlgFile, "%%%%\n");
  160. fclose( dlgFile );
  161. }
  162. /* For each lexical class, scan ExprOrder looking for expressions
  163. * in that lexical class. Print out only those that match.
  164. * Each element of the ExprOrder list has both an expr and an lclass
  165. * field.
  166. */
  167. void
  168. #ifdef __USE_PROTOS
  169. dumpLexClasses( FILE *dlgFile )
  170. #else
  171. dumpLexClasses( dlgFile )
  172. FILE *dlgFile;
  173. #endif
  174. {
  175. int i;
  176. TermEntry *t;
  177. ListNode *p;
  178. Expr *q;
  179. for (i=0; i<NumLexClasses; i++)
  180. {
  181. fprintf(dlgFile, "\n%%%%%s\n\n", lclass[i].classnum);
  182. for (p=ExprOrder->next; p!=NULL; p=p->next)
  183. {
  184. q = (Expr *) p->elem;
  185. if ( q->lclass != i ) continue;
  186. lexmode(i);
  187. t = (TermEntry *) hash_get(Texpr, q->expr);
  188. require(t!=NULL, eMsg1("genLexDescr: rexpr %s not in hash table",q->expr) );
  189. if ( t->token == EpToken ) continue;
  190. fprintf(dlgFile, "%s\n\t<<\n", StripQuotes(q->expr));
  191. /* replace " killed by StripQuotes() */
  192. q->expr[ strlen(q->expr) ] = '"';
  193. if ( !GenCC ) {
  194. if ( TokenString(t->token) != NULL )
  195. fprintf(dlgFile, "\t\tNLA = %s;\n", TokenString(t->token));
  196. else
  197. fprintf(dlgFile, "\t\tNLA = %d;\n", t->token);
  198. }
  199. if ( t->action != NULL ) dumpAction( t->action, dlgFile, 2,-1,0,1 );
  200. if ( GenCC ) {
  201. if ( TokenString(t->token) != NULL )
  202. fprintf(dlgFile, "\t\treturn %s;\n", TokenString(t->token));
  203. else
  204. fprintf(dlgFile, "\t\treturn (ANTLRTokenType)%d;\n", t->token);
  205. }
  206. fprintf(dlgFile, "\t>>\n\n");
  207. }
  208. }
  209. }
  210. /* Strip the leading path (if any) from a filename */
  211. char *
  212. #ifdef __USE_PROTOS
  213. StripPath( char *fileName )
  214. #else
  215. StripPath( fileName )
  216. char *fileName;
  217. #endif
  218. {
  219. char *p;
  220. static char dirSym[2] = DirectorySymbol;
  221. if(NULL != (p = strrchr(fileName, dirSym[0])))
  222. p++;
  223. else
  224. p = fileName;
  225. return(p);
  226. }
  227. /* Generate a list of #defines && list of struct definitions for
  228. * aggregate retv's */
  229. void
  230. #ifdef __USE_PROTOS
  231. genDefFile( void )
  232. #else
  233. genDefFile( )
  234. #endif
  235. {
  236. int i;
  237. /* If C++ mode and #tokdef used, then don't need anything in here since
  238. * C++ puts all definitions in the class file name.
  239. */
  240. if ( GenCC && UserTokenDefsFile ) return;
  241. if ( MR_Inhibit_Tokens_h_Gen) return;
  242. DefFile = fopen(OutMetaName(DefFileName), "w");
  243. require(DefFile!=NULL, eMsg1("genDefFile: cannot open %s", OutMetaName(DefFileName)) );
  244. #ifdef SPECIAL_FOPEN
  245. special_fopen_actions(OutMetaName(DefFileName)); /* MR1 */
  246. #endif
  247. fprintf(DefFile, "#ifndef %s\n", StripPath(gate_symbol(DefFileName)));
  248. fprintf(DefFile, "#define %s\n", StripPath(gate_symbol(DefFileName)));
  249. fprintf(DefFile, "/* %s -- List of labelled tokens and stuff\n", DefFileName);
  250. fprintf(DefFile, " *\n");
  251. fprintf(DefFile, " * Generated from:");
  252. for (i=0; i<NumFiles; i++) fprintf(DefFile, " %s", FileStr[i]);
  253. fprintf(DefFile, "\n");
  254. fprintf(DefFile, " *\n");
  255. fprintf(DefFile, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
  256. fprintf(DefFile, " * Purdue University Electrical Engineering\n");
  257. fprintf(DefFile, " * ANTLR Version %s\n", Version);
  258. fprintf(DefFile, " */\n");
  259. if ( !GenCC && LexGen ) {
  260. fprintf(DefFile,"#define zzEOF_TOKEN %d\n",
  261. TokenInd!=NULL?TokenInd[EofToken]:EofToken);
  262. }
  263. if ( !UserDefdTokens )
  264. {
  265. int first=1;
  266. if ( GenCC ) fprintf(DefFile, "enum ANTLRTokenType {\n");
  267. for (i=1; i<TokenNum; i++)
  268. {
  269. /* Don't do EpToken or expr w/o labels */
  270. if ( TokenString(i)!=NULL && i != EpToken )
  271. {
  272. TermEntry *p;
  273. if ( WarningLevel>1 )
  274. {
  275. int j;
  276. /* look in all lexclasses for the reg expr */
  277. /* MR10 Derek Pappas */
  278. /* MR10 A #tokclass doesn't have associated regular expressiones */
  279. /* MR10 so don't warn user about it's omission */
  280. p = (TermEntry *) hash_get(Tname, TokenString(i));
  281. if (p != NULL && ! p->classname) {
  282. for (j=0; j<NumLexClasses; j++)
  283. {
  284. lexmode(j);
  285. if ( ExprString(i)!=NULL ) break;
  286. }
  287. if ( j>=NumLexClasses )
  288. {
  289. warnNoFL(eMsg1("token label has no associated rexpr: %s",TokenString(i)));
  290. }
  291. };
  292. }
  293. require((p=(TermEntry *)hash_get(Tname, TokenString(i))) != NULL,
  294. "token not in sym tab when it should be");
  295. if ( !p->classname )
  296. {
  297. if ( GenCC ) {
  298. if ( !first ) fprintf(DefFile, ",\n");
  299. first = 0;
  300. fprintf(DefFile, "\t%s=%d", TokenString(i), i);
  301. }
  302. else
  303. fprintf(DefFile, "#define %s %d\n", TokenString(i), i);
  304. }
  305. }
  306. }
  307. /* MR1 */
  308. /* MR1 10-Apr-97 133MR1 Prevent use of varying sizes of integer */
  309. /* MR1 for the enum ANTLRTokenType */
  310. /* MR1 */
  311. if ( GenCC ) { /* MR1 */
  312. if ( !first ) fprintf(DefFile, ",\n"); /* MR14 */
  313. fprintf(DefFile, "\tDLGminToken=0"); /* MR1 */
  314. fprintf(DefFile, ",\n\tDLGmaxToken=9999};\n"); /* MR1 */
  315. }; /* MR1 */
  316. }
  317. if ( !GenCC ) GenRulePrototypes(DefFile, SynDiag);
  318. fprintf(DefFile, "\n#endif\n");
  319. }
  320. void
  321. #ifdef __USE_PROTOS
  322. GenRemapFile( void )
  323. #else
  324. GenRemapFile( )
  325. #endif
  326. {
  327. if ( strcmp(ParserName, DefaultParserName)!=0 )
  328. {
  329. FILE *f;
  330. int i;
  331. f = fopen(OutMetaName(RemapFileName), "w");
  332. require(f!=NULL, eMsg1("GenRemapFile: cannot open %s", OutMetaName(RemapFileName)) );
  333. #ifdef SPECIAL_FOPEN
  334. special_fopen_actions(OutMetaName(RemapFileName)); /* MR1 */
  335. #endif
  336. fprintf(f, "/* %s -- List of symbols to remap\n", RemapFileName);
  337. fprintf(f, " *\n");
  338. fprintf(f, " * Generated from:");
  339. for (i=0; i<NumFiles; i++) fprintf(f, " %s", FileStr[i]);
  340. fprintf(f, "\n");
  341. fprintf(f, " *\n");
  342. fprintf(f, " * Terence Parr, Will Cohen, and Hank Dietz: 1989-2001\n");
  343. fprintf(f, " * Purdue University Electrical Engineering\n");
  344. fprintf(f, " * ANTLR Version %s\n", Version);
  345. fprintf(f, " */\n");
  346. GenRuleFuncRedefs(f, SynDiag);
  347. GenPredefinedSymbolRedefs(f);
  348. if ( GenAST ) GenASTSymbolRedefs(f);
  349. GenSetRedefs(f);
  350. fclose(f);
  351. }
  352. }
  353. /* Generate a bunch of #defines that rename all functions to be "ParserName_func" */
  354. void
  355. #ifdef __USE_PROTOS
  356. GenRuleFuncRedefs( FILE *f, Junction *p )
  357. #else
  358. GenRuleFuncRedefs( f, p )
  359. FILE *f;
  360. Junction *p;
  361. #endif
  362. {
  363. fprintf(f, "\n/* rename rule functions to be 'ParserName_func' */\n");
  364. while ( p!=NULL )
  365. {
  366. fprintf(f, "#define %s %s_%s\n", p->rname, ParserName, p->rname);
  367. p = (Junction *)p->p2;
  368. }
  369. }
  370. /* Generate a bunch of #defines that rename all standard symbols to be
  371. * "ParserName_symbol". The list of standard symbols to change is in
  372. * globals.c.
  373. */
  374. void
  375. #ifdef __USE_PROTOS
  376. GenPredefinedSymbolRedefs( FILE *f )
  377. #else
  378. GenPredefinedSymbolRedefs( f )
  379. FILE *f;
  380. #endif
  381. {
  382. char **p;
  383. fprintf(f, "\n/* rename PCCTS-supplied symbols to be 'ParserName_symbol' */\n");
  384. for (p = &StandardSymbols[0]; *p!=NULL; p++)
  385. {
  386. fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
  387. }
  388. }
  389. /* Generate a bunch of #defines that rename all AST symbols to be
  390. * "ParserName_symbol". The list of AST symbols to change is in
  391. * globals.c.
  392. */
  393. void
  394. #ifdef __USE_PROTOS
  395. GenASTSymbolRedefs( FILE *f )
  396. #else
  397. GenASTSymbolRedefs( f )
  398. FILE *f;
  399. #endif
  400. {
  401. char **p;
  402. fprintf(f, "\n/* rename PCCTS-supplied AST symbols to be 'ParserName_symbol' */\n");
  403. for (p = &ASTSymbols[0]; *p!=NULL; p++)
  404. {
  405. fprintf(f, "#define %s %s_%s\n", *p, ParserName, *p);
  406. }
  407. }
  408. /* redefine all sets generated by ANTLR; WARNING: 'zzerr', 'setwd' must match
  409. * use in bits.c (DumpSetWd() etc...)
  410. */
  411. void
  412. #ifdef __USE_PROTOS
  413. GenSetRedefs( FILE *f )
  414. #else
  415. GenSetRedefs( f )
  416. FILE *f;
  417. #endif
  418. {
  419. int i;
  420. for (i=1; i<=wordnum; i++)
  421. {
  422. fprintf(f, "#define setwd%d %s_setwd%d\n", i, ParserName, i);
  423. }
  424. for (i=1; i<=esetnum; i++)
  425. {
  426. fprintf(f, "#define zzerr%d %s_err%d\n", i, ParserName, i);
  427. }
  428. }
  429. /* Find all return types/parameters that require structs and def
  430. * all rules with ret types.
  431. *
  432. * This is for the declaration, not the definition.
  433. */
  434. void
  435. #ifdef __USE_PROTOS
  436. GenRulePrototypes( FILE *f, Junction *p )
  437. #else
  438. GenRulePrototypes( f, p )
  439. FILE *f;
  440. Junction *p;
  441. #endif
  442. {
  443. int i;
  444. i = 1;
  445. while ( p!=NULL )
  446. {
  447. if ( p->ret != NULL )
  448. {
  449. /* MR23 */ if ( hasMultipleOperands(p->ret) )
  450. {
  451. DumpRetValStruct(f, p->ret, i);
  452. }
  453. fprintf(f, "\n#ifdef __USE_PROTOS\n");
  454. /* MR23 */ if ( hasMultipleOperands(p->ret) )
  455. {
  456. fprintf(f, "extern struct _rv%d", i);
  457. }
  458. else
  459. {
  460. fprintf(f, "extern ");
  461. DumpType(p->ret, f);
  462. }
  463. fprintf(f, " %s%s(", RulePrefix, p->rname);
  464. DumpANSIFunctionArgDef(f,p,1 /* emit initializers ? */);
  465. fprintf(f, ";\n");
  466. fprintf(f, "#else\n");
  467. /* MR23 */ if ( hasMultipleOperands(p->ret) )
  468. {
  469. fprintf(f, "extern struct _rv%d", i);
  470. }
  471. else
  472. {
  473. fprintf(f, "extern ");
  474. DumpType(p->ret, f);
  475. }
  476. fprintf(f, " %s%s();\n", RulePrefix, p->rname);
  477. fprintf(f, "#endif\n");
  478. }
  479. else
  480. {
  481. fprintf(f, "\n#ifdef __USE_PROTOS\n");
  482. fprintf(f, "void %s%s(", RulePrefix, p->rname);
  483. DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ );
  484. fprintf(f, ";\n");
  485. #ifdef OLD
  486. if ( p->pdecl != NULL || GenAST )
  487. {
  488. if ( GenAST ) {
  489. fprintf(f, "AST **%s",(p->pdecl!=NULL)?",":"");
  490. }
  491. if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  492. }
  493. else fprintf(f, "void");
  494. fprintf(f, ");\n");
  495. #endif
  496. fprintf(f, "#else\n");
  497. fprintf(f, "extern void %s%s();\n", RulePrefix, p->rname);
  498. fprintf(f, "#endif\n");
  499. }
  500. i++;
  501. p = (Junction *)p->p2;
  502. }
  503. }
  504. /* Define all rules in the class.h file; generate any required
  505. * struct definitions first, however.
  506. */
  507. void
  508. #ifdef __USE_PROTOS
  509. GenRuleMemberDeclarationsForCC( FILE *f, Junction *q )
  510. #else
  511. GenRuleMemberDeclarationsForCC( f, q )
  512. FILE *f;
  513. Junction *q;
  514. #endif
  515. {
  516. Junction *p = q;
  517. int i;
  518. fprintf(f, "private:\n");
  519. /* Dump dflt handler declaration */
  520. fprintf(f, "\tvoid zzdflthandlers( int _signal, int *_retsignal );\n\n");
  521. fprintf(f, "public:\n");
  522. /* Dump return value structs */
  523. i = 1;
  524. while ( p!=NULL )
  525. {
  526. if ( p->ret != NULL )
  527. {
  528. /* MR23 */ if ( hasMultipleOperands(p->ret) )
  529. {
  530. DumpRetValStruct(f, p->ret, i);
  531. }
  532. }
  533. i++;
  534. p = (Junction *)p->p2;
  535. }
  536. /* Dump member func defs && CONSTRUCTOR */
  537. fprintf(f, "\t%s(ANTLRTokenBuffer *input);\n", CurrentClassName);
  538. /*
  539. fprintf(f, "\t%s(ANTLRTokenBuffer *input, ANTLRTokenType eof);\n",
  540. CurrentClassName);
  541. */
  542. i = 1;
  543. p = q;
  544. while ( p!=NULL )
  545. {
  546. if ( p->ret != NULL )
  547. {
  548. /* MR23 */ if ( hasMultipleOperands(p->ret) )
  549. {
  550. fprintf(f, "\tstruct _rv%d", i);
  551. }
  552. else
  553. {
  554. fprintf(f, "\t");
  555. DumpType(p->ret, f);
  556. }
  557. fprintf(f, " %s%s(",RulePrefix,p->rname);
  558. DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */ );
  559. fprintf(f, ";\n");
  560. #ifdef OLD
  561. if ( p->pdecl != NULL || GenAST )
  562. {
  563. if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
  564. if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  565. }
  566. fprintf(f, ");\n");
  567. #endif
  568. }
  569. else
  570. {
  571. fprintf(f, "\tvoid %s%s(",RulePrefix,p->rname);
  572. DumpANSIFunctionArgDef(f,p, 1 /* emit initializers ? */);
  573. fprintf(f, ";\n");
  574. #ifdef OLD
  575. if ( p->pdecl != NULL || GenAST )
  576. {
  577. if ( GenAST ) fprintf(f, "ASTBase **%s",(p->pdecl!=NULL)?",":"");
  578. if ( p->pdecl!=NULL ) fprintf(f, "%s", p->pdecl);
  579. }
  580. fprintf(f, ");\n");
  581. #endif
  582. }
  583. i++;
  584. p = (Junction *)p->p2;
  585. }
  586. }
  587. /* Given a list of ANSI-style parameter declarations, print out a
  588. * comma-separated list of the symbols (w/o types).
  589. * Basically, we look for a comma, then work backwards until start of
  590. * the symbol name. Then print it out until 1st non-alnum char. Now,
  591. * move on to next parameter.
  592. *
  593. */
  594. /* MR5 Jan Mikkelsen 26-May-97 - added initialComma parameter */
  595. void
  596. #ifdef __USE_PROTOS
  597. DumpListOfParmNames(char *pdecl, FILE *output, int initialComma) /* MR5 */
  598. #else
  599. DumpListOfParmNames(pdecl, output, initialComma) /* MR5 */
  600. char *pdecl; /* MR5 */
  601. FILE *output; /* MR5 */
  602. int initialComma; /* MR5 */
  603. #endif
  604. {
  605. int firstTime = 1, done = 0;
  606. require(output!=NULL, "DumpListOfParmNames: NULL parm");
  607. if ( pdecl == NULL ) return;
  608. while ( !done )
  609. {
  610. if ( !firstTime || initialComma ) putc(',', output); /* MR5 */
  611. done = DumpNextNameInDef(&pdecl, output);
  612. firstTime = 0;
  613. }
  614. }
  615. /* given a list of parameters or return values, dump the next
  616. * name to output. Return 1 if last one just printed, 0 if more to go.
  617. */
  618. /* MR23 Total rewrite */
  619. int
  620. #ifdef __USE_PROTOS
  621. DumpNextNameInDef( char **q, FILE *output )
  622. #else
  623. DumpNextNameInDef( q, output )
  624. char **q;
  625. FILE *output;
  626. #endif
  627. {
  628. char *p;
  629. char *t;
  630. char *pDataType;
  631. char *pSymbol;
  632. char *pEqualSign;
  633. char *pValue;
  634. char *pSeparator;
  635. int nest = 0;
  636. p = endFormal(*q,
  637. &pDataType,
  638. &pSymbol,
  639. &pEqualSign,
  640. &pValue,
  641. &pSeparator,
  642. &nest);
  643. /* MR26 Handle rule arguments such as: IIR_Bool (IIR_Decl::*constraint)()
  644. For this we need to strip off anything which follows the symbol.
  645. */
  646. /* MR26 */ t = pSymbol;
  647. /* MR26 */ if (t != NULL) {
  648. /* MR26 */ for (t = pSymbol; *t != 0; t++) {
  649. /* MR26 */ if (! (isalpha(*t) || isdigit(*t) || *t == '_' || *t == '$')) break;
  650. /* MR26 */ }
  651. /* MR26 */ }
  652. /* MR26 */ fprintf(output, "%s", strBetween(pSymbol, t, pSeparator));
  653. *q = p;
  654. return (*pSeparator == 0);
  655. }
  656. /* Given a list of ANSI-style parameter declarations, dump K&R-style
  657. * declarations, one per line for each parameter. Basically, convert
  658. * comma to semi-colon, newline.
  659. */
  660. void
  661. #ifdef __USE_PROTOS
  662. DumpOldStyleParms( char *pdecl, FILE *output )
  663. #else
  664. DumpOldStyleParms( pdecl, output )
  665. char *pdecl;
  666. FILE *output;
  667. #endif
  668. {
  669. require(output!=NULL, "DumpOldStyleParms: NULL parm");
  670. if ( pdecl == NULL ) return;
  671. while ( *pdecl != '\0' )
  672. {
  673. if ( *pdecl == ',' )
  674. {
  675. pdecl++;
  676. putc(';', output); putc('\n', output);
  677. while ( *pdecl==' ' || *pdecl=='\t' || *pdecl=='\n' ) pdecl++;
  678. }
  679. else {putc(*pdecl, output); pdecl++;}
  680. }
  681. putc(';', output);
  682. putc('\n', output);
  683. }
  684. /* Take in a type definition (type + symbol) and print out type only */
  685. /* MR23 Total rewrite */
  686. void
  687. #ifdef __USE_PROTOS
  688. DumpType( char *s, FILE *f )
  689. #else
  690. DumpType( s, f )
  691. char *s;
  692. FILE *f;
  693. #endif
  694. {
  695. char *p;
  696. char *pDataType;
  697. char *pSymbol;
  698. char *pEqualSign;
  699. char *pValue;
  700. char *pSeparator;
  701. int nest = 0;
  702. require(s!=NULL, "DumpType: invalid type string");
  703. p = endFormal(s,
  704. &pDataType,
  705. &pSymbol,
  706. &pEqualSign,
  707. &pValue,
  708. &pSeparator,
  709. &nest);
  710. fprintf(f, "%s", strBetween(pDataType, pSymbol, pSeparator));
  711. }
  712. /* check to see if string e is a word in string s */
  713. int
  714. #ifdef __USE_PROTOS
  715. strmember( char *s, char *e )
  716. #else
  717. strmember( s, e )
  718. char *s;
  719. char *e;
  720. #endif
  721. {
  722. register char *p;
  723. require(s!=NULL&&e!=NULL, "strmember: NULL string");
  724. if ( *e=='\0' ) return 1; /* empty string is always member */
  725. do {
  726. while ( *s!='\0' && !isalnum(*s) && *s!='_' )
  727. ++s;
  728. p = e;
  729. while ( *p!='\0' && *p==*s ) {p++; s++;}
  730. if ( *p=='\0' ) {
  731. if ( *s=='\0' ) return 1;
  732. if ( !isalnum (*s) && *s != '_' ) return 1;
  733. }
  734. while ( isalnum(*s) || *s == '_' )
  735. ++s;
  736. } while ( *s!='\0' );
  737. return 0;
  738. }
  739. #if 0
  740. /* MR23 Replaced by hasMultipleOperands() */
  741. int
  742. #ifdef __USE_PROTOS
  743. HasComma( char *s )
  744. #else
  745. HasComma( s )
  746. char *s;
  747. #endif
  748. {
  749. while (*s!='\0')
  750. if ( *s++ == ',' ) return 1;
  751. return 0;
  752. }
  753. #endif
  754. /* MR23 Total rewrite */
  755. void
  756. #ifdef __USE_PROTOS
  757. DumpRetValStruct( FILE *f, char *ret, int i )
  758. #else
  759. DumpRetValStruct( f, ret, i )
  760. FILE *f;
  761. char *ret;
  762. int i;
  763. #endif
  764. {
  765. char *p = ret;
  766. char *pDataType;
  767. char *pSymbol;
  768. char *pEqualSign;
  769. char *pValue;
  770. char *pSeparator;
  771. int nest = 0;
  772. fprintf(f, "\nstruct _rv%d {\n", i);
  773. while (*p != 0 && nest == 0) {
  774. p = endFormal(p,
  775. &pDataType,
  776. &pSymbol,
  777. &pEqualSign,
  778. &pValue,
  779. &pSeparator,
  780. &nest);
  781. fprintf(f,"\t");
  782. fprintf(f, "%s", strBetween(pDataType, pSymbol, pSeparator));
  783. fprintf(f," ");
  784. fprintf(f, "%s", strBetween(pSymbol, pEqualSign, pSeparator));
  785. fprintf(f,";\n");
  786. }
  787. fprintf(f,"};\n");
  788. }
  789. /* given "s" yield s -- DESTRUCTIVE (we modify s if starts with " else return s) */
  790. char *
  791. #ifdef __USE_PROTOS
  792. StripQuotes( char *s )
  793. #else
  794. StripQuotes( s )
  795. char *s;
  796. #endif
  797. {
  798. if ( *s == '"' )
  799. {
  800. s[ strlen(s)-1 ] = '\0'; /* remove last quote */
  801. return( s+1 ); /* return address past initial quote */
  802. }
  803. return( s );
  804. }