]>
git.saurik.com Git - bison.git/blob - src/reader.c
f0c0434ca7dc5ef7124919abb0aaed6fe451c2b5
   1 /* Input parser for bison 
   2    Copyright (C) 1984, 86, 89, 92, 98, 2000 Free Software Foundation, Inc. 
   4    This file is part of Bison, the GNU Compiler Compiler. 
   6    Bison is free software; you can redistribute it and/or modify 
   7    it under the terms of the GNU General Public License as published by 
   8    the Free Software Foundation; either version 2, or (at your option) 
  11    Bison is distributed in the hope that it will be useful, 
  12    but WITHOUT ANY WARRANTY; without even the implied warranty of 
  13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
  14    GNU General Public License for more details. 
  16    You should have received a copy of the GNU General Public License 
  17    along with Bison; see the file COPYING.  If not, write to 
  18    the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 
  19    Boston, MA 02111-1307, USA.  */ 
  22 /* Read in the grammar specification and record it in the format 
  23    described in gram.h.  All guards are copied into the fguard file 
  24    and all actions into faction, in each case forming the body of a C 
  25    function (yyguard or yyaction) which contains a switch statement to 
  26    decide which guard or action to execute. 
  28    The entry point is reader ().  */ 
  58 #define YYLTYPE yyltype\n\ 
  62 /* Number of slots allocated (but not necessarily used yet) in `rline'  */ 
  65 extern int definesflag
; 
  66 extern int nolinesflag
; 
  67 extern int noparserflag
; 
  68 extern int rawtoknumflag
; 
  69 extern bucket 
*symval
; 
  71 extern int expected_conflicts
; 
  72 extern char *token_buffer
; 
  75 extern void init_lex 
PARAMS((void)); 
  76 extern char *grow_token_buffer 
PARAMS((char *)); 
  77 extern void tabinit 
PARAMS((void)); 
  78 extern void output_headers 
PARAMS((void)); 
  79 extern void output_trailers 
PARAMS((void)); 
  80 extern void free_symtab 
PARAMS((void)); 
  81 extern void open_extra_files 
PARAMS((void)); 
  82 extern char *printable_version 
PARAMS((int)); 
  83 extern void unlex 
PARAMS((int)); 
  85 extern int skip_white_space 
PARAMS((void)); 
  86 extern int parse_percent_token 
PARAMS((void)); 
  87 extern int lex 
PARAMS((void)); 
  92       struct symbol_list 
*next
; 
  99 void reader 
PARAMS((void)); 
 100 void reader_output_yylsp 
PARAMS((FILE *)); 
 101 void read_declarations 
PARAMS((void)); 
 102 void copy_definition 
PARAMS((void)); 
 103 void parse_token_decl 
PARAMS((int, int)); 
 104 void parse_start_decl 
PARAMS((void)); 
 105 void parse_type_decl 
PARAMS((void)); 
 106 void parse_assoc_decl 
PARAMS((int)); 
 107 void parse_union_decl 
PARAMS((void)); 
 108 void parse_expect_decl 
PARAMS((void)); 
 109 char *get_type_name 
PARAMS((int, symbol_list 
*)); 
 110 void copy_guard 
PARAMS((symbol_list 
*, int)); 
 111 void parse_thong_decl 
PARAMS((void)); 
 112 void copy_action 
PARAMS((symbol_list 
*, int)); 
 113 bucket 
*gensym 
PARAMS((void)); 
 114 void readgram 
PARAMS((void)); 
 115 void record_rule_line 
PARAMS((void)); 
 116 void packsymbols 
PARAMS((void)); 
 117 void output_token_defines 
PARAMS((FILE *)); 
 118 void packgram 
PARAMS((void)); 
 119 int read_signed_integer 
PARAMS((FILE *)); 
 122 static int get_type 
PARAMS((void)); 
 126 symbol_list 
*grammar
; 
 132 /* Nonzero if components of semantic values are used, implying 
 133    they must be unions.  */ 
 134 static int value_components_used
; 
 136 static int typed
;  /* nonzero if %union has been seen.  */ 
 138 static int lastprec
;  /* incremented for each %left, %right or %nonassoc seen */ 
 140 static int gensym_count
;  /* incremented for each generated symbol */ 
 142 static bucket 
*errtoken
; 
 143 static bucket 
*undeftoken
; 
 145 /* Nonzero if any action or guard uses the @n construct.  */ 
 146 static int yylsp_needed
; 
 150 skip_to_char (int target
) 
 154     complain (_("   Skipping to next \\n")); 
 156     complain (_("   Skipping to next %c"), target
); 
 159     c 
= skip_white_space(); 
 160   while (c 
!= target 
&& c 
!= EOF
); 
 166 /* Dump the string from FINPUT to FOUTPUT.  MATCH is the delimiter of 
 167    the string (either ' or ").  */ 
 170 copy_string (FILE *finput
, FILE *foutput
, int match
) 
 174   putc (match
, foutput
); 
 180         fatal (_("unterminated string at end of file")); 
 183           complain (_("unterminated string")); 
 185           c 
