home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume19 / flex2 / part02 < prev    next >
Text File  |  1989-06-21  |  41KB  |  1,917 lines

  1. Subject:  v19i056:  Flex, a fast LEX replacement, Part02/07
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: Vern Paxson <vern@csam.lbl.gov>
  7. Posting-number: Volume 19, Issue 56
  8. Archive-name: flex2/part02
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 2 (of 7)."
  17. # Contents:  flex/flex.skel flex/misc.c flex/parse.y
  18. # Wrapped by rsalz@prune.bbn.com on Thu Jun 22 19:01:44 1989
  19. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  20. if test -f 'flex/flex.skel' -a "${1}" != "-c" ; then 
  21.   echo shar: Will not clobber existing file \"'flex/flex.skel'\"
  22. else
  23. echo shar: Extracting \"'flex/flex.skel'\" \(11297 characters\)
  24. sed "s/^X//" >'flex/flex.skel' <<'END_OF_FILE'
  25. X/* A lexical scanner generated by flex */
  26. X
  27. X/* scanner skeleton version:
  28. X * $Header: flex.skel,v 2.0 89/06/20 15:49:46 vern Locked $
  29. X */
  30. X
  31. X#include <stdio.h>
  32. X
  33. X#define FLEX_SCANNER
  34. X
  35. X/* amount of stuff to slurp up with each read */
  36. X#ifndef YY_READ_BUF_SIZE
  37. X#define YY_READ_BUF_SIZE 8192
  38. X#endif
  39. X
  40. X#ifndef YY_BUF_SIZE
  41. X#define YY_BUF_SIZE (YY_READ_BUF_SIZE * 2) /* size of input buffer */
  42. X#endif
  43. X
  44. X/* returned upon end-of-file */
  45. X#define YY_END_TOK 0
  46. X
  47. X/* copy whatever the last rule matched to the standard output */
  48. X
  49. X#define ECHO fputs( yytext, yyout )
  50. X
  51. X/* gets input and stuffs it into "buf".  number of characters read, or YY_NULL,
  52. X * is returned in "result".
  53. X */
  54. X#define YY_INPUT(buf,result,max_size) \
  55. X    if ( (result = read( fileno(yyin), buf, max_size )) < 0 ) \
  56. X        YY_FATAL_ERROR( "read() in flex scanner failed" );
  57. X#define YY_NULL 0
  58. X#define yyterminate() return ( YY_NULL )
  59. X
  60. X/* report a fatal error */
  61. X#define YY_FATAL_ERROR(msg) \
  62. X    { \
  63. X    fputs( msg, stderr ); \
  64. X    putc( '\n', stderr ); \
  65. X    exit( 1 ); \
  66. X    }
  67. X
  68. X/* default yywrap function - always treat EOF as an EOF */
  69. X#define yywrap() 1
  70. X
  71. X/* enter a start condition.  This macro really ought to take a parameter,
  72. X * but we do it the disgusting crufty way forced on us by the ()-less
  73. X * definition of BEGIN
  74. X */
  75. X#define BEGIN yy_start = 1 + 2 *
  76. X
  77. X/* action number for EOF rule of a given start state */
  78. X#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
  79. X
  80. X/* special action meaning "start processing a new file" */
  81. X#define YY_NEW_FILE goto new_file
  82. X
  83. X/* default declaration of generated scanner - a define so the user can
  84. X * easily add parameters
  85. X */
  86. X#ifdef __STDC__
  87. X#define YY_DECL int yylex( void )
  88. X#else
  89. X#define YY_DECL int yylex()
  90. X#endif
  91. X
  92. X/* code executed at the end of each rule */
  93. X#define YY_BREAK break;
  94. X
  95. X#define YY_END_OF_BUFFER_CHAR 0
  96. X
  97. X/* done after the current pattern has been matched and before the
  98. X * corresponding action - sets up yytext
  99. X */
  100. X#define YY_DO_BEFORE_ACTION \
  101. X    yytext = yy_bp; \
  102. X    yy_hold_char = *yy_cp; \
  103. X    *yy_cp = '\0'; \
  104. X    yy_c_buf_p = yy_cp;
  105. X
  106. X/* returns the length of the matched text */
  107. X#define yyleng (yy_cp - yy_bp)
  108. X
  109. X#define EOB_ACT_RESTART_SCAN 0
  110. X#define EOB_ACT_END_OF_FILE 1
  111. X#define EOB_ACT_LAST_MATCH 2
  112. X
  113. X/* return all but the first 'n' matched characters back to the input stream */
  114. X#define yyless(n) \
  115. X    { \
  116. X    *yy_cp = yy_hold_char; /* undo effects of setting up yytext */ \
  117. X    yy_c_buf_p = yy_cp = yy_bp + n; \
  118. X    YY_DO_BEFORE_ACTION; /* set up yytext again */ \
  119. X    }
  120. X
  121. X#define unput(c) yyunput( c, yy_bp )
  122. X
  123. X#define YY_USER_ACTION
  124. X
  125. XFILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
  126. Xchar *yytext;
  127. X
  128. X#ifndef __STDC__
  129. X#define const
  130. X#endif
  131. X
  132. X%% section 1 code and the data tables for the DFA go here
  133. X
  134. X/* these variables are all declared out here so that section 3 code can
  135. X * manipulate them
  136. X */
  137. Xstatic char *yy_c_buf_p;    /* points to current character in buffer */
  138. Xstatic int yy_init = 1;        /* whether we need to initialize */
  139. Xstatic int yy_start = 0;    /* start state number */
  140. X
  141. X/* true when we've seen an EOF for the current input file */
  142. Xstatic int yy_eof_has_been_seen;
  143. X
  144. Xstatic int yy_n_chars;        /* number of characters read into yy_ch_buf */
  145. X
  146. X/* yy_ch_buf has to be 2 characters longer than YY_BUF_SIZE because we need
  147. X * to put in 2 end-of-buffer characters (this is explained where it is
  148. X * done) at the end of yy_ch_buf
  149. X */
  150. Xstatic char yy_ch_buf[YY_BUF_SIZE + 2];
  151. X
  152. X/* yy_hold_char holds the character lost when yytext is formed */
  153. Xstatic char yy_hold_char;
  154. X
  155. Xstatic yy_state_type yy_last_accepting_state;
  156. Xstatic char *yy_last_accepting_cpos;
  157. X
  158. X#ifdef __STDC__
  159. Xstatic yy_state_type yy_get_previous_state( void );
  160. Xstatic int yy_get_next_buffer( void );
  161. Xstatic void yyunput( int c, char *buf_ptr );
  162. Xstatic int input( void );
  163. Xstatic void yyrestart( FILE *input_file );
  164. X#else
  165. Xstatic yy_state_type yy_get_previous_state();
  166. Xstatic int yy_get_next_buffer();
  167. Xstatic void yyunput();
  168. Xstatic int input();
  169. Xstatic void yyrestart();
  170. X#endif
  171. X
  172. XYY_DECL
  173. X    {
  174. X    register yy_state_type yy_current_state;
  175. X    register char *yy_cp, *yy_bp;
  176. X    register int yy_act;
  177. X
  178. X%% user's declarations go here
  179. X
  180. X    if ( yy_init )
  181. X    {
  182. X    if ( ! yy_start )
  183. X        yy_start = 1;    /* first start state */
  184. X
  185. X    if ( ! yyin )
  186. X        yyin = stdin;
  187. X
  188. X    if ( ! yyout )
  189. X        yyout = stdout;
  190. X
  191. Xnew_file:
  192. X    /* this is where we enter upon encountering an end-of-file and
  193. X     * yywrap() indicating that we should continue processing
  194. X     */
  195. X
  196. X    /* we put in the '\n' and start reading from [1] so that an
  197. X     * initial match-at-newline will be true.
  198. X     */
  199. X
  200. X    yy_ch_buf[0] = '\n';
  201. X    yy_n_chars = 1;
  202. X
  203. X    /* we always need two end-of-buffer characters.  The first causes
  204. X     * a transition to the end-of-buffer state.  The second causes
  205. X     * a jam in that state.
  206. X     */
  207. X    yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
  208. X    yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
  209. X
  210. X    yy_eof_has_been_seen = 0;
  211. X
  212. X    yytext = yy_c_buf_p = &yy_ch_buf[1];
  213. X    yy_hold_char = *yy_c_buf_p;
  214. X    yy_init = 0;
  215. X    }
  216. X
  217. X    while ( 1 )        /* loops until end-of-file is reached */
  218. X    {
  219. X    yy_cp = yy_c_buf_p;
  220. X
  221. X    /* support of yytext */
  222. X    *yy_cp = yy_hold_char;
  223. X
  224. X    /* yy_bp points to the position in yy_ch_buf of the start of the
  225. X     * current run.
  226. X     */
  227. X%% yymore()-related code goes here
  228. X
  229. X%% code to set up and find next match goes here
  230. X
  231. X    /* bogus while loop to let YY_BACK_TRACK, EOB_ACT_LAST_MATCH,
  232. X     * and EOF actions branch here without introducing an optimizer-
  233. X     * daunting goto
  234. X     */
  235. X    while ( 1 )
  236. X        {
  237. X%% code to find the action number goes here
  238. X
  239. X        YY_DO_BEFORE_ACTION;
  240. X        YY_USER_ACTION;
  241. X
  242. X#ifdef FLEX_DEBUG
  243. X        fprintf( stderr, "--accepting rule #%d (\"%s\")\n",
  244. X             yy_act, yytext );
  245. X#endif
  246. X
  247. Xdo_action:    /* this label is used only to access EOF actions */
  248. X        switch ( yy_act )
  249. X        {
  250. X%% actions go here
  251. X
  252. X        case YY_END_OF_BUFFER:
  253. X            /* undo the effects of YY_DO_BEFORE_ACTION */
  254. X            *yy_cp = yy_hold_char;
  255. X
  256. X            yytext = yy_bp;
  257. X
  258. X            switch ( yy_get_next_buffer() )
  259. X            {
  260. X            case EOB_ACT_END_OF_FILE:
  261. X                {
  262. X                if ( yywrap() )
  263. X                {
  264. X                /* note: because we've taken care in
  265. X                 * yy_get_next_buffer() to have set up yytext,
  266. X                 * we can now set up yy_c_buf_p so that if some
  267. X                 * total hoser (like flex itself) wants
  268. X                 * to call the scanner after we return the
  269. X                 * YY_NULL, it'll still work - another YY_NULL
  270. X                 * will get returned.
  271. X                 */
  272. X                yy_c_buf_p = yytext;
  273. X
  274. X                yy_act = YY_STATE_EOF((yy_start - 1) / 2);
  275. X                goto do_action;
  276. X                }
  277. X
  278. X                else
  279. X                YY_NEW_FILE;
  280. X                }
  281. X                break;
  282. X
  283. X            case EOB_ACT_RESTART_SCAN:
  284. X                yy_c_buf_p = yytext;
  285. X                yy_hold_char = *yy_c_buf_p;
  286. X                break;
  287. X
  288. X            case EOB_ACT_LAST_MATCH:
  289. X                yy_c_buf_p = &yy_ch_buf[yy_n_chars];
  290. X
  291. X                yy_current_state = yy_get_previous_state();
  292. X
  293. X                yy_cp = yy_c_buf_p;
  294. X                yy_bp = yytext;
  295. X                continue; /* go to "YY_DO_BEFORE_ACTION" */
  296. X            }
  297. X            break;
  298. X
  299. X        default:
  300. X            printf( "action # %d\n", yy_act );
  301. X            YY_FATAL_ERROR( "fatal flex scanner internal error" );
  302. X        }
  303. X
  304. X        break; /* exit bogus while loop */
  305. X        }
  306. X    }
  307. X    }
  308. X
  309. X
  310. X/* yy_get_next_buffer - try to read in new buffer
  311. X *
  312. X * synopsis
  313. X *     int yy_get_next_buffer();
  314. X *     
  315. X * returns a code representing an action
  316. X *     EOB_ACT_LAST_MATCH - 
  317. X *     EOB_ACT_RESTART_SCAN - restart the scanner
  318. X *     EOB_ACT_END_OF_FILE - end of file
  319. X */
  320. X
  321. Xstatic int yy_get_next_buffer()
  322. X
  323. X    {
  324. X    register char *dest = yy_ch_buf;
  325. X    register char *source = yytext - 1; /* copy prev. char, too */
  326. X    register int number_to_move, i;
  327. X    int ret_val;
  328. X    
  329. X    if ( yy_c_buf_p != &yy_ch_buf[yy_n_chars + 1] )
  330. X    {
  331. X    YY_FATAL_ERROR( "NULL in input" );
  332. X    /*NOTREACHED*/
  333. X    }
  334. X
  335. X    /* try to read more data */
  336. X
  337. X    /* first move last chars to start of buffer */
  338. X    number_to_move = yy_c_buf_p - yytext;
  339. X
  340. X    for ( i = 0; i < number_to_move; ++i )
  341. X    *(dest++) = *(source++);
  342. X
  343. X    if ( yy_eof_has_been_seen )
  344. X    /* don't do the read, it's not guaranteed to return an EOF,
  345. X     * just force an EOF
  346. X     */
  347. X    yy_n_chars = 0;
  348. X
  349. X    else
  350. X    {
  351. X    int num_to_read = YY_BUF_SIZE - number_to_move - 1;
  352. X
  353. X    if ( num_to_read > YY_READ_BUF_SIZE )
  354. X        num_to_read = YY_READ_BUF_SIZE;
  355. X
  356. X    /* read in more data */
  357. X    YY_INPUT( (&yy_ch_buf[number_to_move]), yy_n_chars, num_to_read );
  358. X    }
  359. X
  360. X    if ( yy_n_chars == 0 )
  361. X    {
  362. X    if ( number_to_move == 1 )
  363. X        ret_val = EOB_ACT_END_OF_FILE;
  364. X    else
  365. X        ret_val = EOB_ACT_LAST_MATCH;
  366. X
  367. X    yy_eof_has_been_seen = 1;
  368. X    }
  369. X
  370. X    else
  371. X    ret_val = EOB_ACT_RESTART_SCAN;
  372. X
  373. X    yy_n_chars += number_to_move;
  374. X    yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
  375. X    yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
  376. X
  377. X    /* yytext begins at the second character in
  378. X     * yy_ch_buf; the first character is the one which
  379. X     * preceded it before reading in the latest buffer;
  380. X     * it needs to be kept around in case it's a
  381. X     * newline, so yy_get_previous_state() will have
  382. X     * with '^' rules active
  383. X     */
  384. X
  385. X    yytext = &yy_ch_buf[1];
  386. X
  387. X    return ( ret_val );
  388. X    }
  389. X
  390. X
  391. X/* yy_get_previous_state - get the state just before the EOB char was reached
  392. X *
  393. X * synopsis
  394. X *     yy_state_type yy_get_previous_state();
  395. X */
  396. X
  397. Xstatic yy_state_type yy_get_previous_state()
  398. X
  399. X    {
  400. X    register yy_state_type yy_current_state;
  401. X    register char *yy_cp;
  402. X
  403. X%% code to get the start state into yy_current_state goes here
  404. X
  405. X    for ( yy_cp = yytext; yy_cp < yy_c_buf_p; ++yy_cp )
  406. X    {
  407. X%% code to find the next state goes here
  408. X    }
  409. X
  410. X    return ( yy_current_state );
  411. X    }
  412. X
  413. X
  414. X#ifdef __STDC__
  415. Xstatic void yyunput( int c, register char *yy_bp )
  416. X#else
  417. Xstatic void yyunput( c, yy_bp )
  418. Xint c;
  419. Xregister char *yy_bp;
  420. X#endif
  421. X
  422. X    {
  423. X    register char *yy_cp = yy_c_buf_p;
  424. X
  425. X    *yy_cp = yy_hold_char; /* undo effects of setting up yytext */
  426. X
  427. X    if ( yy_cp < yy_ch_buf + 2 )
  428. X    { /* need to shift things up to make room */
  429. X    register int number_to_move = yy_n_chars + 2; /* +2 for EOB chars */
  430. X    register char *dest = &yy_ch_buf[YY_BUF_SIZE + 2];
  431. X    register char *source = &yy_ch_buf[number_to_move];
  432. X
  433. X    while ( source > yy_ch_buf )
  434. X        *--dest = *--source;
  435. X
  436. X    yy_cp += dest - source;
  437. X    yy_bp += dest - source;
  438. X
  439. X    if ( yy_cp < yy_ch_buf + 2 )
  440. X        YY_FATAL_ERROR( "flex scanner push-back overflow" );
  441. X    }
  442. X
  443. X    if ( yy_cp > yy_bp && yy_cp[-1] == '\n' )
  444. X    yy_cp[-2] = '\n';
  445. X
  446. X    *--yy_cp = c;
  447. X
  448. X    YY_DO_BEFORE_ACTION; /* set up yytext again */
  449. X    }
  450. X
  451. X
  452. Xstatic int input()
  453. X
  454. X    {
  455. X    int c;
  456. X    char *yy_cp = yy_c_buf_p;
  457. X
  458. X    *yy_cp = yy_hold_char;
  459. X
  460. X    if ( *yy_c_buf_p == YY_END_OF_BUFFER_CHAR )
  461. X    { /* need more input */
  462. X    yytext = yy_c_buf_p;
  463. X    ++yy_c_buf_p;
  464. X
  465. X    switch ( yy_get_next_buffer() )
  466. X        {
  467. X        /* this code, unfortunately, is somewhat redundant with
  468. X         * that above
  469. X         */
  470. X        case EOB_ACT_END_OF_FILE:
  471. X        {
  472. X        if ( yywrap() )
  473. X            {
  474. X            yy_c_buf_p = yytext;
  475. X            return ( EOF );
  476. X            }
  477. X
  478. X        yy_ch_buf[0] = '\n';
  479. X        yy_n_chars = 1;
  480. X        yy_ch_buf[yy_n_chars] = YY_END_OF_BUFFER_CHAR;
  481. X        yy_ch_buf[yy_n_chars + 1] = YY_END_OF_BUFFER_CHAR;
  482. X        yy_eof_has_been_seen = 0;
  483. X        yytext = yy_c_buf_p = &yy_ch_buf[1];
  484. X        yy_hold_char = *yy_c_buf_p;
  485. X
  486. X        return ( input() );
  487. X        }
  488. X        break;
  489. X
  490. X        case EOB_ACT_RESTART_SCAN:
  491. X        yy_c_buf_p = yytext;
  492. X        break;
  493. X
  494. X        case EOB_ACT_LAST_MATCH:
  495. X        YY_FATAL_ERROR( "unexpected last match in input()" );
  496. X        }
  497. X    }
  498. X
  499. X    c = *yy_c_buf_p;
  500. X    yy_hold_char = *++yy_c_buf_p;
  501. X
  502. X    return ( c );
  503. X    }
  504. X
  505. X
  506. X#ifdef __STDC__
  507. Xstatic void yyrestart( FILE *input_file )
  508. X#else
  509. Xstatic void yyrestart( input_file )
  510. XFILE *input_file;
  511. X#endif
  512. X
  513. X    {
  514. X    if ( yyin != stdin )
  515. X    fclose( yyin );
  516. X
  517. X    yyin = input_file;
  518. X    yy_init = 1;
  519. X    }
  520. END_OF_FILE
  521. if test 11297 -ne `wc -c <'flex/flex.skel'`; then
  522.     echo shar: \"'flex/flex.skel'\" unpacked with wrong size!
  523. fi
  524. # end of 'flex/flex.skel'
  525. fi
  526. if test -f 'flex/misc.c' -a "${1}" != "-c" ; then 
  527.   echo shar: Will not clobber existing file \"'flex/misc.c'\"
  528. else
  529. echo shar: Extracting \"'flex/misc.c'\" \(12468 characters\)
  530. sed "s/^X//" >'flex/misc.c' <<'END_OF_FILE'
  531. X/* misc - miscellaneous flex routines */
  532. X
  533. X/*
  534. X * Copyright (c) 1989 The Regents of the University of California.
  535. X * All rights reserved.
  536. X *
  537. X * This code is derived from software contributed to Berkeley by
  538. X * Vern Paxson.
  539. X * 
  540. X * The United States Government has rights in this work pursuant to
  541. X * contract no. DE-AC03-76SF00098 between the United States Department of
  542. X * Energy and the University of California.
  543. X *
  544. X * Redistribution and use in source and binary forms are permitted
  545. X * provided that the above copyright notice and this paragraph are
  546. X * duplicated in all such forms and that any documentation,
  547. X * advertising materials, and other materials related to such
  548. X * distribution and use acknowledge that the software was developed
  549. X * by the University of California, Berkeley.  The name of the
  550. X * University may not be used to endorse or promote products derived
  551. X * from this software without specific prior written permission.
  552. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  553. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  554. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  555. X */
  556. X
  557. X#ifndef lint
  558. X
  559. Xstatic char copyright[] =
  560. X    "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
  561. Xstatic char CR_continuation[] = "@(#) All rights reserved.\n";
  562. X
  563. Xstatic char rcsid[] =
  564. X    "@(#) $Header: misc.c,v 2.0 89/06/20 15:50:00 vern Locked $ (LBL)";
  565. X
  566. X#endif
  567. X
  568. X#include <ctype.h>
  569. X#include "flexdef.h"
  570. X
  571. Xchar *malloc(), *realloc();
  572. X
  573. X
  574. X/* action_out - write the actions from the temporary file to lex.yy.c
  575. X *
  576. X * synopsis
  577. X *     action_out();
  578. X *
  579. X *     Copies the action file up to %% (or end-of-file) to lex.yy.c
  580. X */
  581. X
  582. Xaction_out()
  583. X
  584. X    {
  585. X    char buf[MAXLINE];
  586. X
  587. X    while ( fgets( buf, MAXLINE, temp_action_file ) != NULL )
  588. X    if ( buf[0] == '%' && buf[1] == '%' )
  589. X        break;
  590. X    else
  591. X        fputs( buf, stdout );
  592. X    }
  593. X
  594. X
  595. X/* allocate_array - allocate memory for an integer array of the given size */
  596. X
  597. Xchar *allocate_array( size, element_size )
  598. Xint size, element_size;
  599. X
  600. X    {
  601. X    register char *mem;
  602. X
  603. X    /* on 16-bit int machines (e.g., 80286) we might be trying to
  604. X     * allocate more than a signed int can hold, and that won't
  605. X     * work.  Cheap test:
  606. X     */
  607. X    if ( element_size * size <= 0 )
  608. X        flexfatal( "request for < 1 byte in allocate_array()" );
  609. X    
  610. X    mem = malloc( (unsigned) (element_size * size) );
  611. X
  612. X    if ( mem == NULL )
  613. X    flexfatal( "memory allocation failed in allocate_array()" );
  614. X
  615. X    return ( mem );
  616. X    }
  617. X
  618. X
  619. X/* all_lower - true if a string is all lower-case
  620. X *
  621. X * synopsis:
  622. X *    char *str;
  623. X *    int all_lower();
  624. X *    true/false = all_lower( str );
  625. X */
  626. X
  627. Xint all_lower( str )
  628. Xregister char *str;
  629. X
  630. X    {
  631. X    while ( *str )
  632. X    {
  633. X    if ( ! islower( *str ) )
  634. X        return ( 0 );
  635. X    ++str;
  636. X    }
  637. X
  638. X    return ( 1 );
  639. X    }
  640. X
  641. X
  642. X/* all_upper - true if a string is all upper-case
  643. X *
  644. X * synopsis:
  645. X *    char *str;
  646. X *    int all_upper();
  647. X *    true/false = all_upper( str );
  648. X */
  649. X
  650. Xint all_upper( str )
  651. Xregister char *str;
  652. X
  653. X    {
  654. X    while ( *str )
  655. X    {
  656. X    if ( ! isupper( *str ) )
  657. X        return ( 0 );
  658. X    ++str;
  659. X    }
  660. X
  661. X    return ( 1 );
  662. X    }
  663. X
  664. X
  665. X/* bubble - bubble sort an integer array in increasing order
  666. X *
  667. X * synopsis
  668. X *   int v[n], n;
  669. X *   bubble( v, n );
  670. X *
  671. X * description
  672. X *   sorts the first n elements of array v and replaces them in
  673. X *   increasing order.
  674. X *
  675. X * passed
  676. X *   v - the array to be sorted
  677. X *   n - the number of elements of 'v' to be sorted */
  678. X
  679. Xbubble( v, n )
  680. Xint v[], n;
  681. X
  682. X    {
  683. X    register int i, j, k;
  684. X
  685. X    for ( i = n; i > 1; --i )
  686. X    for ( j = 1; j < i; ++j )
  687. X        if ( v[j] > v[j + 1] )    /* compare */
  688. X        {
  689. X        k = v[j];    /* exchange */
  690. X        v[j] = v[j + 1];
  691. X        v[j + 1] = k;
  692. X        }
  693. X    }
  694. X
  695. X
  696. X/* clower - replace upper-case letter to lower-case
  697. X *
  698. X * synopsis:
  699. X *    char clower(), c;
  700. X *    c = clower( c );
  701. X */
  702. X
  703. Xchar clower( c )
  704. Xregister char c;
  705. X
  706. X    {
  707. X    return ( isupper(c) ? tolower(c) : c );
  708. X    }
  709. X
  710. X
  711. X/* copy_string - returns a dynamically allocated copy of a string
  712. X *
  713. X * synopsis
  714. X *    char *str, *copy, *copy_string();
  715. X *    copy = copy_string( str );
  716. X */
  717. X
  718. Xchar *copy_string( str )
  719. Xregister char *str;
  720. X
  721. X    {
  722. X    register char *c;
  723. X    char *copy;
  724. X
  725. X    /* find length */
  726. X    for ( c = str; *c; ++c )
  727. X    ;
  728. X
  729. X    copy = malloc( (unsigned) ((c - str + 1) * sizeof( char )) );
  730. X
  731. X    if ( copy == NULL )
  732. X    flexfatal( "dynamic memory failure in copy_string()" );
  733. X
  734. X    for ( c = copy; (*c++ = *str++); )
  735. X    ;
  736. X    
  737. X    return ( copy );
  738. X    }
  739. X
  740. X
  741. X/* cshell - shell sort a character array in increasing order
  742. X *
  743. X * synopsis
  744. X *
  745. X *   char v[n];
  746. X *   int n;
  747. X *   cshell( v, n );
  748. X *
  749. X * description
  750. X *   does a shell sort of the first n elements of array v.
  751. X *
  752. X * passed
  753. X *   v - array to be sorted
  754. X *   n - number of elements of v to be sorted
  755. X */
  756. Xcshell( v, n )
  757. Xchar v[];
  758. Xint n;
  759. X
  760. X    {
  761. X    int gap, i, j, jg;
  762. X    char k;
  763. X
  764. X    for ( gap = n / 2; gap > 0; gap = gap / 2 )
  765. X    for ( i = gap; i < n; ++i )
  766. X        for ( j = i - gap; j >= 0; j = j - gap )
  767. X        {
  768. X        jg = j + gap;
  769. X
  770. X        if ( v[j] <= v[jg] )
  771. X            break;
  772. X
  773. X        k = v[j];
  774. X        v[j] = v[jg];
  775. X        v[jg] = k;
  776. X        }
  777. X    }
  778. X
  779. X
  780. X/* dataend - finish up a block of data declarations
  781. X *
  782. X * synopsis
  783. X *    dataend();
  784. X */
  785. Xdataend()
  786. X
  787. X    {
  788. X    if ( datapos > 0 )
  789. X    dataflush();
  790. X
  791. X    /* add terminator for initialization */
  792. X    puts( "    } ;\n" );
  793. X
  794. X    dataline = 0;
  795. X    }
  796. X
  797. X
  798. X
  799. X/* dataflush - flush generated data statements
  800. X *
  801. X * synopsis
  802. X *    dataflush();
  803. X */
  804. Xdataflush()
  805. X
  806. X    {
  807. X    putchar( '\n' );
  808. X
  809. X    if ( ++dataline >= NUMDATALINES )
  810. X    {
  811. X    /* put out a blank line so that the table is grouped into
  812. X     * large blocks that enable the user to find elements easily
  813. X     */
  814. X    putchar( '\n' );
  815. X    dataline = 0;
  816. X    }
  817. X
  818. X    /* reset the number of characters written on the current line */
  819. X    datapos = 0;
  820. X    }
  821. X
  822. X/* flex_gettime - return current time
  823. X *
  824. X * synopsis
  825. X *    char *flex_gettime(), *time_str;
  826. X *    time_str = flex_gettime();
  827. X *
  828. X * note
  829. X *    the routine name has the "flex_" prefix because of name clashes
  830. X *    with Turbo-C
  831. X */
  832. X
  833. X/* include sys/types.h to use time_t and make lint happy */
  834. X
  835. X#ifndef MS_DOS
  836. X#ifndef VMS
  837. X#include <sys/types.h>
  838. X#else
  839. X#include <types.h>
  840. X#endif
  841. X#endif
  842. X
  843. X#ifdef MS_DOS
  844. X#include <time.h>
  845. Xtypedef long time_t;
  846. X#endif
  847. X
  848. Xchar *flex_gettime()
  849. X
  850. X    {
  851. X    time_t t, time();
  852. X    char *result, *ctime(), *copy_string();
  853. X
  854. X    t = time( (long *) 0 );
  855. X
  856. X    result = copy_string( ctime( &t ) );
  857. X
  858. X    /* get rid of trailing newline */
  859. X    result[24] = '\0';
  860. X
  861. X    return ( result );
  862. X    }
  863. X
  864. X
  865. X/* lerrif - report an error message formatted with one integer argument
  866. X *
  867. X * synopsis
  868. X *    char msg[];
  869. X *    int arg;
  870. X *    lerrif( msg, arg );
  871. X */
  872. X
  873. Xlerrif( msg, arg )
  874. Xchar msg[];
  875. Xint arg;
  876. X
  877. X    {
  878. X    char errmsg[MAXLINE];
  879. X    (void) sprintf( errmsg, msg, arg );
  880. X    flexerror( errmsg );
  881. X    }
  882. X
  883. X
  884. X/* lerrsf - report an error message formatted with one string argument
  885. X *
  886. X * synopsis
  887. X *    char msg[], arg[];
  888. X *    lerrsf( msg, arg );
  889. X */
  890. X
  891. Xlerrsf( msg, arg )
  892. Xchar msg[], arg[];
  893. X
  894. X    {
  895. X    char errmsg[MAXLINE];
  896. X
  897. X    (void) sprintf( errmsg, msg, arg );
  898. X    flexerror( errmsg );
  899. X    }
  900. X
  901. X
  902. X/* flexerror - report an error message and terminate
  903. X *
  904. X * synopsis
  905. X *    char msg[];
  906. X *    flexerror( msg );
  907. X */
  908. X
  909. Xflexerror( msg )
  910. Xchar msg[];
  911. X
  912. X    {
  913. X    fprintf( stderr, "flex: %s\n", msg );
  914. X
  915. X    flexend( 1 );
  916. X    }
  917. X
  918. X
  919. X/* flexfatal - report a fatal error message and terminate
  920. X *
  921. X * synopsis
  922. X *    char msg[];
  923. X *    flexfatal( msg );
  924. X */
  925. X
  926. Xflexfatal( msg )
  927. Xchar msg[];
  928. X
  929. X    {
  930. X    fprintf( stderr, "flex: fatal internal error %s\n", msg );
  931. X    flexend( 1 );
  932. X    }
  933. X
  934. X
  935. X/* line_directive_out - spit out a "# line" statement */
  936. X
  937. Xline_directive_out( output_file_name )
  938. XFILE *output_file_name;
  939. X
  940. X    {
  941. X    if ( infilename && gen_line_dirs ) 
  942. X        fprintf( output_file_name, "# line %d \"%s\"\n", linenum, infilename );
  943. X    }
  944. X
  945. X
  946. X/* mk2data - generate a data statement for a two-dimensional array
  947. X *
  948. X * synopsis
  949. X *    int value;
  950. X *    mk2data( value );
  951. X *
  952. X *  generates a data statement initializing the current 2-D array to "value"
  953. X */
  954. Xmk2data( value )
  955. Xint value;
  956. X
  957. X    {
  958. X    if ( datapos >= NUMDATAITEMS )
  959. X    {
  960. X    putchar( ',' );
  961. X    dataflush();
  962. X    }
  963. X
  964. X    if ( datapos == 0 )
  965. X    /* indent */
  966. X    fputs( "    ", stdout );
  967. X
  968. X    else
  969. X    putchar( ',' );
  970. X
  971. X    ++datapos;
  972. X
  973. X    printf( "%5d", value );
  974. X    }
  975. X
  976. X
  977. X/* mkdata - generate a data statement
  978. X *
  979. X * synopsis
  980. X *    int value;
  981. X *    mkdata( value );
  982. X *
  983. X *  generates a data statement initializing the current array element to
  984. X *  "value"
  985. X */
  986. Xmkdata( value )
  987. Xint value;
  988. X
  989. X    {
  990. X    if ( datapos >= NUMDATAITEMS )
  991. X    {
  992. X    putchar( ',' );
  993. X    dataflush();
  994. X    }
  995. X
  996. X    if ( datapos == 0 )
  997. X    /* indent */
  998. X    fputs( "    ", stdout );
  999. X
  1000. X    else
  1001. X    putchar( ',' );
  1002. X
  1003. X    ++datapos;
  1004. X
  1005. X    printf( "%5d", value );
  1006. X    }
  1007. X
  1008. X
  1009. X/* myctoi - return the integer represented by a string of digits
  1010. X *
  1011. X * synopsis
  1012. X *    char array[];
  1013. X *    int val, myctoi();
  1014. X *    val = myctoi( array );
  1015. X *
  1016. X */
  1017. X
  1018. Xint myctoi( array )
  1019. Xchar array[];
  1020. X
  1021. X    {
  1022. X    int val = 0;
  1023. X
  1024. X    (void) sscanf( array, "%d", &val );
  1025. X
  1026. X    return ( val );
  1027. X    }
  1028. X
  1029. X
  1030. X/* myesc - return character corresponding to escape sequence
  1031. X *
  1032. X * synopsis
  1033. X *    char array[], c, myesc();
  1034. X *    c = myesc( array );
  1035. X *
  1036. X */
  1037. X
  1038. Xchar myesc( array )
  1039. Xchar array[];
  1040. X
  1041. X    {
  1042. X    switch ( array[1] )
  1043. X    {
  1044. X    case 'a': return ( '\a' );
  1045. X    case 'b': return ( '\b' );
  1046. X    case 'f': return ( '\f' );
  1047. X    case 'n': return ( '\n' );
  1048. X    case 'r': return ( '\r' );
  1049. X    case 't': return ( '\t' );
  1050. X    case 'v': return ( '\v' );
  1051. X
  1052. X    case '0':
  1053. X    case '1':
  1054. X    case '2':
  1055. X    case '3':
  1056. X    case '4':
  1057. X    case '5':
  1058. X    case '6':
  1059. X    case '7':
  1060. X    case '8':
  1061. X    case '9':
  1062. X        { /* \<octal> */
  1063. X        char c, esc_char;
  1064. X        register int sptr = 1;
  1065. X
  1066. X        while ( isdigit(array[sptr]) )
  1067. X        /* don't increment inside loop control because if
  1068. X         * isdigit() is a macro it will expand it to two
  1069. X         * increments ...
  1070. X         */
  1071. X        ++sptr;
  1072. X
  1073. X        c = array[sptr];
  1074. X        array[sptr] = '\0';
  1075. X
  1076. X        esc_char = otoi( array + 1 );
  1077. X        array[sptr] = c;
  1078. X
  1079. X        if ( esc_char == '\0' )
  1080. X        {
  1081. X        synerr( "escape sequence for null not allowed" );
  1082. X        return ( 1 );
  1083. X        }
  1084. X
  1085. X        return ( esc_char );
  1086. X        }
  1087. X
  1088. X    default:
  1089. X        return ( array[1] );
  1090. X    }
  1091. X    }
  1092. X
  1093. X
  1094. X/* otoi - convert an octal digit string to an integer value
  1095. X *
  1096. X * synopsis:
  1097. X *    int val, otoi();
  1098. X *    char str[];
  1099. X *    val = otoi( str );
  1100. X */
  1101. X
  1102. Xint otoi( str )
  1103. Xchar str[];
  1104. X
  1105. X    {
  1106. X    int result;
  1107. X
  1108. X    (void) sscanf( str, "%o", &result );
  1109. X
  1110. X    return ( result );
  1111. X    }
  1112. X
  1113. X
  1114. X/* readable_form - return the the human-readable form of a character
  1115. X *
  1116. X * synopsis:
  1117. X *    int c;
  1118. X *    char *readable_form();
  1119. X *    <string> = readable_form( c );
  1120. X *
  1121. X * The returned string is in static storage.
  1122. X */
  1123. X
  1124. Xchar *readable_form( c )
  1125. Xregister int c;
  1126. X
  1127. X    {
  1128. X    static char rform[10];
  1129. X
  1130. X    if ( (c >= 0 && c < 32) || c == 127 )
  1131. X    {
  1132. X    switch ( c )
  1133. X        {
  1134. X        case '\n': return ( "\\n" );
  1135. X        case '\t': return ( "\\t" );
  1136. X        case '\f': return ( "\\f" );
  1137. X        case '\r': return ( "\\r" );
  1138. X        case '\b': return ( "\\b" );
  1139. X
  1140. X        default:
  1141. X        sprintf( rform, "\\%.3o", c );
  1142. X        return ( rform );
  1143. X        }
  1144. X    }
  1145. X    
  1146. X    else if ( c == ' ' )
  1147. X    return ( "' '" );
  1148. X    
  1149. X    else
  1150. X    {
  1151. X    rform[0] = c;
  1152. X    rform[1] = '\0';
  1153. X
  1154. X    return ( rform );
  1155. X    }
  1156. X    }
  1157. X
  1158. X
  1159. X/* reallocate_array - increase the size of a dynamic array */
  1160. X
  1161. Xchar *reallocate_array( array, size, element_size )
  1162. Xchar *array;
  1163. Xint size, element_size;
  1164. X
  1165. X    {
  1166. X    register char *new_array;
  1167. X
  1168. X    /* same worry as in allocate_array(): */
  1169. X    if ( size * element_size <= 0 )
  1170. X        flexfatal( "attempt to increase array size by less than 1 byte" );
  1171. X    
  1172. X    new_array = realloc( array, (unsigned) (size * element_size ));
  1173. X
  1174. X    if ( new_array == NULL )
  1175. X    flexfatal( "attempt to increase array size failed" );
  1176. X    
  1177. X    return ( new_array );
  1178. X    }
  1179. X
  1180. X
  1181. X/* skelout - write out one section of the skeleton file
  1182. X *
  1183. X * synopsis
  1184. X *    skelout();
  1185. X *
  1186. X * DESCRIPTION
  1187. X *    Copies from skelfile to stdout until a line beginning with "%%" or
  1188. X *    EOF is found.
  1189. X */
  1190. Xskelout()
  1191. X
  1192. X    {
  1193. X    char buf[MAXLINE];
  1194. X
  1195. X    while ( fgets( buf, MAXLINE, skelfile ) != NULL )
  1196. X    if ( buf[0] == '%' && buf[1] == '%' )
  1197. X        break;
  1198. X    else
  1199. X        fputs( buf, stdout );
  1200. X    }
  1201. X
  1202. X
  1203. X/* transition_struct_out - output a yy_trans_info structure
  1204. X *
  1205. X * synopsis
  1206. X *     int element_v, element_n;
  1207. X *     transition_struct_out( element_v, element_n );
  1208. X *
  1209. X * outputs the yy_trans_info structure with the two elements, element_v and
  1210. X * element_n.  Formats the output with spaces and carriage returns.
  1211. X */
  1212. X
  1213. Xtransition_struct_out( element_v, element_n )
  1214. Xint element_v, element_n;
  1215. X
  1216. X    {
  1217. X    printf( "%7d, %5d,", element_v, element_n );
  1218. X
  1219. X    datapos += TRANS_STRUCT_PRINT_LENGTH;
  1220. X
  1221. X    if ( datapos >= 75 )
  1222. X    {
  1223. X    putchar( '\n' );
  1224. X
  1225. X    if ( ++dataline % 10 == 0 )
  1226. X        putchar( '\n' );
  1227. X
  1228. X    datapos = 0;
  1229. X    }
  1230. X    }
  1231. END_OF_FILE
  1232. if test 12468 -ne `wc -c <'flex/misc.c'`; then
  1233.     echo shar: \"'flex/misc.c'\" unpacked with wrong size!
  1234. fi
  1235. # end of 'flex/misc.c'
  1236. fi
  1237. if test -f 'flex/parse.y' -a "${1}" != "-c" ; then 
  1238.   echo shar: Will not clobber existing file \"'flex/parse.y'\"
  1239. else
  1240. echo shar: Extracting \"'flex/parse.y'\" \(13366 characters\)
  1241. sed "s/^X//" >'flex/parse.y' <<'END_OF_FILE'
  1242. X/* parse.y - parser for flex input */
  1243. X
  1244. X/*
  1245. X * Copyright (c) 1989 The Regents of the University of California.
  1246. X * All rights reserved.
  1247. X *
  1248. X * This code is derived from software contributed to Berkeley by
  1249. X * Vern Paxson.
  1250. X * 
  1251. X * The United States Government has rights in this work pursuant to
  1252. X * contract no. DE-AC03-76SF00098 between the United States Department of
  1253. X * Energy and the University of California.
  1254. X *
  1255. X * Redistribution and use in source and binary forms are permitted
  1256. X * provided that the above copyright notice and this paragraph are
  1257. X * duplicated in all such forms and that any documentation,
  1258. X * advertising materials, and other materials related to such
  1259. X * distribution and use acknowledge that the software was developed
  1260. X * by the University of California, Berkeley.  The name of the
  1261. X * University may not be used to endorse or promote products derived
  1262. X * from this software without specific prior written permission.
  1263. X * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  1264. X * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  1265. X * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  1266. X */
  1267. X
  1268. X%token CHAR NUMBER SECTEND SCDECL XSCDECL WHITESPACE NAME PREVCCL EOF_OP
  1269. X
  1270. X%{
  1271. X
  1272. X#include "flexdef.h"
  1273. X
  1274. X#ifndef lint
  1275. X
  1276. Xstatic char copyright[] =
  1277. X    "@(#) Copyright (c) 1989 The Regents of the University of California.\n";
  1278. Xstatic char CR_continuation[] = "@(#) All rights reserved.\n";
  1279. X
  1280. Xstatic char rcsid[] =
  1281. X    "@(#) $Header: parse.y,v 2.1 89/06/20 17:23:54 vern Exp $ (LBL)";
  1282. X
  1283. X#endif
  1284. X
  1285. Xint pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, actvp, rulelen;
  1286. Xint trlcontxt, xcluflg, cclsorted, varlength, variable_trail_rule;
  1287. Xchar clower();
  1288. X
  1289. Xstatic int madeany = false;  /* whether we've made the '.' character class */
  1290. Xint previous_continued_action;    /* whether the previous rule's action was '|' */
  1291. X
  1292. X%}
  1293. X
  1294. X%%
  1295. Xgoal            :  initlex sect1 sect1end sect2 initforrule
  1296. X            { /* add default rule */
  1297. X            int def_rule;
  1298. X
  1299. X            pat = cclinit();
  1300. X            cclnegate( pat );
  1301. X
  1302. X            def_rule = mkstate( -pat );
  1303. X
  1304. X            finish_rule( def_rule, false, 0, 0 );
  1305. X
  1306. X            for ( i = 1; i <= lastsc; ++i )
  1307. X                scset[i] = mkbranch( scset[i], def_rule );
  1308. X
  1309. X            if ( spprdflt )
  1310. X                fputs( "YY_FATAL_ERROR( \"flex scanner jammed\" )",
  1311. X                   temp_action_file );
  1312. X            else
  1313. X                fputs( "ECHO", temp_action_file );
  1314. X
  1315. X            fputs( ";\n\tYY_BREAK\n", temp_action_file );
  1316. X            }
  1317. X        ;
  1318. X
  1319. Xinitlex         :
  1320. X            {
  1321. X            /* initialize for processing rules */
  1322. X
  1323. X            /* create default DFA start condition */
  1324. X            scinstal( "INITIAL", false );
  1325. X            }
  1326. X        ;
  1327. X            
  1328. Xsect1        :  sect1 startconddecl WHITESPACE namelist1 '\n'
  1329. X        |
  1330. X        |  error '\n'
  1331. X            { synerr( "unknown error processing section 1" ); }
  1332. X        ;
  1333. X
  1334. Xsect1end    :  SECTEND
  1335. X        ;
  1336. X
  1337. Xstartconddecl   :  SCDECL
  1338. X            {
  1339. X            /* these productions are separate from the s1object
  1340. X             * rule because the semantics must be done before
  1341. X             * we parse the remainder of an s1object
  1342. X             */
  1343. X
  1344. X            xcluflg = false;
  1345. X            }
  1346. X        
  1347. X        |  XSCDECL
  1348. X            { xcluflg = true; }
  1349. X        ;
  1350. X
  1351. Xnamelist1    :  namelist1 WHITESPACE NAME
  1352. X            { scinstal( nmstr, xcluflg ); }
  1353. X
  1354. X        |  NAME
  1355. X            { scinstal( nmstr, xcluflg ); }
  1356. X
  1357. X        |  error
  1358. X                        { synerr( "bad start condition list" ); }
  1359. X        ;
  1360. X
  1361. Xsect2           :  sect2 initforrule flexrule '\n'
  1362. X        |
  1363. X        ;
  1364. X
  1365. Xinitforrule     :
  1366. X            {
  1367. X            /* initialize for a parse of one rule */
  1368. X            trlcontxt = variable_trail_rule = varlength = false;
  1369. X            trailcnt = headcnt = rulelen = 0;
  1370. X            current_state_type = STATE_NORMAL;
  1371. X            previous_continued_action = continued_action;
  1372. X            new_rule();
  1373. X            }
  1374. X        ;
  1375. X
  1376. Xflexrule        :  scon '^' re eol 
  1377. X                        {
  1378. X            pat = link_machines( $3, $4 );
  1379. X            finish_rule( pat, variable_trail_rule,
  1380. X                     headcnt, trailcnt );
  1381. X
  1382. X            for ( i = 1; i <= actvp; ++i )
  1383. X                scbol[actvsc[i]] =
  1384. X                mkbranch( scbol[actvsc[i]], pat );
  1385. X
  1386. X            if ( ! bol_needed )
  1387. X                {
  1388. X                bol_needed = true;
  1389. X
  1390. X                if ( performance_report )
  1391. X                fprintf( stderr,
  1392. X            "'^' operator results in sub-optimal performance\n" );
  1393. X                }
  1394. X            }
  1395. X
  1396. X        |  scon re eol 
  1397. X                        {
  1398. X            pat = link_machines( $2, $3 );
  1399. X            finish_rule( pat, variable_trail_rule,
  1400. X                     headcnt, trailcnt );
  1401. X
  1402. X            for ( i = 1; i <= actvp; ++i )
  1403. X                scset[actvsc[i]] = 
  1404. X                mkbranch( scset[actvsc[i]], pat );
  1405. X            }
  1406. X
  1407. X                |  '^' re eol 
  1408. X            {
  1409. X            pat = link_machines( $2, $3 );
  1410. X            finish_rule( pat, variable_trail_rule,
  1411. X                     headcnt, trailcnt );
  1412. X
  1413. X            /* add to all non-exclusive start conditions,
  1414. X             * including the default (0) start condition
  1415. X             */
  1416. X
  1417. X            for ( i = 1; i <= lastsc; ++i )
  1418. X                if ( ! scxclu[i] )
  1419. X                scbol[i] = mkbranch( scbol[i], pat );
  1420. X
  1421. X            if ( ! bol_needed )
  1422. X                {
  1423. X                bol_needed = true;
  1424. X
  1425. X                if ( performance_report )
  1426. X                fprintf( stderr,
  1427. X            "'^' operator results in sub-optimal performance\n" );
  1428. X                }
  1429. X            }
  1430. X
  1431. X                |  re eol 
  1432. X            {
  1433. X            pat = link_machines( $1, $2 );
  1434. X            finish_rule( pat, variable_trail_rule,
  1435. X                     headcnt, trailcnt );
  1436. X
  1437. X            for ( i = 1; i <= lastsc; ++i )
  1438. X                if ( ! scxclu[i] )
  1439. X                scset[i] = mkbranch( scset[i], pat );
  1440. X            }
  1441. X
  1442. X                |  scon EOF_OP
  1443. X            { build_eof_action(); }
  1444. X
  1445. X                |  EOF_OP
  1446. X            {
  1447. X            /* this EOF applies only to the INITIAL start cond. */
  1448. X            actvsc[actvp = 1] = 1;
  1449. X            build_eof_action();
  1450. X            }
  1451. X
  1452. X                |  error
  1453. X            { synerr( "unrecognized rule" ); }
  1454. X        ;
  1455. X
  1456. Xscon            :  '<' namelist2 '>'
  1457. X        ;
  1458. X
  1459. Xnamelist2       :  namelist2 ',' NAME
  1460. X                        {
  1461. X            if ( (scnum = sclookup( nmstr )) == 0 )
  1462. X                lerrsf( "undeclared start condition %s", nmstr );
  1463. X
  1464. X            else
  1465. X                actvsc[++actvp] = scnum;
  1466. X            }
  1467. X
  1468. X        |  NAME
  1469. X            {
  1470. X            if ( (scnum = sclookup( nmstr )) == 0 )
  1471. X                lerrsf( "undeclared start condition %s", nmstr );
  1472. X            else
  1473. X                actvsc[actvp = 1] = scnum;
  1474. X            }
  1475. X
  1476. X        |  error
  1477. X            { synerr( "bad start condition list" ); }
  1478. X        ;
  1479. X
  1480. Xeol             :  '$'
  1481. X                        {
  1482. X            if ( trlcontxt )
  1483. X                {
  1484. X                synerr( "trailing context used twice" );
  1485. X                $$ = mkstate( SYM_EPSILON );
  1486. X                }
  1487. X            else
  1488. X                {
  1489. X                trlcontxt = true;
  1490. X
  1491. X                if ( ! varlength )
  1492. X                headcnt = rulelen;
  1493. X
  1494. X                ++rulelen;
  1495. X                trailcnt = 1;
  1496. X
  1497. X                eps = mkstate( SYM_EPSILON );
  1498. X                $$ = link_machines( eps, mkstate( '\n' ) );
  1499. X                }
  1500. X            }
  1501. X
  1502. X        |
  1503. X                {
  1504. X                $$ = mkstate( SYM_EPSILON );
  1505. X
  1506. X            if ( trlcontxt )
  1507. X                {
  1508. X                if ( varlength && headcnt == 0 )
  1509. X                /* both head and trail are variable-length */
  1510. X                variable_trail_rule = true;
  1511. X                else
  1512. X                trailcnt = rulelen;
  1513. X                }
  1514. X                }
  1515. X        ;
  1516. X
  1517. Xre              :  re '|' series
  1518. X                        {
  1519. X            varlength = true;
  1520. X
  1521. X            $$ = mkor( $1, $3 );
  1522. X            }
  1523. X
  1524. X        |  re2 series
  1525. X            {
  1526. X            if ( transchar[lastst[$2]] != SYM_EPSILON )
  1527. X                /* provide final transition \now/ so it
  1528. X                 * will be marked as a trailing context
  1529. X                 * state
  1530. X                 */
  1531. X                $2 = link_machines( $2, mkstate( SYM_EPSILON ) );
  1532. X
  1533. X            mark_beginning_as_normal( $2 );
  1534. X            current_state_type = STATE_NORMAL;
  1535. X
  1536. X            if ( previous_continued_action )
  1537. X                {
  1538. X                /* we need to treat this as variable trailing
  1539. X                 * context so that the backup does not happen
  1540. X                 * in the action but before the action switch
  1541. X                 * statement.  If the backup happens in the
  1542. X                 * action, then the rules "falling into" this
  1543. X                 * one's action will *also* do the backup,
  1544. X                 * erroneously.
  1545. X                 */
  1546. X                if ( ! varlength || headcnt != 0 )
  1547. X                {
  1548. X                fprintf( stderr,
  1549. X    "flex: warning - trailing context rule at line %d made variable because\n",
  1550. X                     linenum );
  1551. X                fprintf( stderr,
  1552. X                     "      of preceding '|' action\n" );
  1553. X                }
  1554. X
  1555. X                /* mark as variable */
  1556. X                varlength = true;
  1557. X                headcnt = 0;
  1558. X                }
  1559. X
  1560. X            if ( varlength && headcnt == 0 )
  1561. X                { /* variable trailing context rule */
  1562. X                /* mark the first part of the rule as the accepting
  1563. X                 * "head" part of a trailing context rule
  1564. X                 */
  1565. X                /* by the way, we didn't do this at the beginning
  1566. X                 * of this production because back then
  1567. X                 * current_state_type was set up for a trail
  1568. X                 * rule, and add_accept() can create a new
  1569. X                 * state ...
  1570. X                 */
  1571. X                add_accept( $1, num_rules | YY_TRAILING_HEAD_MASK );
  1572. X                }
  1573. X
  1574. X            $$ = link_machines( $1, $2 );
  1575. X            }
  1576. X
  1577. X        |  series
  1578. X            { $$ = $1; }
  1579. X        ;
  1580. X
  1581. X
  1582. Xre2        :  re '/'
  1583. X            {
  1584. X            /* this rule is separate from the others for "re" so
  1585. X             * that the reduction will occur before the trailing
  1586. X             * series is parsed
  1587. X             */
  1588. X
  1589. X            if ( trlcontxt )
  1590. X                synerr( "trailing context used twice" );
  1591. X            else
  1592. X                trlcontxt = true;
  1593. X
  1594. X            if ( varlength )
  1595. X                /* we hope the trailing context is fixed-length */
  1596. X                varlength = false;
  1597. X            else
  1598. X                headcnt = rulelen;
  1599. X
  1600. X            rulelen = 0;
  1601. X
  1602. X            current_state_type = STATE_TRAILING_CONTEXT;
  1603. X            $$ = $1;
  1604. X            }
  1605. X        ;
  1606. X
  1607. Xseries          :  series singleton
  1608. X                        {
  1609. X            /* this is where concatenation of adjacent patterns
  1610. X             * gets done
  1611. X             */
  1612. X            $$ = link_machines( $1, $2 );
  1613. X            }
  1614. X
  1615. X        |  singleton
  1616. X            { $$ = $1; }
  1617. X        ;
  1618. X
  1619. Xsingleton       :  singleton '*'
  1620. X                        {
  1621. X            varlength = true;
  1622. X
  1623. X            $$ = mkclos( $1 );
  1624. X            }
  1625. X            
  1626. X        |  singleton '+'
  1627. X            {
  1628. X            varlength = true;
  1629. X
  1630. X            $$ = mkposcl( $1 );
  1631. X            }
  1632. X
  1633. X        |  singleton '?'
  1634. X            {
  1635. X            varlength = true;
  1636. X
  1637. X            $$ = mkopt( $1 );
  1638. X            }
  1639. X
  1640. X        |  singleton '{' NUMBER ',' NUMBER '}'
  1641. X            {
  1642. X            varlength = true;
  1643. X
  1644. X            if ( $3 > $5 || $3 < 0 )
  1645. X                {
  1646. X                synerr( "bad iteration values" );
  1647. X                $$ = $1;
  1648. X                }
  1649. X            else
  1650. X                {
  1651. X                if ( $3 == 0 )
  1652. X                $$ = mkopt( mkrep( $1, $3, $5 ) );
  1653. X                else
  1654. X                $$ = mkrep( $1, $3, $5 );
  1655. X                }
  1656. X            }
  1657. X                
  1658. X        |  singleton '{' NUMBER ',' '}'
  1659. X            {
  1660. X            varlength = true;
  1661. X
  1662. X            if ( $3 <= 0 )
  1663. X                {
  1664. X                synerr( "iteration value must be positive" );
  1665. X                $$ = $1;
  1666. X                }
  1667. X
  1668. X            else
  1669. X                $$ = mkrep( $1, $3, INFINITY );
  1670. X            }
  1671. X
  1672. X        |  singleton '{' NUMBER '}'
  1673. X            {
  1674. X            /* the singleton could be something like "(foo)",
  1675. X             * in which case we have no idea what its length
  1676. X             * is, so we punt here.
  1677. X             */
  1678. X            varlength = true;
  1679. X
  1680. X            if ( $3 <= 0 )
  1681. X                {
  1682. X                synerr( "iteration value must be positive" );
  1683. X                $$ = $1;
  1684. X                }
  1685. X
  1686. X            else
  1687. X                $$ = link_machines( $1, copysingl( $1, $3 - 1 ) );
  1688. X            }
  1689. X
  1690. X        |  '.'
  1691. X            {
  1692. X            if ( ! madeany )
  1693. X                {
  1694. X                /* create the '.' character class */
  1695. X                anyccl = cclinit();
  1696. X                ccladd( anyccl, '\n' );
  1697. X                cclnegate( anyccl );
  1698. X
  1699. X                if ( useecs )
  1700. X                mkeccl( ccltbl + cclmap[anyccl],
  1701. X                    ccllen[anyccl], nextecm,
  1702. X                    ecgroup, CSIZE );
  1703. X                
  1704. X                madeany = true;
  1705. X                }
  1706. X
  1707. X            ++rulelen;
  1708. X
  1709. X            $$ = mkstate( -anyccl );
  1710. X            }
  1711. X
  1712. X        |  fullccl
  1713. X            {
  1714. X            if ( ! cclsorted )
  1715. X                /* sort characters for fast searching.  We use a
  1716. X                 * shell sort since this list could be large.
  1717. X                 */
  1718. X                cshell( ccltbl + cclmap[$1], ccllen[$1] );
  1719. X
  1720. X            if ( useecs )
  1721. X                mkeccl( ccltbl + cclmap[$1], ccllen[$1],
  1722. X                    nextecm, ecgroup, CSIZE );
  1723. X                     
  1724. X            ++rulelen;
  1725. X
  1726. X            $$ = mkstate( -$1 );
  1727. X            }
  1728. X
  1729. X        |  PREVCCL
  1730. X            {
  1731. X            ++rulelen;
  1732. X
  1733. X            $$ = mkstate( -$1 );
  1734. X            }
  1735. X
  1736. X        |  '"' string '"'
  1737. X            { $$ = $2; }
  1738. X
  1739. X        |  '(' re ')'
  1740. X            { $$ = $2; }
  1741. X
  1742. X        |  CHAR
  1743. X            {
  1744. X            ++rulelen;
  1745. X
  1746. X            if ( $1 == '\0' )
  1747. X                synerr( "null in rule" );
  1748. X
  1749. X            if ( caseins && $1 >= 'A' && $1 <= 'Z' )
  1750. X                $1 = clower( $1 );
  1751. X
  1752. X            $$ = mkstate( $1 );
  1753. X            }
  1754. X        ;
  1755. X
  1756. Xfullccl        :  '[' ccl ']'
  1757. X            { $$ = $2; }
  1758. X
  1759. X        |  '[' '^' ccl ']'
  1760. X            {
  1761. X            /* *Sigh* - to be compatible Unix lex, negated ccls
  1762. X             * match newlines
  1763. X             */
  1764. X#ifdef NOTDEF
  1765. X            ccladd( $3, '\n' ); /* negated ccls don't match '\n' */
  1766. X            cclsorted = false; /* because we added the newline */
  1767. X#endif
  1768. X            cclnegate( $3 );
  1769. X            $$ = $3;
  1770. X            }
  1771. X        ;
  1772. X
  1773. Xccl             :  ccl CHAR '-' CHAR
  1774. X                        {
  1775. X            if ( $2 > $4 )
  1776. X                synerr( "negative range in character class" );
  1777. X
  1778. X            else
  1779. X                {
  1780. X                if ( caseins )
  1781. X                {
  1782. X                if ( $2 >= 'A' && $2 <= 'Z' )
  1783. X                    $2 = clower( $2 );
  1784. X                if ( $4 >= 'A' && $4 <= 'Z' )
  1785. X                    $4 = clower( $4 );
  1786. X                }
  1787. X
  1788. X                for ( i = $2; i <= $4; ++i )
  1789. X                    ccladd( $1, i );
  1790. X
  1791. X                /* keep track if this ccl is staying in alphabetical
  1792. X                 * order
  1793. X                 */
  1794. X                cclsorted = cclsorted && ($2 > lastchar);
  1795. X                lastchar = $4;
  1796. X                }
  1797. X            
  1798. X            $$ = $1;
  1799. X            }
  1800. X
  1801. X        |  ccl CHAR
  1802. X                {
  1803. X            if ( caseins )
  1804. X                if ( $2 >= 'A' && $2 <= 'Z' )
  1805. X                $2 = clower( $2 );
  1806. X
  1807. X            ccladd( $1, $2 );
  1808. X            cclsorted = cclsorted && ($2 > lastchar);
  1809. X            lastchar = $2;
  1810. X            $$ = $1;
  1811. X            }
  1812. X
  1813. X        |
  1814. X            {
  1815. X            cclsorted = true;
  1816. X            lastchar = 0;
  1817. X            $$ = cclinit();
  1818. X            }
  1819. X        ;
  1820. X
  1821. Xstring        :  string CHAR
  1822. X                        {
  1823. X            if ( caseins )
  1824. X                if ( $2 >= 'A' && $2 <= 'Z' )
  1825. X                $2 = clower( $2 );
  1826. X
  1827. X            ++rulelen;
  1828. X
  1829. X            $$ = link_machines( $1, mkstate( $2 ) );
  1830. X            }
  1831. X
  1832. X        |
  1833. X            { $$ = mkstate( SYM_EPSILON ); }
  1834. X        ;
  1835. X
  1836. X%%
  1837. X
  1838. X
  1839. X/* build_eof_action - build the "<<EOF>>" action for the active start
  1840. X *                    conditions
  1841. X */
  1842. X
  1843. Xbuild_eof_action()
  1844. X
  1845. X    {
  1846. X    register int i;
  1847. X
  1848. X    for ( i = 1; i <= actvp; ++i )
  1849. X    {
  1850. X    if ( sceof[actvsc[i]] )
  1851. X        lerrsf( "multiple <<EOF>> rules for start condition %s",
  1852. X            scname[actvsc[i]] );
  1853. X
  1854. X    else
  1855. X        {
  1856. X        sceof[actvsc[i]] = true;
  1857. X        fprintf( temp_action_file, "case YY_STATE_EOF(%s):\n",
  1858. X             scname[actvsc[i]] );
  1859. X        }
  1860. X    }
  1861. X
  1862. X    line_directive_out( temp_action_file );
  1863. X    }
  1864. X
  1865. X
  1866. X/* synerr - report a syntax error
  1867. X *
  1868. X * synopsis
  1869. X *    char str[];
  1870. X *    synerr( str );
  1871. X */
  1872. X
  1873. Xsynerr( str )
  1874. Xchar str[];
  1875. X
  1876. X    {
  1877. X    syntaxerror = true;
  1878. X    fprintf( stderr, "Syntax error at line %d: %s\n", linenum, str );
  1879. X    }
  1880. X
  1881. X
  1882. X/* yyerror - eat up an error message from the parser
  1883. X *
  1884. X * synopsis
  1885. X *    char msg[];
  1886. X *    yyerror( msg );
  1887. X */
  1888. X
  1889. Xyyerror( msg )
  1890. Xchar msg[];
  1891. X
  1892. X    {
  1893. X    }
  1894. END_OF_FILE
  1895. if test 13366 -ne `wc -c <'flex/parse.y'`; then
  1896.     echo shar: \"'flex/parse.y'\" unpacked with wrong size!
  1897. fi
  1898. # end of 'flex/parse.y'
  1899. fi
  1900. echo shar: End of archive 2 \(of 7\).
  1901. cp /dev/null ark2isdone
  1902. MISSING=""
  1903. for I in 1 2 3 4 5 6 7 ; do
  1904.     if test ! -f ark${I}isdone ; then
  1905.     MISSING="${MISSING} ${I}"
  1906.     fi
  1907. done
  1908. if test "${MISSING}" = "" ; then
  1909.     echo You have unpacked all 7 archives.
  1910.     rm -f ark[1-9]isdone
  1911. else
  1912.     echo You still need to unpack the following archives:
  1913.     echo "        " ${MISSING}
  1914. fi
  1915. ##  End of shell archive.
  1916. exit 0
  1917.