Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

491 lines
13 KiB

  1. // Copyright (c) 1993-1999 Microsoft Corporation
  2. #include <stdlib.h>
  3. #include "y2.h"
  4. #include <string.h>
  5. #include <ctype.h>
  6. /*
  7. * YSETUP.C -- Modified for use with DECUS LEX
  8. * Variable "yylval" resides in yylex(), not in yypars();
  9. * Therefore, is defined "extern" here.
  10. *
  11. * Also, the command line processing for the Decus version
  12. * has been changed. A new switch has been added to allow
  13. * specification of the "table" file name(s), and unused
  14. * switch processing removed.
  15. *
  16. * NOTE
  17. * This probably won't run on UNIX any more.
  18. *
  19. * Bob Denny 27-Aug-81
  20. * Bob Denny 22-Mar-82 (01) Added header line, changes for 'new' DECUS library
  21. * Bob Denny 12-Apr-83 (02) Make filename[] size per #define'd FNAMESIZE so
  22. * VAX filenames won't blow out. Conditionalize
  23. * time handling for banner. Make filespec buffer
  24. * static for safety, since global "infile" is
  25. * pointed to it.
  26. * Scott Guthery 15-May-83 (03) Fixed up option flag handling for RT-11
  27. * 23-Dec-83 Adapted for IBM PC/XT & DeSmet C compiler
  28. */
  29. static char filename[FNAMESIZE];
  30. int i;
  31. SSIZE_T lev, t, j, ty;
  32. int c;
  33. SSIZE_T tempty;
  34. SSIZE_T *p;
  35. int defsw, infsw, ssw = 0;
  36. char actname[8];
  37. char *cp;
  38. char *pszPrefix = NULL;
  39. void
  40. setup(argc,argv)
  41. int argc;
  42. char *argv[];
  43. {
  44. char finsave[FNAMESIZE];
  45. defsw = infsw = 0;
  46. foutput = NULL;
  47. fdefine = NULL;
  48. argc--;
  49. argv++;
  50. while( argc && **argv == '-' )
  51. {
  52. while( *++(*argv) )
  53. {
  54. switch( toupper(**argv) )
  55. {
  56. case 'I':
  57. infsw++;
  58. continue;
  59. case 'H':
  60. defsw++;
  61. continue;
  62. case 'S':
  63. ssw++;
  64. infsw++;
  65. continue;
  66. case 'T':
  67. if (!--argc) {
  68. fprintf(stderr, "-t requires an argument\n");
  69. usage();
  70. } else {
  71. argv++;
  72. if (pszPrefix) {
  73. free(pszPrefix);
  74. }
  75. pszPrefix = MIDL_STRDUP(*argv);
  76. goto next_arg; // I hate myself
  77. }
  78. break;
  79. default:
  80. fprintf(stderr, "Illegal option: %c\n", *argv[i]);
  81. usage();
  82. }
  83. }
  84. next_arg:
  85. argc--;
  86. argv++;
  87. }
  88. if(!argc) {
  89. fprintf(stderr, "No input file specified\n");
  90. usage(); /* Catch no filename given */
  91. }
  92. /*
  93. * Now open the input file with a default extension of ".Y",
  94. * then replace the period in argv[1] with a null, so argv[1]
  95. * can be used to form the table, defs and info filenames.
  96. */
  97. if (!(cp = strrchr(argv[i], '\\')) && !(cp = strrchr(argv[i], ':'))) {
  98. cp = argv[i];
  99. }
  100. cp = strrchr(cp, '.');
  101. if(!cp) {
  102. strcpy(filename, argv[i]); strcat(filename, ".Y");
  103. } else {
  104. strcpy(filename, argv[i]);
  105. *cp = '\0';
  106. }
  107. strcpy(finsave, filename);
  108. if((finput=fopen( filename, "r" )) == NULL )
  109. error( "cannot open input file \"%s\"", filename );
  110. /*
  111. * Now open the .H and .I files if requested.
  112. */
  113. if(defsw)
  114. {
  115. strcpy(filename, argv[i]); strcat(filename, ".H");
  116. fdefine = fopen(filename, "w");
  117. if(fdefine == NULL) error("cannot open defs file\"%s\"", filename);
  118. }
  119. if(infsw)
  120. {
  121. strcpy(filename, argv[i]); strcat(filename, ".I");
  122. foutput = fopen(filename, "w");
  123. if(foutput == NULL) error("cannot open info file\"%s\"", filename);
  124. }
  125. /*
  126. * Now the "table" output C file.
  127. */
  128. strcpy(filename, argv[i]); strcat(filename, ".C");
  129. ftable = fopen(filename, "w");
  130. if( ftable == NULL ) error( "cannot open table file \"%s\"", filename);
  131. /*
  132. * Finally, the temp files.
  133. */
  134. ftemp = fopen( TEMPNAME, "w" );
  135. if( ftemp==NULL ) error( "cannot open temp file" );
  136. faction = fopen( ACTNAME, "w" );
  137. if( faction==NULL ) error( "cannot open action file" );
  138. /*
  139. * Now put the full filename of the input file into
  140. * the "filename" buffer for cpyact(), and point the
  141. * global cell "infile" at it.
  142. */
  143. strcpy(filename, finsave);
  144. infile = filename;
  145. /*
  146. * Put out a header line at the beginning of the 'table' file.
  147. */
  148. fprintf(ftable, "/*\n * Created by CSD YACC (IBM PC) from \"%s\" */\n",
  149. infile);
  150. /*
  151. * Complete initialization.
  152. */
  153. cnamp = cnames;
  154. defin(0,"$end");
  155. extval = 0400;
  156. defin(0,"error");
  157. defin(1,"$accept");
  158. mem=mem0;
  159. lev = 0;
  160. ty = 0;
  161. i=0;
  162. yyparse();
  163. }
  164. void
  165. yyparse( void )
  166. {
  167. /* sorry -- no yacc parser here.....
  168. we must bootstrap somehow... */
  169. for( t=gettok(); t!=MARK && t!= ENDFILE; )
  170. {
  171. switch( t )
  172. {
  173. case ';':
  174. t = gettok();
  175. break;
  176. case START:
  177. if( (t=gettok()) != IDENTIFIER )
  178. {
  179. error( "bad %%start construction" );
  180. }
  181. start = chfind(1,tokname);
  182. t = gettok();
  183. continue;
  184. case TYPEDEF:
  185. if( (t=gettok()) != TYPENAME ) error( "bad syntax in %%type" );
  186. ty = numbval;
  187. for(;;)
  188. {
  189. t = gettok();
  190. switch( t )
  191. {
  192. case IDENTIFIER:
  193. if( (t=chfind( 1, tokname ) ) < NTBASE )
  194. {
  195. j = TYPE( toklev[t] );
  196. if( j!= 0 && j != ty )
  197. {
  198. error( "type redeclaration of token %s",
  199. tokset[t].name );
  200. }
  201. else SETTYPE( toklev[t],ty);
  202. }
  203. else
  204. {
  205. j = nontrst[t-NTBASE].tvalue;
  206. if( j != 0 && j != ty )
  207. {
  208. error( "type redeclaration of nonterminal %s",
  209. nontrst[t-NTBASE].name );
  210. }
  211. else nontrst[t-NTBASE].tvalue = ty;
  212. }
  213. case ',':
  214. continue;
  215. case ';':
  216. t = gettok();
  217. break;
  218. default:
  219. break;
  220. }
  221. break;
  222. }
  223. continue;
  224. case UNION:
  225. /* copy the union declaration to the output */
  226. cpyunion();
  227. t = gettok();
  228. continue;
  229. case LEFT:
  230. case BINARY:
  231. case RIGHT:
  232. ++i;
  233. case TERM:
  234. lev = t-TERM; /* nonzero means new prec. and assoc. */
  235. ty = 0;
  236. /* get identifiers so defined */
  237. t = gettok();
  238. if( t == TYPENAME )
  239. {
  240. /* there is a type defined */
  241. ty = numbval;
  242. t = gettok();
  243. }
  244. for(;;)
  245. {
  246. switch( t )
  247. {
  248. case ',':
  249. t = gettok();
  250. continue;
  251. case ';':
  252. break;
  253. case IDENTIFIER:
  254. j = chfind(0,tokname);
  255. if( lev )
  256. {
  257. if( ASSOC(toklev[j]) ) error( "redeclaration of precedence of%s", tokname );
  258. SETASC(toklev[j],lev);
  259. SETPLEV(toklev[j],i);
  260. }
  261. if( ty )
  262. {
  263. if( TYPE(toklev[j]) ) error( "redeclaration of type of %s", tokname );
  264. SETTYPE(toklev[j],ty);
  265. }
  266. if( (t=gettok()) == NUMBER )
  267. {
  268. tokset[j].value = numbval;
  269. if( j < ndefout && j>2 )
  270. {
  271. error( "please define type number of %s earlier",
  272. tokset[j].name );
  273. }
  274. t=gettok();
  275. }
  276. continue;
  277. }
  278. break;
  279. }
  280. continue;
  281. case LCURLY:
  282. defout();
  283. cpycode();
  284. t = gettok();
  285. continue;
  286. default:
  287. printf("Unrecognized character: %o\n", t);
  288. error( "syntax error" );
  289. }
  290. }
  291. if( t == ENDFILE )
  292. {
  293. error( "unexpected EOF before %%" );
  294. }
  295. /* t is MARK */
  296. defout();
  297. fprintf( ftable,"#define yyclearin yychar = -1\n" );
  298. fprintf( ftable,"#define yyerrok yyerrflag = 0\n" );
  299. /*
  300. fprintf( ftable,"extern int yychar;\nextern short yyerrflag;\n" );
  301. */
  302. fprintf( ftable,"#ifndef YYMAXDEPTH\n#define YYMAXDEPTH 150\n#endif\n" );
  303. if(!ntypes)
  304. fprintf( ftable, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n" );
  305. #ifdef unix
  306. fprintf( ftable, "YYSTYPE yylval, yyval;\n" );
  307. #else
  308. fprintf( ftable, "extern YYSTYPE yylval; /*CSD & DECUS LEX */\n");
  309. fprintf( ftable, "YYSTYPE yyval; /*CSD & DECUS LEX */\n");
  310. #endif
  311. prdptr[0]=mem;
  312. /* added production */
  313. *mem++ = NTBASE;
  314. *mem++ = start; /* if start is 0, we will overwrite with the lhs of the firstrule */
  315. *mem++ = 1;
  316. *mem++ = 0;
  317. prdptr[1]=mem;
  318. while( (t=gettok()) == LCURLY ) cpycode();
  319. if( t != C_IDENTIFIER ) error( "bad syntax on first rule" );
  320. if( !start ) prdptr[0][1] = chfind(1,tokname);
  321. /* read rules */
  322. while( t!=MARK && t!=ENDFILE )
  323. {
  324. /* process a rule */
  325. if( t == '|' )
  326. {
  327. *mem++ = *prdptr[nprod-1];
  328. }
  329. else if( t == C_IDENTIFIER )
  330. {
  331. *mem = chfind(1,tokname);
  332. if( *mem < NTBASE ) error( "token illegal on LHS of grammar rule" );
  333. ++mem;
  334. }
  335. else error( "illegal rule: missing semicolon or | ?" );
  336. /* read rule body */
  337. t = gettok();
  338. more_rule:
  339. while( t == IDENTIFIER )
  340. {
  341. *mem = chfind(1,tokname);
  342. if( *mem<NTBASE ) levprd[nprod] = toklev[*mem];
  343. ++mem;
  344. t = gettok();
  345. }
  346. if( t == PREC )
  347. {
  348. if( gettok()!=IDENTIFIER) error( "illegal %%prec syntax" );
  349. j = chfind(2,tokname);
  350. if( j>=NTBASE)error("nonterminal %s illegal after %%prec", nontrst[j-NTBASE].name);
  351. levprd[nprod]=toklev[j];
  352. t = gettok();
  353. }
  354. if( t == '=' )
  355. {
  356. levprd[nprod] |= ACTFLAG;
  357. fprintf( faction, "\ncase %d:", nprod );
  358. cpyact( mem-prdptr[nprod]-1 );
  359. fprintf( faction, " break;" );
  360. if( (t=gettok()) == IDENTIFIER )
  361. {
  362. /* action within rule... */
  363. sprintf( actname, "$$%d", nprod );
  364. j = chfind(1,actname); /* make it a nonterminal */
  365. /* the current rule will become rule number nprod+1 */
  366. /* move the contents down, and make room for the null */
  367. for( p=mem; p>=prdptr[nprod]; --p ) p[2] = *p;
  368. mem += 2;
  369. /* enter null production for action */
  370. p = prdptr[nprod];
  371. *p++ = j;
  372. *p++ = -nprod;
  373. /* update the production information */
  374. levprd[nprod+1] = levprd[nprod] & ~ACTFLAG;
  375. levprd[nprod] = ACTFLAG;
  376. if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
  377. prdptr[nprod] = p;
  378. /* make the action appear in the original rule */
  379. *mem++ = j;
  380. /* get some more of the rule */
  381. goto more_rule;
  382. }
  383. }
  384. while( t == ';' ) t = gettok();
  385. *mem++ = -nprod;
  386. /* check that default action is reasonable */
  387. if( ntypes && !(levprd[nprod]&ACTFLAG) && nontrst[*prdptr[nprod]-NTBASE].tvalue )
  388. {
  389. /* no explicit action, LHS has value */
  390. /*01*/
  391. tempty = prdptr[nprod][1];
  392. if( tempty < 0 ) error( "must return a value, since LHS has a type" );
  393. else if( tempty >= NTBASE ) tempty = nontrst[tempty-NTBASE].tvalue;
  394. else tempty = TYPE( toklev[tempty] );
  395. if( tempty != nontrst[*prdptr[nprod]-NTBASE].tvalue )
  396. {
  397. error( "default action causes potential type clash" );
  398. }
  399. }
  400. if( ++nprod >= NPROD ) error( "more than %d rules", NPROD );
  401. prdptr[nprod] = mem;
  402. levprd[nprod]=0;
  403. }
  404. /* end of all rules */
  405. fprintf(faction, "/* End of actions */"); /* Properly terminate the last line */
  406. finact();
  407. if( t == MARK )
  408. {
  409. writeline(ftable);
  410. while( (c=unix_getc(finput)) != EOF ) putc( c, ftable );
  411. }
  412. fclose( finput );
  413. }
  414. void
  415. usage( void )
  416. {
  417. fprintf(stderr,"UNIX YACC (CSD Variant):\n");
  418. fprintf(stderr," yacc -hist tag infile\n\n");
  419. fprintf(stderr,"Switches:\n");
  420. fprintf(stderr," -h Create definitions header file\n");
  421. fprintf(stderr," -i Create parser description file\n");
  422. fprintf(stderr," -t tag Prepends tag to tables\n");
  423. fprintf(stderr," -s Generates extended tables (MIDL specific) \n\n");
  424. fprintf(stderr,"Default input file extension is \".Y\"\n");
  425. fprintf(stderr,"Defs file same name, \".H\" extension.\n");
  426. fprintf(stderr,"Info file same name, \".I\" extension.\n");
  427. fprintf(stderr,"Extended Tables in file \"extable.[h1/h2/h3]\".\n");
  428. fprintf(stderr,"Specifying -s switch also enables the -i switch\n");
  429. exit(EX_ERR);
  430. }