= match
;            /* invent terminator */ 
 195             fatal (_("unterminated string at end of file")); 
 208 /* Dump the comment from IN to OUT1 and OUT2.  C is either `*' or `/', 
 209    depending upon the type of comments used.  OUT2 might be NULL.  */ 
 212 copy_comment2 (FILE *in
, FILE *out1
, FILE* out2
, int c
) 
 217   cplus_comment 
= (c 
== '/'); 
 226       if (!cplus_comment 
&& c 
== '*') 
 256         fatal (_("unterminated comment")); 
 268 /* Dump the comment from FINPUT to FOUTPUT.  C is either `*' or `/', 
 269    depending upon the type of comments used.  */ 
 272 copy_comment (FILE *finput
, FILE *foutput
, int c
) 
 274   copy_comment2 (finput
, foutput
, NULL
, c
); 
 282   startval 
= NULL
;  /* start symbol not specified yet. */ 
 285   translations 
= 0;  /* initially assume token number translation not needed.  */ 
 287   /* Nowadays translations is always set to 1, 
 288      since we give `error' a user-token-number 
 289      to satisfy the Posix demand for YYERRCODE==256.  */ 
 296   rline_allocated 
= 10; 
 297   rline 
= NEW2(rline_allocated
, short); 
 313   /* initialize the symbol table.  */ 
 315   /* construct the error token */ 
 316   errtoken 
= getsym("error"); 
 317   errtoken
->class = STOKEN
; 
 318   errtoken
->user_token_number 
= 256; /* Value specified by posix.  */ 
 319   /* construct a token that represents all undefined literal tokens. */ 
 320   /* it is always token number 2.  */ 
 321   undeftoken 
= getsym("$undefined."); 
 322   undeftoken
->class = STOKEN
; 
 323   undeftoken
->user_token_number 
= 2; 
 324   /* Read the declaration section.  Copy %{ ... %} groups to ftable and fdefines file. 
 325      Also notice any %token, %left, etc. found there.  */ 
 327     fprintf(ftable
, "\n/*  Bison-generated parse tables, made from %s\n", 
 330     fprintf(ftable
, "\n/*  A Bison parser, made from %s\n", infile
); 
 331   fprintf(ftable
, "    by %s  */\n\n", VERSION_STRING
); 
 332   fprintf(ftable
, "#define YYBISON 1  /* Identify Bison output.  */\n\n"); 
 334   /* start writing the guard and action files, if they are needed.  */ 
 336   /* read in the grammar, build grammar in list form.  write out guards and actions.  */ 
 338   /* Now we know whether we need the line-number stack. 
 339      If we do, write its type into the .tab.h file.  */ 
 341     reader_output_yylsp(fdefines
); 
 342   /* write closing delimiters for actions and guards.  */ 
 345     fprintf(ftable
, "#define YYLSP_NEEDED\n\n"); 
 346   /* assign the symbols their symbol numbers. 
 347      Write #defines for the token symbols into fdefines if requested.  */ 
 349   /* convert the grammar into the format described in gram.h.  */ 
 351   /* free the symbol table data structure 
 352      since symbols are now all referred to by symbol number.  */ 
 357 reader_output_yylsp (FILE *f
) 
 360     fprintf(f
, LTYPESTR
); 
 363 /* Read from finput until `%%' is seen.  Discard the `%%'.  Handle any 
 364    `%' declarations, and copy the contents of any `%{ ... %}' groups 
 368 read_declarations (void) 
 375       c 
= skip_white_space(); 
 379           tok 
= parse_percent_token(); 
 386             case PERCENT_LEFT_CURLY
: 
 391               parse_token_decl (STOKEN
, SNTERM
); 
 395               parse_token_decl (SNTERM
, STOKEN
); 
 417               parse_assoc_decl(LEFT_ASSOC
); 
 421               parse_assoc_decl(RIGHT_ASSOC
); 
 425               parse_assoc_decl(NON_ASSOC
); 
 428             case SEMANTIC_PARSER
: 
 429               if (semantic_parser 
== 0) 
 444               complain (_("unrecognized: %s"), token_buffer
); 
 449         fatal (_("no input grammar")); 
 452           complain (_("unknown character: %s"), printable_version(c
)); 
 459 /* Copy the contents of a `%{ ... %}' into the definitions file.  The 
 460    `%{' has already been read.  Return after reading the `%}'.  */ 
 463 copy_definition (void) 
 466   /* -1 while reading a character if prev char was %. */ 
 467   register int after_percent
; 
 470     fprintf(fattrs
, "#line %d \"%s\"\n", lineno
, infile
); 
 491           copy_string (finput
, fattrs
, c
); 
 497           if (c 
!= '*' && c 
!= '/') 
 499           copy_comment (finput
, fattrs
, c
); 
 504                  _("unterminated `%{' definition")); 
 526 /* parse what comes after %token or %nterm. 
 527 For %token, what_is is STOKEN and what_is_not is SNTERM. 
 528 For %nterm, the arguments are reversed.  */ 
 531 parse_token_decl (int what_is
, int what_is_not
) 
 533   register int token 
= 0; 
 534   register char *typename 
= 0; 
 535   register struct bucket 
*symbol 
= NULL
;  /* pts to symbol being defined */ 
 540       int tmp_char 
