]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - usr.bin/lex/parse.y
This commit was generated by cvs2svn to compensate for changes in r51922,
[FreeBSD/FreeBSD.git] / usr.bin / lex / parse.y
1 /* parse.y - parser for flex input */
2
3 %token CHAR NUMBER SECTEND SCDECL XSCDECL NAME PREVCCL EOF_OP
4 %token OPTION_OP OPT_OUTFILE OPT_PREFIX OPT_YYCLASS
5
6 %token CCE_ALNUM CCE_ALPHA CCE_BLANK CCE_CNTRL CCE_DIGIT CCE_GRAPH
7 %token CCE_LOWER CCE_PRINT CCE_PUNCT CCE_SPACE CCE_UPPER CCE_XDIGIT
8
9 %{
10 /*-
11  * Copyright (c) 1990 The Regents of the University of California.
12  * All rights reserved.
13  *
14  * This code is derived from software contributed to Berkeley by
15  * Vern Paxson.
16  * 
17  * The United States Government has rights in this work pursuant
18  * to contract no. DE-AC03-76SF00098 between the United States
19  * Department of Energy and the University of California.
20  *
21  * Redistribution and use in source and binary forms are permitted provided
22  * that: (1) source distributions retain this entire copyright notice and
23  * comment, and (2) distributions including binaries display the following
24  * acknowledgement:  ``This product includes software developed by the
25  * University of California, Berkeley and its contributors'' in the
26  * documentation or other materials provided with the distribution and in
27  * all advertising materials mentioning features or use of this software.
28  * Neither the name of the University nor the names of its contributors may
29  * be used to endorse or promote products derived from this software without
30  * specific prior written permission.
31  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
32  * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
33  * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
34  */
35
36 /* $FreeBSD$ */
37
38
39 /* Some versions of bison are broken in that they use alloca() but don't
40  * declare it properly.  The following is the patented (just kidding!)
41  * #ifdef chud to fix the problem, courtesy of Francois Pinard.
42  */
43 #ifdef YYBISON
44 /* AIX requires this to be the first thing in the file.  What a piece.  */
45 # ifdef _AIX
46  #pragma alloca
47 # endif
48 #endif
49
50 #include "flexdef.h"
51
52 /* The remainder of the alloca() cruft has to come after including flexdef.h,
53  * so HAVE_ALLOCA_H is (possibly) defined.
54  */
55 #ifdef YYBISON
56 # ifdef __GNUC__
57 #  ifndef alloca
58 #   define alloca __builtin_alloca
59 #  endif
60 # else
61 #  if HAVE_ALLOCA_H
62 #   include <alloca.h>
63 #  else
64 #   ifdef __hpux
65 void *alloca ();
66 #   else
67 #    ifdef __TURBOC__
68 #     include <malloc.h>
69 #    else
70 char *alloca ();
71 #    endif
72 #   endif
73 #  endif
74 # endif
75 #endif
76
77 /* Bletch, ^^^^ that was ugly! */
78
79
80 int pat, scnum, eps, headcnt, trailcnt, anyccl, lastchar, i, rulelen;
81 int trlcontxt, xcluflg, currccl, cclsorted, varlength, variable_trail_rule;
82
83 int *scon_stk;
84 int scon_stk_ptr;
85
86 static int madeany = false;  /* whether we've made the '.' character class */
87 int previous_continued_action;  /* whether the previous rule's action was '|' */
88
89 /* Expand a POSIX character class expression. */
90 #define CCL_EXPR(func) \
91         { \
92         int c; \
93         for ( c = 0; c < csize; ++c ) \
94                 if ( isascii(c) && func(c) ) \
95                         ccladd( currccl, c ); \
96         }
97
98 /* While POSIX defines isblank(), it's not ANSI C. */
99 #define IS_BLANK(c) ((c) == ' ' || (c) == '\t')
100
101 /* On some over-ambitious machines, such as DEC Alpha's, the default
102  * token type is "long" instead of "int"; this leads to problems with
103  * declaring yylval in flexdef.h.  But so far, all the yacc's I've seen
104  * wrap their definitions of YYSTYPE with "#ifndef YYSTYPE"'s, so the
105  * following should ensure that the default token type is "int".
106  */
107 #define YYSTYPE int
108
109 %}
110
111 %%
112 goal            :  initlex sect1 sect1end sect2 initforrule
113                         { /* add default rule */
114                         int def_rule;
115
116                         pat = cclinit();
117                         cclnegate( pat );
118
119                         def_rule = mkstate( -pat );
120
121                         /* Remember the number of the default rule so we
122                          * don't generate "can't match" warnings for it.
123                          */
124                         default_rule = num_rules;
125
126                         finish_rule( def_rule, false, 0, 0 );
127
128                         for ( i = 1; i <= lastsc; ++i )
129                                 scset[i] = mkbranch( scset[i], def_rule );
130
131                         if ( spprdflt )
132                                 add_action(
133                                 "YY_FATAL_ERROR( \"flex scanner jammed\" )" );
134                         else
135                                 add_action( "ECHO" );
136
137                         add_action( ";\n\tYY_BREAK\n" );
138                         }
139                 ;
140
141 initlex         :
142                         { /* initialize for processing rules */
143
144                         /* Create default DFA start condition. */
145                         scinstal( "INITIAL", false );
146                         }
147                 ;
148
149 sect1           :  sect1 startconddecl namelist1
150                 |  sect1 options
151                 |
152                 |  error
153                         { synerr( "unknown error processing section 1" ); }
154                 ;
155
156 sect1end        :  SECTEND
157                         {
158                         check_options();
159                         scon_stk = allocate_integer_array( lastsc + 1 );
160                         scon_stk_ptr = 0;
161                         }
162                 ;
163
164 startconddecl   :  SCDECL
165                         { xcluflg = false; }
166
167                 |  XSCDECL
168                         { xcluflg = true; }
169                 ;
170
171 namelist1       :  namelist1 NAME
172                         { scinstal( nmstr, xcluflg ); }
173
174                 |  NAME
175                         { scinstal( nmstr, xcluflg ); }
176
177                 |  error
178                         { synerr( "bad start condition list" ); }
179                 ;
180
181 options         :  OPTION_OP optionlist
182                 ;
183
184 optionlist      :  optionlist option
185                 |
186                 ;
187
188 option          :  OPT_OUTFILE '=' NAME
189                         {
190                         outfilename = copy_string( nmstr );
191                         did_outfilename = 1;
192                         }
193                 |  OPT_PREFIX '=' NAME
194                         { prefix = copy_string( nmstr ); }
195                 |  OPT_YYCLASS '=' NAME
196                         { yyclass = copy_string( nmstr ); }
197                 ;
198
199 sect2           :  sect2 scon initforrule flexrule '\n'
200                         { scon_stk_ptr = $2; }
201                 |  sect2 scon '{' sect2 '}'
202                         { scon_stk_ptr = $2; }
203                 |
204                 ;
205
206 initforrule     :
207                         {
208                         /* Initialize for a parse of one rule. */
209                         trlcontxt = variable_trail_rule = varlength = false;
210                         trailcnt = headcnt = rulelen = 0;
211                         current_state_type = STATE_NORMAL;
212                         previous_continued_action = continued_action;
213                         in_rule = true;
214
215                         new_rule();
216                         }
217                 ;
218
219 flexrule        :  '^' rule
220                         {
221                         pat = $2;
222                         finish_rule( pat, variable_trail_rule,
223                                 headcnt, trailcnt );
224
225                         if ( scon_stk_ptr > 0 )
226                                 {
227                                 for ( i = 1; i <= scon_stk_ptr; ++i )
228                                         scbol[scon_stk[i]] =
229                                                 mkbranch( scbol[scon_stk[i]],
230                                                                 pat );
231                                 }
232
233                         else
234                                 {
235                                 /* Add to all non-exclusive start conditions,
236                                  * including the default (0) start condition.
237                                  */
238
239                                 for ( i = 1; i <= lastsc; ++i )
240                                         if ( ! scxclu[i] )
241                                                 scbol[i] = mkbranch( scbol[i],
242                                                                         pat );
243                                 }
244
245                         if ( ! bol_needed )
246                                 {
247                                 bol_needed = true;
248
249                                 if ( performance_report > 1 )
250                                         pinpoint_message(
251                         "'^' operator results in sub-optimal performance" );
252                                 }
253                         }
254
255                 |  rule
256                         {
257                         pat = $1;
258                         finish_rule( pat, variable_trail_rule,
259                                 headcnt, trailcnt );
260
261                         if ( scon_stk_ptr > 0 )
262                                 {
263                                 for ( i = 1; i <= scon_stk_ptr; ++i )
264                                         scset[scon_stk[i]] =
265                                                 mkbranch( scset[scon_stk[i]],
266                                                                 pat );
267                                 }
268
269                         else
270                                 {
271                                 for ( i = 1; i <= lastsc; ++i )
272                                         if ( ! scxclu[i] )
273                                                 scset[i] =
274                                                         mkbranch( scset[i],
275                                                                 pat );
276                                 }
277                         }
278
279                 |  EOF_OP
280                         {
281                         if ( scon_stk_ptr > 0 )
282                                 build_eof_action();
283         
284                         else
285                                 {
286                                 /* This EOF applies to all start conditions
287                                  * which don't already have EOF actions.
288                                  */
289                                 for ( i = 1; i <= lastsc; ++i )
290                                         if ( ! sceof[i] )
291                                                 scon_stk[++scon_stk_ptr] = i;
292
293                                 if ( scon_stk_ptr == 0 )
294                                         warn(
295                         "all start conditions already have <<EOF>> rules" );
296
297                                 else
298                                         build_eof_action();
299                                 }
300                         }
301
302                 |  error
303                         { synerr( "unrecognized rule" ); }
304                 ;
305
306 scon_stk_ptr    :
307                         { $$ = scon_stk_ptr; }
308                 ;
309
310 scon            :  '<' scon_stk_ptr namelist2 '>'
311                         { $$ = $2; }
312
313                 |  '<' '*' '>'
314                         {
315                         $$ = scon_stk_ptr;
316
317                         for ( i = 1; i <= lastsc; ++i )
318                                 {
319                                 int j;
320
321                                 for ( j = 1; j <= scon_stk_ptr; ++j )
322                                         if ( scon_stk[j] == i )
323                                                 break;
324
325                                 if ( j > scon_stk_ptr )
326                                         scon_stk[++scon_stk_ptr] = i;
327                                 }
328                         }
329
330                 |
331                         { $$ = scon_stk_ptr; }
332                 ;
333
334 namelist2       :  namelist2 ',' sconname
335
336                 |  sconname
337
338                 |  error
339                         { synerr( "bad start condition list" ); }
340                 ;
341
342 sconname        :  NAME
343                         {
344                         if ( (scnum = sclookup( nmstr )) == 0 )
345                                 format_pinpoint_message(
346                                         "undeclared start condition %s",
347                                         nmstr );
348                         else
349                                 {
350                                 for ( i = 1; i <= scon_stk_ptr; ++i )
351                                         if ( scon_stk[i] == scnum )
352                                                 {
353                                                 format_warn(
354                                                         "<%s> specified twice",
355                                                         scname[scnum] );
356                                                 break;
357                                                 }
358
359                                 if ( i > scon_stk_ptr )
360                                         scon_stk[++scon_stk_ptr] = scnum;
361                                 }
362                         }
363                 ;
364
365 rule            :  re2 re
366                         {
367                         if ( transchar[lastst[$2]] != SYM_EPSILON )
368                                 /* Provide final transition \now/ so it
369                                  * will be marked as a trailing context
370                                  * state.
371                                  */
372                                 $2 = link_machines( $2,
373                                                 mkstate( SYM_EPSILON ) );
374
375                         mark_beginning_as_normal( $2 );
376                         current_state_type = STATE_NORMAL;
377
378                         if ( previous_continued_action )
379                                 {
380                                 /* We need to treat this as variable trailing
381                                  * context so that the backup does not happen
382                                  * in the action but before the action switch
383                                  * statement.  If the backup happens in the
384                                  * action, then the rules "falling into" this
385                                  * one's action will *also* do the backup,
386                                  * erroneously.
387                                  */
388                                 if ( ! varlength || headcnt != 0 )
389                                         warn(
390                 "trailing context made variable due to preceding '|' action" );
391
392                                 /* Mark as variable. */
393                                 varlength = true;
394                                 headcnt = 0;
395                                 }
396
397                         if ( lex_compat || (varlength && headcnt == 0) )
398                                 { /* variable trailing context rule */
399                                 /* Mark the first part of the rule as the
400                                  * accepting "head" part of a trailing
401                                  * context rule.
402                                  *
403                                  * By the way, we didn't do this at the
404                                  * beginning of this production because back
405                                  * then current_state_type was set up for a
406                                  * trail rule, and add_accept() can create
407                                  * a new state ...
408                                  */
409                                 add_accept( $1,
410                                         num_rules | YY_TRAILING_HEAD_MASK );
411                                 variable_trail_rule = true;
412                                 }
413                         
414                         else
415                                 trailcnt = rulelen;
416
417                         $$ = link_machines( $1, $2 );
418                         }
419
420                 |  re2 re '$'
421                         { synerr( "trailing context used twice" ); }
422
423                 |  re '$'
424                         {
425                         headcnt = 0;
426                         trailcnt = 1;
427                         rulelen = 1;
428                         varlength = false;
429
430                         current_state_type = STATE_TRAILING_CONTEXT;
431
432                         if ( trlcontxt )
433                                 {
434                                 synerr( "trailing context used twice" );
435                                 $$ = mkstate( SYM_EPSILON );
436                                 }
437
438                         else if ( previous_continued_action )
439                                 {
440                                 /* See the comment in the rule for "re2 re"
441                                  * above.
442                                  */
443                                 warn(
444                 "trailing context made variable due to preceding '|' action" );
445
446                                 varlength = true;
447                                 }
448
449                         if ( lex_compat || varlength )
450                                 {
451                                 /* Again, see the comment in the rule for
452                                  * "re2 re" above.
453                                  */
454                                 add_accept( $1,
455                                         num_rules | YY_TRAILING_HEAD_MASK );
456                                 variable_trail_rule = true;
457                                 }
458
459                         trlcontxt = true;
460
461                         eps = mkstate( SYM_EPSILON );
462                         $$ = link_machines( $1,
463                                 link_machines( eps, mkstate( '\n' ) ) );
464                         }
465
466                 |  re
467                         {
468                         $$ = $1;
469
470                         if ( trlcontxt )
471                                 {
472                                 if ( lex_compat || (varlength && headcnt == 0) )
473                                         /* Both head and trail are
474                                          * variable-length.
475                                          */
476                                         variable_trail_rule = true;
477                                 else
478                                         trailcnt = rulelen;
479                                 }
480                         }
481                 ;
482
483
484 re              :  re '|' series
485                         {
486                         varlength = true;
487                         $$ = mkor( $1, $3 );
488                         }
489
490                 |  series
491                         { $$ = $1; }
492                 ;
493
494
495 re2             :  re '/'
496                         {
497                         /* This rule is written separately so the
498                          * reduction will occur before the trailing
499                          * series is parsed.
500                          */
501
502                         if ( trlcontxt )
503                                 synerr( "trailing context used twice" );
504                         else
505                                 trlcontxt = true;
506
507                         if ( varlength )
508                                 /* We hope the trailing context is
509                                  * fixed-length.
510                                  */
511                                 varlength = false;
512                         else
513                                 headcnt = rulelen;
514
515                         rulelen = 0;
516
517                         current_state_type = STATE_TRAILING_CONTEXT;
518                         $$ = $1;
519                         }
520                 ;
521
522 series          :  series singleton
523                         {
524                         /* This is where concatenation of adjacent patterns
525                          * gets done.
526                          */
527                         $$ = link_machines( $1, $2 );
528                         }
529
530                 |  singleton
531                         { $$ = $1; }
532                 ;
533
534 singleton       :  singleton '*'
535                         {
536                         varlength = true;
537
538                         $$ = mkclos( $1 );
539                         }
540
541                 |  singleton '+'
542                         {
543                         varlength = true;
544                         $$ = mkposcl( $1 );
545                         }
546
547                 |  singleton '?'
548                         {
549                         varlength = true;
550                         $$ = mkopt( $1 );
551                         }
552
553                 |  singleton '{' NUMBER ',' NUMBER '}'
554                         {
555                         varlength = true;
556
557                         if ( $3 > $5 || $3 < 0 )
558                                 {
559                                 synerr( "bad iteration values" );
560                                 $$ = $1;
561                                 }
562                         else
563                                 {
564                                 if ( $3 == 0 )
565                                         {
566                                         if ( $5 <= 0 )
567                                                 {
568                                                 synerr(
569                                                 "bad iteration values" );
570                                                 $$ = $1;
571                                                 }
572                                         else
573                                                 $$ = mkopt(
574                                                         mkrep( $1, 1, $5 ) );
575                                         }
576                                 else
577                                         $$ = mkrep( $1, $3, $5 );
578                                 }
579                         }
580
581                 |  singleton '{' NUMBER ',' '}'
582                         {
583                         varlength = true;
584
585                         if ( $3 <= 0 )
586                                 {
587                                 synerr( "iteration value must be positive" );
588                                 $$ = $1;
589                                 }
590
591                         else
592                                 $$ = mkrep( $1, $3, INFINITY );
593                         }
594
595                 |  singleton '{' NUMBER '}'
596                         {
597                         /* The singleton could be something like "(foo)",
598                          * in which case we have no idea what its length
599                          * is, so we punt here.
600                          */
601                         varlength = true;
602
603                         if ( $3 <= 0 )
604                                 {
605                                 synerr( "iteration value must be positive" );
606                                 $$ = $1;
607                                 }
608
609                         else
610                                 $$ = link_machines( $1,
611                                                 copysingl( $1, $3 - 1 ) );
612                         }
613
614                 |  '.'
615                         {
616                         if ( ! madeany )
617                                 {
618                                 /* Create the '.' character class. */
619                                 anyccl = cclinit();
620                                 ccladd( anyccl, '\n' );
621                                 cclnegate( anyccl );
622
623                                 if ( useecs )
624                                         mkeccl( ccltbl + cclmap[anyccl],
625                                                 ccllen[anyccl], nextecm,
626                                                 ecgroup, csize, csize );
627
628                                 madeany = true;
629                                 }
630
631                         ++rulelen;
632
633                         $$ = mkstate( -anyccl );
634                         }
635
636                 |  fullccl
637                         {
638                         if ( ! cclsorted )
639                                 /* Sort characters for fast searching.  We
640                                  * use a shell sort since this list could
641                                  * be large.
642                                  */
643                                 cshell( ccltbl + cclmap[$1], ccllen[$1], true );
644
645                         if ( useecs )
646                                 mkeccl( ccltbl + cclmap[$1], ccllen[$1],
647                                         nextecm, ecgroup, csize, csize );
648
649                         ++rulelen;
650
651                         $$ = mkstate( -$1 );
652                         }
653
654                 |  PREVCCL
655                         {
656                         ++rulelen;
657
658                         $$ = mkstate( -$1 );
659                         }
660
661                 |  '"' string '"'
662                         { $$ = $2; }
663
664                 |  '(' re ')'
665                         { $$ = $2; }
666
667                 |  CHAR
668                         {
669                         ++rulelen;
670
671                         if ( caseins && $1 >= 'A' && $1 <= 'Z' )
672                                 $1 = clower( $1 );
673
674                         $$ = mkstate( $1 );
675                         }
676                 ;
677
678 fullccl         :  '[' ccl ']'
679                         { $$ = $2; }
680
681                 |  '[' '^' ccl ']'
682                         {
683                         cclnegate( $3 );
684                         $$ = $3;
685                         }
686                 ;
687
688 ccl             :  ccl CHAR '-' CHAR
689                         {
690                         if ( caseins )
691                                 {
692                                 if ( $2 >= 'A' && $2 <= 'Z' )
693                                         $2 = clower( $2 );
694                                 if ( $4 >= 'A' && $4 <= 'Z' )
695                                         $4 = clower( $4 );
696                                 }
697
698                         if ( $2 > $4 )
699                                 synerr( "negative range in character class" );
700
701                         else
702                                 {
703                                 for ( i = $2; i <= $4; ++i )
704                                         ccladd( $1, i );
705
706                                 /* Keep track if this ccl is staying in
707                                  * alphabetical order.
708                                  */
709                                 cclsorted = cclsorted && ($2 > lastchar);
710                                 lastchar = $4;
711                                 }
712
713                         $$ = $1;
714                         }
715
716                 |  ccl CHAR
717                         {
718                         if ( caseins && $2 >= 'A' && $2 <= 'Z' )
719                                 $2 = clower( $2 );
720
721                         ccladd( $1, $2 );
722                         cclsorted = cclsorted && ($2 > lastchar);
723                         lastchar = $2;
724                         $$ = $1;
725                         }
726
727                 |  ccl ccl_expr
728                         {
729                         /* Too hard to properly maintain cclsorted. */
730                         cclsorted = false;
731                         $$ = $1;
732                         }
733
734                 |
735                         {
736                         cclsorted = true;
737                         lastchar = 0;
738                         currccl = $$ = cclinit();
739                         }
740                 ;
741
742 ccl_expr:          CCE_ALNUM    { CCL_EXPR(isalnum) }
743                 |  CCE_ALPHA    { CCL_EXPR(isalpha) }
744                 |  CCE_BLANK    { CCL_EXPR(IS_BLANK) }
745                 |  CCE_CNTRL    { CCL_EXPR(iscntrl) }
746                 |  CCE_DIGIT    { CCL_EXPR(isdigit) }
747                 |  CCE_GRAPH    { CCL_EXPR(isgraph) }
748                 |  CCE_LOWER    { CCL_EXPR(islower) }
749                 |  CCE_PRINT    { CCL_EXPR(isprint) }
750                 |  CCE_PUNCT    { CCL_EXPR(ispunct) }
751                 |  CCE_SPACE    { CCL_EXPR(isspace) }
752                 |  CCE_UPPER    {
753                                 if ( caseins )
754                                         CCL_EXPR(islower)
755                                 else
756                                         CCL_EXPR(isupper)
757                                 }
758                 |  CCE_XDIGIT   { CCL_EXPR(isxdigit) }
759                 ;
760                 
761 string          :  string CHAR
762                         {
763                         if ( caseins && $2 >= 'A' && $2 <= 'Z' )
764                                 $2 = clower( $2 );
765
766                         ++rulelen;
767
768                         $$ = link_machines( $1, mkstate( $2 ) );
769                         }
770
771                 |
772                         { $$ = mkstate( SYM_EPSILON ); }
773                 ;
774
775 %%
776
777
778 /* build_eof_action - build the "<<EOF>>" action for the active start
779  *                    conditions
780  */
781
782 void build_eof_action()
783         {
784         register int i;
785         char action_text[MAXLINE];
786
787         for ( i = 1; i <= scon_stk_ptr; ++i )
788                 {
789                 if ( sceof[scon_stk[i]] )
790                         format_pinpoint_message(
791                                 "multiple <<EOF>> rules for start condition %s",
792                                 scname[scon_stk[i]] );
793
794                 else
795                         {
796                         sceof[scon_stk[i]] = true;
797                         sprintf( action_text, "case YY_STATE_EOF(%s):\n",
798                                 scname[scon_stk[i]] );
799                         add_action( action_text );
800                         }
801                 }
802
803         line_directive_out( (FILE *) 0, 1 );
804
805         /* This isn't a normal rule after all - don't count it as
806          * such, so we don't have any holes in the rule numbering
807          * (which make generating "rule can never match" warnings
808          * more difficult.
809          */
810         --num_rules;
811         ++num_eof_rules;
812         }
813
814
815 /* format_synerr - write out formatted syntax error */
816
817 void format_synerr( msg, arg )
818 char msg[], arg[];
819         {
820         char errmsg[MAXLINE];
821
822         (void) sprintf( errmsg, msg, arg );
823         synerr( errmsg );
824         }
825
826
827 /* synerr - report a syntax error */
828
829 void synerr( str )
830 char str[];
831         {
832         syntaxerror = true;
833         pinpoint_message( str );
834         }
835
836
837 /* format_warn - write out formatted warning */
838
839 void format_warn( msg, arg )
840 char msg[], arg[];
841         {
842         char warn_msg[MAXLINE];
843
844         (void) sprintf( warn_msg, msg, arg );
845         warn( warn_msg );
846         }
847
848
849 /* warn - report a warning, unless -w was given */
850
851 void warn( str )
852 char str[];
853         {
854         line_warning( str, linenum );
855         }
856
857 /* format_pinpoint_message - write out a message formatted with one string,
858  *                           pinpointing its location
859  */
860
861 void format_pinpoint_message( msg, arg )
862 char msg[], arg[];
863         {
864         char errmsg[MAXLINE];
865
866         (void) sprintf( errmsg, msg, arg );
867         pinpoint_message( errmsg );
868         }
869
870
871 /* pinpoint_message - write out a message, pinpointing its location */
872
873 void pinpoint_message( str )
874 char str[];
875         {
876         line_pinpoint( str, linenum );
877         }
878
879
880 /* line_warning - report a warning at a given line, unless -w was given */
881
882 void line_warning( str, line )
883 char str[];
884 int line;
885         {
886         char warning[MAXLINE];
887
888         if ( ! nowarn )
889                 {
890                 sprintf( warning, "warning, %s", str );
891                 line_pinpoint( warning, line );
892                 }
893         }
894
895
896 /* line_pinpoint - write out a message, pinpointing it at the given line */
897
898 void line_pinpoint( str, line )
899 char str[];
900 int line;
901         {
902         fprintf( stderr, "\"%s\", line %d: %s\n", infilename, line, str );
903         }
904
905
906 /* yyerror - eat up an error message from the parser;
907  *           currently, messages are ignore
908  */
909
910 void yyerror( msg )
911 char msg[];
912         {
913         }