/[bison]/bison/src/scan-gram.l
ViewVC logotype

Diff of /bison/src/scan-gram.l

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.48 by eggert, Sat Dec 7 06:14:27 2002 UTC revision 1.49 by eggert, Wed Dec 11 06:48:18 2002 UTC
# Line 24  Line 24 
24    
25  %{  %{
26  #include "system.h"  #include "system.h"
27  #include "mbswidth.h"  
28    #include <mbswidth.h>
29    #include <get-errno.h>
30    #include <quote.h>
31    
32  #include "complain.h"  #include "complain.h"
33  #include "files.h"  #include "files.h"
 #include "quote.h"  
 #include "struniq.h"  
34  #include "getargs.h"  #include "getargs.h"
35  #include "gram.h"  #include "gram.h"
36  #include "reader.h"  #include "reader.h"
37    #include "uniqstr.h"
38    
39  #define YY_USER_INIT                                    \  #define YY_USER_INIT                                    \
40    do                                                    \    do                                                    \
# Line 45  Line 48 
48  /* Location of scanner cursor.  */  /* Location of scanner cursor.  */
49  boundary scanner_cursor;  boundary scanner_cursor;
50    
51  static void adjust_location (location_t *, char const *, size_t);  static void adjust_location (location *, char const *, size_t);
52  #define YY_USER_ACTION  adjust_location (loc, yytext, yyleng);  #define YY_USER_ACTION  adjust_location (loc, yytext, yyleng);
53    
54  static size_t no_cr_read (FILE *, char *, size_t);  static size_t no_cr_read (FILE *, char *, size_t);
55  #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))  #define YY_INPUT(buf, result, size) ((result) = no_cr_read (yyin, buf, size))
56    
57    
58  /* STRING_OBSTACK -- Used to store all the characters that we need to  /* OBSTACK_FOR_STRING -- Used to store all the characters that we need to
59     keep (to construct ID, STRINGS etc.).  Use the following macros to     keep (to construct ID, STRINGS etc.).  Use the following macros to
60     use it.     use it.
61    
# Line 61  static size_t no_cr_read (FILE *, char * Line 64  static size_t no_cr_read (FILE *, char *
64     STRING_FINISH also stores this string in LAST_STRING, which can be     STRING_FINISH also stores this string in LAST_STRING, which can be
65     used, and which is used by STRING_FREE to free the last string.  */     used, and which is used by STRING_FREE to free the last string.  */
66    
67  static struct obstack string_obstack;  static struct obstack obstack_for_string;
68    
69  /* A string representing the most recently saved token.  */  /* A string representing the most recently saved token.  */
70  static char *last_string;  static char *last_string;
71    
72    
73  #define STRING_GROW   \  #define STRING_GROW   \
74    obstack_grow (&string_obstack, yytext, yyleng)    obstack_grow (&obstack_for_string, yytext, yyleng)
75    
76  #define STRING_FINISH                                   \  #define STRING_FINISH                                   \
77    do {                                                  \    do {                                                  \
78      obstack_1grow (&string_obstack, '\0');              \      obstack_1grow (&obstack_for_string, '\0');          \
79      last_string = obstack_finish (&string_obstack);     \      last_string = obstack_finish (&obstack_for_string); \
80    } while (0)    } while (0)
81    
82  #define STRING_FREE \  #define STRING_FREE \
83    obstack_free (&string_obstack, last_string)    obstack_free (&obstack_for_string, last_string)
84    
85  void  void
86  scanner_last_string_free (void)  scanner_last_string_free (void)
# Line 93  scanner_last_string_free (void) Line 96  scanner_last_string_free (void)
96     Outside of well-formed rules, RULE_LENGTH has an undefined value.  */     Outside of well-formed rules, RULE_LENGTH has an undefined value.  */
97  static int rule_length;  static int rule_length;
98    
99  static void handle_dollar (braced_code_t code_kind,  static void handle_dollar (braced_code code_kind, char *cp, location loc);
100                             char *cp, location_t location);  static void handle_at (braced_code code_kind, char *cp, location loc);
 static void handle_at (braced_code_t code_kind,  
                        char *cp, location_t location);  
101  static void handle_syncline (char *args);  static void handle_syncline (char *args);
102  static int convert_ucn_to_byte (char const *hex_text);  static int convert_ucn_to_byte (char const *hex_text);
103  static void unexpected_end_of_file (boundary, char const *);  static void unexpected_end_of_file (boundary, char const *);
# Line 131  splice  (\\[ \f\t\v]*\n)* Line 132  splice  (\\[ \f\t\v]*\n)*
132    int context_state IF_LINT (= 0);    int context_state IF_LINT (= 0);
133    
134    /* Location of most recent identifier, when applicable.  */    /* Location of most recent identifier, when applicable.  */
135    location_t id_loc IF_LINT (= *loc);    location id_loc IF_LINT (= *loc);
136    
137    /* Location where containing code started, when applicable.  */    /* Where containing code started, when applicable.  */
138    boundary code_start IF_LINT (= loc->start);    boundary code_start IF_LINT (= loc->start);
139    
140    /* Location where containing comment or string or character literal    /* Where containing comment or string or character literal started,
141       started, when applicable.  */       when applicable.  */
142    boundary token_start IF_LINT (= loc->start);    boundary token_start IF_LINT (= loc->start);
143  %}  %}
144    
# Line 223  splice  (\\[ \f\t\v]*\n)* Line 224  splice  (\\[ \f\t\v]*\n)*
224    
225    {int} {    {int} {
226      unsigned long num;      unsigned long num;
227      errno = 0;      set_errno (0);
228      num = strtoul (yytext, 0, 10);      num = strtoul (yytext, 0, 10);
229      if (INT_MAX < num || errno)      if (INT_MAX < num || get_errno ())
230        {        {
231          complain_at (*loc, _("integer out of range: %s"), quote (yytext));          complain_at (*loc, _("integer out of range: %s"), quote (yytext));
232          num = INT_MAX;          num = INT_MAX;
# Line 253  splice  (\\[ \f\t\v]*\n)* Line 254  splice  (\\[ \f\t\v]*\n)*
254    
255    /* A type. */    /* A type. */
256    "<"{tag}">" {    "<"{tag}">" {
257      obstack_grow (&string_obstack, yytext + 1, yyleng - 2);      obstack_grow (&obstack_for_string, yytext + 1, yyleng - 2);
258      STRING_FINISH;      STRING_FINISH;
259      val->struniq = struniq_new (last_string);      val->uniqstr = uniqstr_new (last_string);
260      STRING_FREE;      STRING_FREE;
261      return TYPE;      return TYPE;
262    }    }
# Line 349  splice  (\\[ \f\t\v]*\n)* Line 350  splice  (\\[ \f\t\v]*\n)*
350      STRING_GROW;      STRING_GROW;
351      STRING_FINISH;      STRING_FINISH;
352      loc->start = token_start;      loc->start = token_start;
353      val->string = last_string;      val->chars = last_string;
354      rule_length++;      rule_length++;
355      BEGIN INITIAL;      BEGIN INITIAL;
356      return STRING;      return STRING;
# Line 396  splice  (\\[ \f\t\v]*\n)* Line 397  splice  (\\[ \f\t\v]*\n)*
397      if (UCHAR_MAX < c)      if (UCHAR_MAX < c)
398        complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));        complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
399      else      else
400        obstack_1grow (&string_obstack, c);        obstack_1grow (&obstack_for_string, c);
401    }    }
402    
403    \\x[0-9abcdefABCDEF]+ {    \\x[0-9abcdefABCDEF]+ {
404      unsigned long c;      unsigned long c;
405      errno = 0;      set_errno (0);
406      c = strtoul (yytext + 2, 0, 16);      c = strtoul (yytext + 2, 0, 16);
407      if (UCHAR_MAX < c || errno)      if (UCHAR_MAX < c || get_errno ())
408        complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));        complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
409      else      else
410        obstack_1grow (&string_obstack, c);        obstack_1grow (&obstack_for_string, c);
411    }    }
412    
413    \\a   obstack_1grow (&string_obstack, '\a');    \\a   obstack_1grow (&obstack_for_string, '\a');
414    \\b   obstack_1grow (&string_obstack, '\b');    \\b   obstack_1grow (&obstack_for_string, '\b');
415    \\f   obstack_1grow (&string_obstack, '\f');    \\f   obstack_1grow (&obstack_for_string, '\f');
416    \\n   obstack_1grow (&string_obstack, '\n');    \\n   obstack_1grow (&obstack_for_string, '\n');
417    \\r   obstack_1grow (&string_obstack, '\r');    \\r   obstack_1grow (&obstack_for_string, '\r');
418    \\t   obstack_1grow (&string_obstack, '\t');    \\t   obstack_1grow (&obstack_for_string, '\t');
419    \\v   obstack_1grow (&string_obstack, '\v');    \\v   obstack_1grow (&obstack_for_string, '\v');
420    
421    /* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */    /* \\[\"\'?\\] would be shorter, but it confuses xgettext.  */
422    \\("\""|"'"|"?"|"\\")  obstack_1grow (&string_obstack, yytext[1]);    \\("\""|"'"|"?"|"\\")  obstack_1grow (&obstack_for_string, yytext[1]);
423    
424    \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {    \\(u|U[0-9abcdefABCDEF]{4})[0-9abcdefABCDEF]{4} {
425      int c = convert_ucn_to_byte (yytext);      int c = convert_ucn_to_byte (yytext);
426      if (c < 0)      if (c < 0)
427        complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));        complain_at (*loc, _("invalid escape sequence: %s"), quote (yytext));
428      else      else
429        obstack_1grow (&string_obstack, c);        obstack_1grow (&obstack_for_string, c);
430    }    }
431    \\(.|\n)      {    \\(.|\n)      {
432      complain_at (*loc, _("unrecognized escape sequence: %s"), quote (yytext));      complain_at (*loc, _("unrecognized escape sequence: %s"), quote (yytext));
# Line 508  splice  (\\[ \f\t\v]*\n)* Line 509  splice  (\\[ \f\t\v]*\n)*
509        {        {
510          STRING_FINISH;          STRING_FINISH;
511          loc->start = code_start;          loc->start = code_start;
512          val->string = last_string;          val->chars = last_string;
513          rule_length++;          rule_length++;
514          BEGIN INITIAL;          BEGIN INITIAL;
515          return BRACED_CODE;          return BRACED_CODE;
# Line 537  splice  (\\[ \f\t\v]*\n)* Line 538  splice  (\\[ \f\t\v]*\n)*
538    "%}" {    "%}" {
539      STRING_FINISH;      STRING_FINISH;
540      loc->start = code_start;      loc->start = code_start;
541      val->string = last_string;      val->chars = last_string;
542      BEGIN INITIAL;      BEGIN INITIAL;
543      return PROLOGUE;      return PROLOGUE;
544    }    }
# Line 556  splice  (\\[ \f\t\v]*\n)* Line 557  splice  (\\[ \f\t\v]*\n)*
557    <<EOF>> {    <<EOF>> {
558      STRING_FINISH;      STRING_FINISH;
559      loc->start = code_start;      loc->start = code_start;
560      val->string = last_string;      val->chars = last_string;
561      BEGIN INITIAL;      BEGIN INITIAL;
562      return EPILOGUE;      return EPILOGUE;
563    }    }
# Line 570  splice  (\\[ \f\t\v]*\n)* Line 571  splice  (\\[ \f\t\v]*\n)*
571    
572  <SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>  <SC_COMMENT,SC_LINE_COMMENT,SC_STRING,SC_CHARACTER,SC_BRACED_CODE,SC_PROLOGUE,SC_EPILOGUE>
573  {  {
574    \$    obstack_sgrow (&string_obstack, "$][");    \$    obstack_sgrow (&obstack_for_string, "$][");
575    \@    obstack_sgrow (&string_obstack, "@@");    \@    obstack_sgrow (&obstack_for_string, "@@");
576    \[    obstack_sgrow (&string_obstack, "@{");    \[    obstack_sgrow (&obstack_for_string, "@{");
577    \]    obstack_sgrow (&string_obstack, "@}");    \]    obstack_sgrow (&obstack_for_string, "@}");
578    .|\n  STRING_GROW;    .|\n  STRING_GROW;
579  }  }
580    
# Line 584  splice  (\\[ \f\t\v]*\n)* Line 585  splice  (\\[ \f\t\v]*\n)*
585     size SIZE.  */     size SIZE.  */
586    
587  static void  static void
588  adjust_location (location_t *loc, char const *token, size_t size)  adjust_location (location *loc, char const *token, size_t size)
589  {  {
590    int line = scanner_cursor.line;    int line = scanner_cursor.line;
591    int column = scanner_cursor.column;    int column = scanner_cursor.column;
# Line 669  no_cr_read (FILE *fp, char *buf, size_t Line 670  no_cr_read (FILE *fp, char *buf, size_t
670  |                                                                   |  |                                                                   |
671  | Possible inputs: $[<TYPENAME>]($|integer)                         |  | Possible inputs: $[<TYPENAME>]($|integer)                         |
672  |                                                                   |  |                                                                   |
673  | Output to the STRING_OBSTACK a reference to this semantic value.  |  | Output to OBSTACK_FOR_STRING a reference to this semantic value.  |
674  `------------------------------------------------------------------*/  `------------------------------------------------------------------*/
675    
676  static inline void  static inline void
677  handle_action_dollar (char *text, location_t location)  handle_action_dollar (char *text, location loc)
678  {  {
679    const char *type_name = NULL;    const char *type_name = NULL;
680    char *cp = text + 1;    char *cp = text + 1;
# Line 691  handle_action_dollar (char *text, locati Line 692  handle_action_dollar (char *text, locati
692    if (*cp == '$')    if (*cp == '$')
693      {      {
694        if (!type_name)        if (!type_name)
695          type_name = symbol_list_n_type_name_get (current_rule, location, 0);          type_name = symbol_list_n_type_name_get (current_rule, loc, 0);
696        if (!type_name && typed)        if (!type_name && typed)
697          complain_at (location, _("$$ of `%s' has no declared type"),          complain_at (loc, _("$$ of `%s' has no declared type"),
698                       current_rule->sym->tag);                       current_rule->sym->tag);
699        if (!type_name)        if (!type_name)
700          type_name = "";          type_name = "";
701        obstack_fgrow1 (&string_obstack,        obstack_fgrow1 (&obstack_for_string,
702                        "]b4_lhs_value([%s])[", type_name);                        "]b4_lhs_value([%s])[", type_name);
703      }      }
704    else    else
705      {      {
706        long num;        long num;
707        errno = 0;        set_errno (0);
708        num = strtol (cp, 0, 10);        num = strtol (cp, 0, 10);
709    
710        if (INT_MIN <= num && num <= rule_length && ! errno)        if (INT_MIN <= num && num <= rule_length && ! get_errno ())
711          {          {
712            int n = num;            int n = num;
713            if (!type_name && n > 0)            if (!type_name && n > 0)
714              type_name = symbol_list_n_type_name_get (current_rule, location,              type_name = symbol_list_n_type_name_get (current_rule, loc, n);
                                                      n);  
715            if (!type_name && typed)            if (!type_name && typed)
716              complain_at (location, _("$%d of `%s' has no declared type"),              complain_at (loc, _("$%d of `%s' has no declared type"),
717                        n, current_rule->sym->tag);                           n, current_rule->sym->tag);
718            if (!type_name)            if (!type_name)
719              type_name = "";              type_name = "";
720            obstack_fgrow3 (&string_obstack,            obstack_fgrow3 (&obstack_for_string,
721                            "]b4_rhs_value([%d], [%d], [%s])[",                            "]b4_rhs_value([%d], [%d], [%s])[",
722                            rule_length, n, type_name);                            rule_length, n, type_name);
723          }          }
724        else        else
725          complain_at (location, _("integer out of range: %s"), quote (text));          complain_at (loc, _("integer out of range: %s"), quote (text));
726      }      }
727  }  }
728    
# Line 733  handle_action_dollar (char *text, locati Line 733  handle_action_dollar (char *text, locati
733  `---------------------------------------------------------------*/  `---------------------------------------------------------------*/
734    
735  static inline void  static inline void
736  handle_symbol_code_dollar (char *text, location_t location)  handle_symbol_code_dollar (char *text, location loc)
737  {  {
738    char *cp = text + 1;    char *cp = text + 1;
739    if (*cp == '$')    if (*cp == '$')
740      obstack_sgrow (&string_obstack, "]b4_dollar_dollar[");      obstack_sgrow (&obstack_for_string, "]b4_dollar_dollar[");
741    else    else
742      complain_at (location, _("invalid value: %s"), quote (text));      complain_at (loc, _("invalid value: %s"), quote (text));
743  }  }
744    
745    
# Line 749  handle_symbol_code_dollar (char *text, l Line 749  handle_symbol_code_dollar (char *text, l
749  `-----------------------------------------------------------------*/  `-----------------------------------------------------------------*/
750    
751  static void  static void
752  handle_dollar (braced_code_t braced_code_kind,  handle_dollar (braced_code braced_code_kind, char *text, location loc)
                char *text, location_t location)  
753  {  {
754    switch (braced_code_kind)    switch (braced_code_kind)
755      {      {
756      case action_braced_code:      case action_braced_code:
757        handle_action_dollar (text, location);        handle_action_dollar (text, loc);
758        break;        break;
759    
760      case destructor_braced_code:      case destructor_braced_code:
761      case printer_braced_code:      case printer_braced_code:
762        handle_symbol_code_dollar (text, location);        handle_symbol_code_dollar (text, loc);
763        break;        break;
764      }      }
765  }  }
# Line 768  handle_dollar (braced_code_t braced_code Line 767  handle_dollar (braced_code_t braced_code
767    
768  /*------------------------------------------------------.  /*------------------------------------------------------.
769  | TEXT is a location token (i.e., a `@...').  Output to |  | TEXT is a location token (i.e., a `@...').  Output to |
770  | STRING_OBSTACK a reference to this location.          |  | OBSTACK_FOR_STRING a reference to this location.      |
771  `------------------------------------------------------*/  `------------------------------------------------------*/
772    
773  static inline void  static inline void
774  handle_action_at (char *text, location_t location)  handle_action_at (char *text, location loc)
775  {  {
776    char *cp = text + 1;    char *cp = text + 1;
777    locations_flag = 1;    locations_flag = 1;
778    
779    if (*cp == '$')    if (*cp == '$')
780      {      {
781        obstack_sgrow (&string_obstack, "]b4_lhs_location[");        obstack_sgrow (&obstack_for_string, "]b4_lhs_location[");
782      }      }
783    else    else
784      {      {
785        long num;        long num;
786        errno = 0;        set_errno (0);
787        num = strtol (cp, 0, 10);        num = strtol (cp, 0, 10);
788    
789        if (INT_MIN <= num && num <= rule_length && ! errno)        if (INT_MIN <= num && num <= rule_length && ! get_errno ())
790          {          {
791            int n = num;            int n = num;
792            obstack_fgrow2 (&string_obstack, "]b4_rhs_location([%d], [%d])[",            obstack_fgrow2 (&obstack_for_string, "]b4_rhs_location([%d], [%d])[",
793                            rule_length, n);                            rule_length, n);
794          }          }
795        else        else
796          complain_at (location, _("integer out of range: %s"), quote (text));          complain_at (loc, _("integer out of range: %s"), quote (text));
797      }      }
798  }  }
799    
# Line 805  handle_action_at (char *text, location_t Line 804  handle_action_at (char *text, location_t
804  `---------------------------------------------------------------*/  `---------------------------------------------------------------*/
805    
806  static inline void  static inline void
807  handle_symbol_code_at (char *text, location_t location)  handle_symbol_code_at (char *text, location loc)
808  {  {
809    char *cp = text + 1;    char *cp = text + 1;
810    if (*cp == '$')    if (*cp == '$')
811      obstack_sgrow (&string_obstack, "]b4_at_dollar[");      obstack_sgrow (&obstack_for_string, "]b4_at_dollar[");
812    else    else
813      complain_at (location, _("invalid value: %s"), quote (text));      complain_at (loc, _("invalid value: %s"), quote (text));
814  }  }
815    
816    
# Line 821  handle_symbol_code_at (char *text, locat Line 820  handle_symbol_code_at (char *text, locat
820  `-------------------------------------------------------------------*/  `-------------------------------------------------------------------*/
821    
822  static void  static void
823  handle_at (braced_code_t braced_code_kind,  handle_at (braced_code braced_code_kind, char *text, location loc)
            char *text, location_t location)  
824  {  {
825    switch (braced_code_kind)    switch (braced_code_kind)
826      {      {
827      case action_braced_code:      case action_braced_code:
828        handle_action_at (text, location);        handle_action_at (text, loc);
829        break;        break;
830    
831      case destructor_braced_code:      case destructor_braced_code:
832      case printer_braced_code:      case printer_braced_code:
833        handle_symbol_code_at (text, location);        handle_symbol_code_at (text, loc);
834        break;        break;
835      }      }
836  }  }
# Line 922  unexpected_end_of_file (boundary start, Line 920  unexpected_end_of_file (boundary start,
920  {  {
921    size_t i = strlen (token_end);    size_t i = strlen (token_end);
922    
923    location_t location;    location loc;
924    location.start = start;    loc.start = start;
925    location.end = scanner_cursor;    loc.end = scanner_cursor;
926    complain_at (location, _("missing `%s' at end of file"), token_end);    complain_at (loc, _("missing `%s' at end of file"), token_end);
927    
928    /* Adjust scanner cursor so that any later message does not count    /* Adjust scanner cursor so that any later message does not count
929       the characters about to be inserted.  */       the characters about to be inserted.  */
# Line 943  unexpected_end_of_file (boundary start, Line 941  unexpected_end_of_file (boundary start,
941  void  void
942  scanner_initialize (void)  scanner_initialize (void)
943  {  {
944    obstack_init (&string_obstack);    obstack_init (&obstack_for_string);
945  }  }
946    
947    
# Line 954  scanner_initialize (void) Line 952  scanner_initialize (void)
952  void  void
953  scanner_free (void)  scanner_free (void)
954  {  {
955    obstack_free (&string_obstack, 0);    obstack_free (&obstack_for_string, 0);
956    /* Reclaim Flex's buffers.  */    /* Reclaim Flex's buffers.  */
957    yy_delete_buffer (YY_CURRENT_BUFFER);    yy_delete_buffer (YY_CURRENT_BUFFER);
958  }  }

Legend:
Removed from v.1.48  
changed lines
  Added in v.1.49

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26