= ungetc (skip_white_space (), finput
); 
 545         fatal (_("Premature EOF after %s"), token_buffer
); 
 553       if (token 
== TYPENAME
) 
 555           k 
= strlen(token_buffer
); 
 556           typename 
= NEW2(k 
+ 1, char); 
 557           strcpy(typename
, token_buffer
); 
 558           value_components_used 
= 1; 
 561       else if (token 
== IDENTIFIER 
&& *symval
->tag 
== '\"' 
 565           symval
->class = STOKEN
; 
 566           symval
->type_name 
= typename
; 
 567           symval
->user_token_number 
= symbol
->user_token_number
; 
 568           symbol
->user_token_number 
= SALIAS
; 
 570           symval
->alias 
= symbol
; 
 571           symbol
->alias 
= symval
; 
 574           nsyms
--;   /* symbol and symval combined are only one symbol */ 
 576       else if (token 
== IDENTIFIER
) 
 578           int oldclass 
= symval
->class; 
 581           if (symbol
->class == what_is_not
) 
 582             complain (_("symbol %s redefined"), symbol
->tag
); 
 583           symbol
->class = what_is
; 
 584           if (what_is 
== SNTERM 
&& oldclass 
!= SNTERM
) 
 585             symbol
->value 
= nvars
++; 
 589               if (symbol
->type_name 
== NULL
) 
 590                 symbol
->type_name 
= typename
; 
 591               else if (strcmp(typename
, symbol
->type_name
) != 0) 
 592                 complain (_("type redeclaration for %s"), symbol
->tag
); 
 595       else if (symbol 
&& token 
== NUMBER
) 
 597           symbol
->user_token_number 
= numval
; 
 602           complain (_("`%s' is invalid in %s"), 
 604                 (what_is 
== STOKEN
) ? "%token" : "%nterm"); 
 611 /* parse what comes after %thong 
 613                 %thong <type> token number literal 
 614  the <type> or number may be omitted.  The number specifies the 
 617  Two symbols are entered in the table, one for the token symbol and 
 618  one for the literal.  Both are given the <type>, if any, from the declaration. 
 619  The ->user_token_number of the first is SALIAS and the ->user_token_number 
 620  of the second is set to the number, if any, from the declaration. 
 621  The two symbols are linked via pointers in their ->alias fields. 
 623  during output_defines_table, the symbol is reported 
 624  thereafter, only the literal string is retained 
 625  it is the literal string that is output to yytname 
 629 parse_thong_decl (void) 
 632   register struct bucket 
*symbol
; 
 633   register char *typename 
= 0; 
 637   token 
= lex();                /* fetch typename or first token */ 
 638   if (token 
== TYPENAME
) { 
 639     k 
= strlen(token_buffer
); 
 640     typename 
= NEW2(k 
+ 1, char); 
 641     strcpy(typename
, token_buffer
); 
 642     value_components_used 
= 1; 
 643     token 
= lex();              /* fetch first token */ 
 646   /* process first token */ 
 648   if (token 
!= IDENTIFIER
) 
 650       complain (_("unrecognized item %s, expected an identifier"), 
 655   symval
->class = STOKEN
; 
 656   symval
->type_name 
= typename
; 
 657   symval
->user_token_number 
= SALIAS
; 
 660   token 
= lex();                /* get number or literal string */ 
 662   if (token 
== NUMBER
) { 
 664     token 
= lex();              /* okay, did number, now get literal */ 
 668   /* process literal string token */ 
 670   if (token 
!= IDENTIFIER 
|| *symval
->tag 
!= '\"') 
 672       complain (_("expected string constant instead of %s"), 
 677   symval
->class = STOKEN
; 
 678   symval
->type_name 
= typename
; 
 679   symval
->user_token_number 
= usrtoknum
; 
 681   symval
->alias 
= symbol
; 
 682   symbol
->alias 
= symval
; 
 684   nsyms
--;                      /* symbol and symval combined are only one symbol */ 
 688 /* Parse what comes after %start */ 
 691 parse_start_decl (void) 
 694     complain (_("multiple %s declarations"), "%start"); 
 695   if (lex () != IDENTIFIER
) 
 696     complain (_("invalid %s declaration"), "%start"); 
 706 /* read in a %type declaration and record its information for get_type_name to access */ 
 709 parse_type_decl (void) 
 714   if (lex() != TYPENAME
) 
 716       complain ("%s", _("%type declaration has no <typename>")); 
 721   k 
= strlen(token_buffer
); 
 722   name 
= NEW2(k 
+ 1, char); 
 723   strcpy(name
, token_buffer
); 
 728       int tmp_char 
= ungetc (skip_white_space (), finput
); 
 733         fatal (_("Premature EOF after %s"), token_buffer
); 
 745           if (symval
->type_name 
== NULL
) 
 746             symval
->type_name 
= name
; 
 747           else if (strcmp(name
, symval
->type_name
) != 0) 
 748             complain (_("type redeclaration for %s"), symval
->tag
); 
 753           complain (_("invalid %%type declaration due to item: %s"), 
 762 /* read in a %left, %right or %nonassoc declaration and record its information.  */ 
 763 /* assoc is either LEFT_ASSOC, RIGHT_ASSOC or NON_ASSOC.  */ 
 766 parse_assoc_decl (int assoc
) 
 769   register char *name 
= NULL
; 
 770   register int prev 
= 0; 
 772   lastprec
++;  /* Assign a new precedence level, never 0.  */ 
 777       int tmp_char 
= ungetc (skip_white_space (), finput
); 
 782         fatal (_("Premature EOF after %s"), token_buffer
); 
 790           k 
= strlen(token_buffer
); 
 791           name 
= NEW2(k 
+ 1, char); 
 792           strcpy(name
, token_buffer
); 
 799           if (symval
->prec 
!= 0) 
 800             complain (_("redefining precedence of %s"), symval
->tag
); 
 801           symval
->prec 
= lastprec
; 
 802           symval
->assoc 
= assoc
; 
 803           if (symval
->class == SNTERM
) 
 804             complain (_("symbol %s redefined"), symval
->tag
); 
 805           symval
->class = STOKEN
; 
 807             { /* record the type, if one is specified */ 
 808               if (symval
->type_name 
== NULL
) 
 809                 symval
->type_name 
= name
; 
 810               else if (strcmp(name
, symval
->type_name
) != 0) 
 811                 complain (_("type redeclaration for %s"), symval
->tag
); 
 816           if (prev 
== IDENTIFIER
) 
 818               symval
->user_token_number 
= numval
; 
 823               complain (_("invalid text (%s) - number should be after identifier"), 
 833           complain (_("unexpected item: %s"), token_buffer
); 
 844 /* copy the union declaration into fattrs (and fdefines), 
 845    where it is made into the 
 846    definition of YYSTYPE, the type of elements of the parser value stack.  */ 
 849 parse_union_decl (void) 
 852   register int count 
= 0; 
 855     complain (_("multiple %s declarations"), "%union"); 
 860     fprintf (fattrs
, "\n#line %d \"%s\"\n", lineno
, infile
); 
 862     fprintf (fattrs
, "\n"); 
 864   fprintf (fattrs
, "typedef union"); 
 866     fprintf (fdefines
, "typedef union"); 
 884           if (c 
!= '*' && c 
!= '/') 
 886           copy_comment2 (finput
, fattrs
, fdefines
, c
); 
 896             complain (_("unmatched %s"), "`}'"); 
 900               fprintf (fattrs
, " YYSTYPE;\n"); 
 902                 fprintf (fdefines
, " YYSTYPE;\n"); 
 903               /* JF don't choke on trailing semi */ 
 904               c 
= skip_white_space (); 
 915 /* parse the declaration %expect N which says to expect N 
 916    shift-reduce conflicts.  */ 
 919 parse_expect_decl (void) 
 926   while (c 
== ' ' || c 
== '\t') 
 930   while (c 
>= '0' && c 
<= '9') 
 940   if (count 
<= 0 || count 
> 10) 
 941     complain ("%s", _("argument of %expect is not an integer")); 
 942   expected_conflicts 
= atoi (buffer
); 
 945 /* that's all of parsing the declaration section */ 
 947 /* FINPUT is pointing to a location (i.e., a `@').  Output to FOUTPUT 
 948    a reference to this location. STACK_OFFSET is the number of values 
 949    in the current rule so far, which says where to find `$0' with 
 950    respect to the top of the stack.  */ 
 952 copy_at (FILE *finput
, FILE *foutput
, int stack_offset
) 
 959       fprintf (foutput
, "yyloc"); 
 962   else if (isdigit(c
) || c 
== '-') 
 967       n 
= read_signed_integer (finput
); 
 969       fprintf (foutput
, "yylsp[%d]", n 
- stack_offset
); 
 973     complain (_("@%s is invalid"), printable_version (c
)); 
 977 /* Get the data type (alternative in the union) of the value for 
 978    symbol n in rule rule.  */ 
 981 get_type_name (int n
, symbol_list 
*rule
) 
 984   register symbol_list 
*rp
; 
 988       complain (_("invalid $ value")); 
 998       if (rp 
== NULL 
|| rp
->sym 
== NULL
) 
1000           complain (_("invalid $ value")); 
1006   return rp
->sym
->type_name
; 
1011 /* After `%guard' is seen in the input file, copy the actual guard 
1012    into the guards file.  If the guard is followed by an action, copy 
1013    that into the actions file.  STACK_OFFSET is the number of values 
1014    in the current rule so far, which says where to find `$0' with 
1015    respect to the top of the stack, for the simple parser in which the 
1016    stack is not popped until after the guard is run.  */ 
1019 copy_guard (symbol_list 
*rule
, int stack_offset
) 
1024   register char *type_name
; 
1027   /* offset is always 0 if parser has already popped the stack pointer */ 
1028   if (semantic_parser
) stack_offset 
= 0; 
1030   fprintf(fguard
, "\ncase %d:\n", nrules
); 
1032     fprintf (fguard
, "#line %d \"%s\"\n", lineno
, infile
); 
1038   while (brace_flag 
? (count 
> 0) : (c 
!= ';')) 
1059               complain (_("unmatched %s"), "`}'"); 
1060               c 
= getc(finput
); /* skip it */ 
1066           copy_string (finput
, fguard
, c
); 
1072           if (c 
!= '*' && c 
!= '/') 
1074           copy_comment (finput
, fguard
, c
); 
1083               register char *cp 
= token_buffer
; 
1085               while ((c 
= getc(finput
)) != '>' && c 
> 0) 
1087                   if (cp 
== token_buffer 
+ maxtoken
) 
1088                     cp 
= grow_token_buffer(cp
); 
1093               type_name 
= token_buffer
; 
1100               fprintf(fguard
, "yyval"); 
1102                 type_name 
= rule
->sym
->type_name
; 
1104                 fprintf(fguard
, ".%s", type_name
); 
1105               if(!type_name 
&& typed
) 
1106                 complain (_("$$ of `%s' has no declared type"), 
1109           else if (isdigit(c
) || c 
== '-') 
1112               n 
= read_signed_integer (finput
); 
1115               if (!type_name 
&& n 
> 0) 
1116                 type_name 
= get_type_name(n
, rule
); 
1118               fprintf(fguard
, "yyvsp[%d]", n 
- stack_offset
); 
1120                 fprintf(fguard
, ".%s", type_name
); 
1121               if (!type_name 
&& typed
) 
1122                 complain (_("$%d of `%s' has no declared type"), 
1127             complain (_("$%s is invalid"), printable_version (c
)); 
1131           copy_at (finput
, fguard
, stack_offset
); 
1136                  _("unterminated %guard clause")); 
1142       if (c 
!= '}' || count 
!= 0) 
1146   c 
= skip_white_space(); 
1148   fprintf(fguard
, ";\n    break;}"); 
1150     copy_action (rule
, stack_offset
); 
1153       c 
= getc(finput
); /* why not skip_white_space -wjh */ 
1155         copy_action (rule
, stack_offset
); 
1163 /* Assuming that a `{' has just been seen, copy everything up to the 
1164    matching `}' into the actions file.  STACK_OFFSET is the number of 
1165    values in the current rule so far, which says where to find `$0' 
1166    with respect to the top of the stack.  */ 
1169 copy_action (symbol_list 
*rule
, int stack_offset
) 
1174   register char *type_name
; 
1176   /* offset is always 0 if parser has already popped the stack pointer */ 
1177   if (semantic_parser
) 
1180   fprintf (faction
, "\ncase %d:\n", nrules
); 
1182     fprintf (faction
, "#line %d \"%s\"\n", lineno
, infile
); 
1183   putc ('{', faction
); 
1206               copy_string (finput
, faction
, c
); 
1212               if (c 
!= '*' && c 
!= '/') 
1214               copy_comment (finput
, faction
, c
); 
1223                   register char *cp 
= token_buffer
; 
1225                   while ((c 
= getc(finput
)) != '>' && c 
> 0) 
1227                       if (cp 
== token_buffer 
+ maxtoken
) 
1228                         cp 
= grow_token_buffer(cp
); 
1233                   type_name 
= token_buffer
; 
1234                   value_components_used 
= 1; 
1240                   fprintf(faction
, "yyval"); 
1242                     type_name 
= get_type_name(0, rule
); 
1244                     fprintf(faction
, ".%s", type_name
); 
1245                   if(!type_name 
&& typed
) 
1246                     complain (_("$$ of `%s' has no declared type"), 
1249               else if (isdigit(c
) || c 
== '-') 
1252                   n 
= read_signed_integer(finput
); 
1255                   if (!type_name 
&& n 
> 0) 
1256                     type_name 
= get_type_name(n
, rule
); 
1258                   fprintf(faction
, "yyvsp[%d]", n 
- stack_offset
); 
1260                     fprintf(faction
, ".%s", type_name
); 
1261                   if(!type_name 
&& typed
) 
1262                     complain (_("$%d of `%s' has no declared type"), 
1267                 complain (_("$%s is invalid"), printable_version (c
)); 
1272               copy_at (finput
, faction
, stack_offset
); 
1276               fatal (_("unmatched %s"), "`{'"); 
1285       /* above loop exits when c is '}' */ 
1294   fprintf(faction
, ";\n    break;}"); 
1299 /* generate a dummy symbol, a nonterminal, 
1300 whose name cannot conflict with the user's names. */ 
1305   register bucket 
*sym
; 
1307   sprintf (token_buffer
, "@%d", ++gensym_count
); 
1308   sym 
= getsym(token_buffer
); 
1309   sym
->class = SNTERM
; 
1310   sym
->value 
= nvars
++; 
1314 /* Parse the input grammar into a one symbol_list structure. 
1315 Each rule is represented by a sequence of symbols: the left hand side 
1316 followed by the contents of the right hand side, followed by a null pointer 
1317 instead of a symbol to terminate the rule. 
1318 The next symbol is the lhs of the following rule. 
1320 All guards and actions are copied out to the appropriate files, 
1321 labelled by the rule number they apply to.  */ 
1327   register bucket 
*lhs 
= NULL
; 
1328   register symbol_list 
*p
; 
1329   register symbol_list 
*p1
; 
1330   register bucket 
*bp
; 
1332   symbol_list 
*crule
;   /* points to first symbol_list of current rule.  */ 
1333                         /* its symbol is the lhs of the rule.   */ 
1334   symbol_list 
*crule1
;  /* points to the symbol_list preceding crule.  */ 
1340   while (t 
!= TWO_PERCENTS 
&& t 
!= ENDFILE
) 
1342       if (t 
== IDENTIFIER 
|| t 
== BAR
) 
1344           register int actionflag 
= 0; 
1345           int rulelength 
= 0;  /* number of symbols in rhs of this rule so far  */ 
1346           int xactions 
= 0;     /* JF for error checking */ 
1347           bucket 
*first_rhs 
= 0; 
1349           if (t 
== IDENTIFIER
) 
1362                   complain (_("ill-formed rule: initial symbol not followed by colon")); 
1367           if (nrules 
== 0 && t 
== BAR
) 
1369               complain (_("grammar starts with vertical bar")); 
1370               lhs 
= symval
;     /* BOGUS: use a random symval */ 
1372           /* start a new rule and record its lhs.  */ 
1377           record_rule_line (); 
1379           p 
= NEW(symbol_list
); 
1391           /* mark the rule's lhs as a nonterminal if not already so.  */ 
1393           if (lhs
->class == SUNKNOWN
) 
1395               lhs
->class = SNTERM
; 
1399           else if (lhs
->class == STOKEN
) 
1400             complain (_("rule given for %s, which is a token"), lhs
->tag
); 
1402           /* read the rhs of the rule.  */ 
1410                   crule
->ruleprec 
= symval
; 
1414               if (! (t 
== IDENTIFIER 
|| t 
== LEFT_CURLY
)) break; 
1416               /* If next token is an identifier, see if a colon follows it. 
1417                  If one does, exit this rule now.  */ 
1418               if (t 
== IDENTIFIER
) 
1420                   register bucket 
*ssave
; 
1427                   if (t1 
== COLON
) break; 
1429                   if(!first_rhs
)        /* JF */ 
1431                   /* Not followed by colon => 
1432                      process as part of this rule's rhs.  */ 
1435               /* If we just passed an action, that action was in the middle 
1436                  of a rule, so make a dummy rule to reduce it to a 
1440                   register bucket 
*sdummy
; 
1442                   /* Since the action was written out with this rule's */ 
1443                   /* number, we must give the new rule this number */ 
1444                   /* by inserting the new rule before it.  */ 
1446                   /* Make a dummy nonterminal, a gensym.  */ 
1449                   /* Make a new rule, whose body is empty, 
1450                      before the current one, so that the action 
1451                      just read can belong to it.  */ 
1454                   record_rule_line (); 
1455                   p 
= NEW(symbol_list
); 
1460                   crule1 
= NEW(symbol_list
); 
1462                   crule1
->next 
= crule
; 
1464                   /* insert the dummy generated by that rule into this rule.  */ 
1466                   p 
= NEW(symbol_list
); 
1474               if (t 
== IDENTIFIER
) 
1477                   p 
= NEW(symbol_list
); 
1482               else /* handle an action.  */ 
1484                   copy_action(crule
, rulelength
); 
1486                   xactions
++;   /* JF */ 
1489             }   /* end of  read rhs of rule */ 
1491           /* Put an empty link in the list to mark the end of this rule  */ 
1492           p 
= NEW(symbol_list
); 
1498               complain (_("two @prec's in a row")); 
1500               crule
->ruleprec 
= symval
; 
1505               if (! semantic_parser
) 
1507                           _("%guard present but %semantic_parser not specified")); 
1509               copy_guard(crule
, rulelength
); 
1512           else if (t 
== LEFT_CURLY
) 
1514                 /* This case never occurs -wjh */ 
1516                 complain (_("two actions at end of one rule")); 
1517               copy_action(crule
, rulelength
); 
1519               xactions
++;       /* -wjh */ 
1522           /* If $$ is being set in default way, report if any type 
1526                    && lhs
->type_name 
!= first_rhs
->type_name
) 
1528               if (lhs
->type_name 
== 0 
1529                   || first_rhs
->type_name 
== 0 
1530                   || strcmp(lhs
->type_name
,first_rhs
->type_name
)) 
1531                 complain (_("type clash (`%s' `%s') on default action"), 
1532                           lhs
->type_name 
? lhs
->type_name 
: "", 
1533                              first_rhs
->type_name 
? first_rhs
->type_name 
: ""); 
1535           /* Warn if there is no default for $$ but we need one.  */ 
1536           else if (!xactions 
&& !first_rhs 
&& lhs
->type_name 
!= 0) 
1537             complain (_("empty rule for typed nonterminal, and no action")); 
1542   /* these things can appear as alternatives to rules.  */ 
1544         a) none of the documentation allows them 
1545         b) most of them scan forward until finding a next % 
1546                 thus they may swallow lots of intervening rules 
1548       else if (t 
== TOKEN
) 
1550           parse_token_decl(STOKEN
, SNTERM
); 
1553       else if (t 
== NTERM
) 
1555           parse_token_decl(SNTERM
, STOKEN
); 
1562       else if (t 
== UNION
) 
1567       else if (t 
== EXPECT
) 
1569           parse_expect_decl(); 
1572       else if (t 
== START
) 
1581           complain (_("invalid input: %s"), token_buffer
); 
1586   /* grammar has been read.  Do some checking */ 
1588   if (nsyms 
> MAXSHORT
) 
1589     fatal (_("too many symbols (tokens plus nonterminals); maximum %d"), 
1592     fatal (_("no rules in the input grammar")); 
1594   if (typed 
== 0        /* JF put out same default YYSTYPE as YACC does */ 
1595       && !value_components_used
) 
1597       /* We used to use `unsigned long' as YYSTYPE on MSDOS, 
1598          but it seems better to be consistent. 
1599          Most programs should declare their own type anyway.  */ 
1600       fprintf(fattrs
, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n"); 
1602         fprintf(fdefines
, "#ifndef YYSTYPE\n#define YYSTYPE int\n#endif\n"); 
1605   /* Report any undefined symbols and consider them nonterminals.  */ 
1607   for (bp 
= firstsymbol
; bp
; bp 
= bp
->next
) 
1608     if (bp
->class == SUNKNOWN
) 
1610         complain (_("symbol %s is used, but is not defined as a token and has no rules"), 
1613         bp
->value 
= nvars
++; 
1616   ntokens 
= nsyms 
- nvars
; 
1621 record_rule_line (void) 
1623   /* Record each rule's source line number in rline table.  */ 
1625   if (nrules 
>= rline_allocated
) 
1627       rline_allocated 
= nrules 
* 2; 
1628       rline 
= (short *) xrealloc ((char *) rline
, 
1629                                   rline_allocated 
* sizeof (short)); 
1631   rline
[nrules
] = lineno
; 
1636 /* read in a %type declaration and record its information for get_type_name to access */ 
1637 /* this is unused.  it is only called from the #if 0 part of readgram */ 
1643   register char *name
; 
1649       complain (_("invalid %s declaration"), "%type"); 
1653   k 
= strlen(token_buffer
); 
1654   name 
= NEW2(k 
+ 1, char); 
1655   strcpy(name
, token_buffer
); 
1670           if (symval
->type_name 
== NULL
) 
1671             symval
->type_name 
= name
; 
1672           else if (strcmp(name
, symval
->type_name
) != 0) 
1673             complain (_("type redeclaration for %s"), symval
->tag
); 
1685 /* Assign symbol numbers, and write definition of token names into 
1686    fdefines.  Set up vectors tags and sprec of names and precedences 
1692   register bucket 
*bp
; 
1693   register int tokno 
= 1; 
1695   register int last_user_token_number
; 
1697   /* int lossage = 0; JF set but not used */ 
1699   tags 
= NEW2(nsyms 
+ 1, char *); 
1701   user_toknums 
= NEW2(nsyms 
+ 1, int); 
1702   user_toknums
[0] = 0; 
1704   sprec 
= NEW2(nsyms
, short); 
1705   sassoc 
= NEW2(nsyms
, short); 
1707   max_user_token_number 
= 256; 
1708   last_user_token_number 
= 256; 
1710   for (bp 
= firstsymbol
; bp
; bp 
= bp
->next
) 
1712       if (bp
->class == SNTERM
) 
1714           bp
->value 
+= ntokens
; 
1718           /* this symbol and its alias are a single token defn. 
1719              allocate a tokno, and assign to both check agreement of 
1720              ->prec and ->assoc fields and make both the same */ 
1722             bp
->value 
= bp
->alias
->value 
= tokno
++; 
1724           if (bp
->prec 
!= bp
->alias
->prec
) 
1726               if (bp
->prec 
!= 0 && bp
->alias
->prec 
!= 0 
1727                   && bp
->user_token_number 
== SALIAS
) 
1728                 complain (_("conflicting precedences for %s and %s"), 
1729                           bp
->tag
, bp
->alias
->tag
); 
1731                 bp
->alias
->prec 
= bp
->prec
; 
1733                 bp
->prec 
= bp
->alias
->prec
; 
1736           if (bp
->assoc 
!= bp
->alias
->assoc
) 
1738               if (bp
->assoc 
!= 0 && bp
->alias
->assoc 
!= 0 
1739                   && bp
->user_token_number 
== SALIAS
) 
1740                 complain (_("conflicting assoc values for %s and %s"), 
1741                           bp
->tag
, bp
->alias
->tag
); 
1743                 bp
->alias
->assoc 
= bp
->assoc
; 
1745                 bp
->assoc 
= bp
->alias
->assoc
; 
1748           if (bp
->user_token_number 
== SALIAS
) 
1749             continue;  /* do not do processing below for SALIASs */ 
1752       else  /* bp->class == STOKEN */ 
1754           bp
->value 
= tokno
++; 
1757       if (bp
->class == STOKEN
) 
1759           if (translations 
&& !(bp
->user_token_number
)) 
1760             bp
->user_token_number 
= ++last_user_token_number
; 
1761           if (bp
->user_token_number 
> max_user_token_number
) 
1762             max_user_token_number 
= bp
->user_token_number
; 
1765       tags
[bp
->value
] = bp
->tag
; 
1766       user_toknums
[bp
->value
] = bp
->user_token_number
; 
1767       sprec
[bp
->value
] = bp
->prec
; 
1768       sassoc
[bp
->value
] = bp
->assoc
; 
1776       token_translations 
= NEW2(max_user_token_number
+1, short); 
1778       /* initialize all entries for literal tokens to 2, the internal 
1779          token number for $undefined., which represents all invalid 
1781       for (i 
= 0; i 
<= max_user_token_number
; i
++) 
1782         token_translations
[i
] = 2; 
1784       for (bp 
= firstsymbol
; bp
; bp 
= bp
->next
) 
1786           if (bp
->value 
>= ntokens
) 
1787             continue;             /* non-terminal */ 
1788           if (bp
->user_token_number 
== SALIAS
) 
1790           if (token_translations
[bp
->user_token_number
] != 2) 
1791             complain (_("tokens %s and %s both assigned number %d"), 
1792                       tags
[token_translations
[bp
->user_token_number
]], 
1794                   bp
->user_token_number
); 
1795           token_translations
[bp
->user_token_number
] = bp
->value
; 
1799   error_token_number 
= errtoken
->value
; 
1802     output_token_defines(ftable
); 
1804   if (startval
->class == SUNKNOWN
) 
1805     fatal (_("the start symbol %s is undefined"), startval
->tag
); 
1806   else if (startval
->class == STOKEN
) 
1807     fatal (_("the start symbol %s is a token"), startval
->tag
); 
1809   start_symbol 
= startval
->value
; 
1813       output_token_defines(fdefines
); 
1817           if (spec_name_prefix
) 
1818             fprintf(fdefines
, "\nextern YYSTYPE %slval;\n", spec_name_prefix
); 
1820             fprintf(fdefines
, "\nextern YYSTYPE yylval;\n"); 
1823       if (semantic_parser
) 
1824         for (i 
= ntokens
; i 
< nsyms
; i
++) 
1826             /* don't make these for dummy nonterminals made by gensym.  */ 
1827             if (*tags
[i
] != '@') 
1828               fprintf(fdefines
, "#define\tNT%s\t%d\n", tags
[i
], i
); 
1831       /* `fdefines' is now a temporary file, so we need to copy its 
1832          contents in `done', so we can't close it here.  */ 
1839 /* For named tokens, but not literal ones, define the name.  The value 
1840    is the user token number.  */ 
1843 output_token_defines (FILE *file
) 
1846   register char *cp
, *symbol
; 
1849   for (bp 
= firstsymbol
; bp
; bp 
= bp
->next
) 
1851       symbol 
= bp
->tag
;                         /* get symbol */ 
1853       if (bp
->value 
>= ntokens
) continue; 
1854       if (bp
->user_token_number 
== SALIAS
) continue; 
1855       if ('\'' == *symbol
) continue;    /* skip literal character */ 
1856       if (bp 
== errtoken
) continue;     /* skip error token */ 
1857       if ('\"' == *symbol
) 
1859                 /* use literal string only if given a symbol with an alias */ 
1861                         symbol 
= bp
->alias
->tag
; 
1866       /* Don't #define nonliteral tokens whose names contain periods.  */ 
1868       while ((c 
= *cp
++) && c 
!= '.'); 
1869       if (c 
!= '\0')  continue; 
1871       fprintf (file
, "#define\t%s\t%d\n", symbol
, 
1872                ((translations 
&& ! rawtoknumflag
) 
1873                 ? bp
->user_token_number
 
1875       if (semantic_parser
) 
1876         fprintf (file
, "#define\tT%s\t%d\n", symbol
, bp
->value
); 
1884 /* convert the rules into the representation using rrhs, rlhs and ritems.  */ 
1889   register int itemno
; 
1890   register int ruleno
; 
1891   register symbol_list 
*p
; 
1892 /*  register bucket *bp; JF unused */ 
1896   ritem 
= NEW2(nitems 
+ 1, short); 
1897   rlhs 
= NEW2(nrules
, short) - 1; 
1898   rrhs 
= NEW2(nrules
, short) - 1; 
1899   rprec 
= NEW2(nrules
, short) - 1; 
1900   rprecsym 
= NEW2(nrules
, short) - 1; 
1901   rassoc 
= NEW2(nrules
, short) - 1; 
1909       rlhs
[ruleno
] = p
->sym
->value
; 
1910       rrhs
[ruleno
] = itemno
; 
1911       ruleprec 
= p
->ruleprec
; 
1916           ritem
[itemno
++] = p
->sym
->value
; 
1917           /* A rule gets by default the precedence and associativity 
1918              of the last token in it.  */ 
1919           if (p
->sym
->class == STOKEN
) 
1921               rprec
[ruleno
] = p
->sym
->prec
; 
1922               rassoc
[ruleno
] = p
->sym
->assoc
; 
1927       /* If this rule has a %prec, 
1928          the specified symbol's precedence replaces the default.  */ 
1931           rprec
[ruleno
] = ruleprec
->prec
; 
1932           rassoc
[ruleno
] = ruleprec
->assoc
; 
1933           rprecsym
[ruleno
] = ruleprec
->value
; 
1936       ritem
[itemno
++] = -ruleno
; 
1945 /* Read a signed integer from STREAM and return its value.  */ 
1948 read_signed_integer (FILE *stream
) 
1950   register int c 
= getc(stream
); 
1951   register int sign 
= 1; 
1962       n 
= 10*n 
+ (c 
- '0');