* corelow.c, exec.c, inftarg.c, m3-nat.c, op50-rom.c, procfs.c,
[deliverable/binutils-gdb.git] / gdb / ch-exp.y
index 40865c0517851076c08706905f71b15f11c2b8ab..b7a0b5ec8c1ff82f354061a83446a96029ee224f 100644 (file)
@@ -1,5 +1,5 @@
 /* YACC grammar for Chill expressions, for GDB.
-   Copyright (C) 1992 Free Software Foundation, Inc.
+   Copyright 1992, 1993, 1994 Free Software Foundation, Inc.
 
 This file is part of GDB.
 
@@ -54,11 +54,16 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 %{
 
 #include "defs.h"
+#include <string.h>
+#include <ctype.h>
 #include "expression.h"
 #include "language.h"
 #include "value.h"
 #include "parser-defs.h"
 #include "ch-lang.h"
+#include "bfd.h" /* Required by objfiles.h.  */
+#include "symfile.h" /* Required by objfiles.h.  */
+#include "objfiles.h" /* For have_full_symbols and have_partial_symbols */
 
 /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
    as well as gratuitiously global symbol names, so we can have multiple
@@ -82,8 +87,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        yypgo   chill_pgo
 #define        yyact   chill_act
 #define        yyexca  chill_exca
-#define yyerrflag chill_errflag
-#define yynerrs        chill_nerrs
+#define        yyerrflag chill_errflag
+#define        yynerrs chill_nerrs
 #define        yyps    chill_ps
 #define        yypv    chill_pv
 #define        yys     chill_s
@@ -94,8 +99,8 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
 #define        yy_yyv  chill_yyv
 #define        yyval   chill_val
 #define        yylloc  chill_lloc
-#define yyreds chill_reds              /* With YYDEBUG defined */
-#define yytoks chill_toks              /* With YYDEBUG defined */
+#define        yyreds  chill_reds              /* With YYDEBUG defined */
+#define        yytoks  chill_toks              /* With YYDEBUG defined */
 
 #ifndef YYDEBUG
 #define        YYDEBUG 0               /* Default to no yydebug support */
@@ -139,7 +144,35 @@ yyerror PARAMS ((char *));
     int *ivec;
   }
 
-%token <voidval> FIXME
+%token <voidval> FIXME_01
+%token <voidval> FIXME_02
+%token <voidval> FIXME_03
+%token <voidval> FIXME_04
+%token <voidval> FIXME_05
+%token <voidval> FIXME_06
+%token <voidval> FIXME_07
+%token <voidval> FIXME_08
+%token <voidval> FIXME_09
+%token <voidval> FIXME_10
+%token <voidval> FIXME_11
+%token <voidval> FIXME_12
+%token <voidval> FIXME_13
+%token <voidval> FIXME_14
+%token <voidval> FIXME_15
+%token <voidval> FIXME_16
+%token <voidval> FIXME_17
+%token <voidval> FIXME_18
+%token <voidval> FIXME_19
+%token <voidval> FIXME_20
+%token <voidval> FIXME_21
+%token <voidval> FIXME_22
+%token <voidval> FIXME_24
+%token <voidval> FIXME_25
+%token <voidval> FIXME_26
+%token <voidval> FIXME_27
+%token <voidval> FIXME_28
+%token <voidval> FIXME_29
+%token <voidval> FIXME_30
 
 %token <typed_val>     INTEGER_LITERAL
 %token <ulval>         BOOLEAN_LITERAL
@@ -149,11 +182,11 @@ yyerror PARAMS ((char *));
 %token <ssym>          LOCATION_NAME
 %token <voidval>       SET_LITERAL
 %token <voidval>       EMPTINESS_LITERAL
-%token <voidval>       CHARACTER_STRING_LITERAL
+%token <sval>          CHARACTER_STRING_LITERAL
 %token <sval>          BIT_STRING_LITERAL
+%token <tsym>          TYPENAME
+%token <sval>          FIELD_NAME
 
-%token <voidval>       STRING
-%token <voidval>       CONSTANT
 %token <voidval>       '.'
 %token <voidval>       ';'
 %token <voidval>       ':'
@@ -182,7 +215,6 @@ yyerror PARAMS ((char *));
 %token <voidval>       NOT
 %token <voidval>       POINTER
 %token <voidval>       RECEIVE
-%token <voidval>       SC
 %token <voidval>       '['
 %token <voidval>       ']'
 %token <voidval>       '('
@@ -199,8 +231,8 @@ yyerror PARAMS ((char *));
 %token <voidval>       SUCC
 %token <voidval>       ABS
 %token <voidval>       CARD
-%token <voidval>       MAX
-%token <voidval>       MIN
+%token <voidval>       MAX_TOKEN
+%token <voidval>       MIN_TOKEN
 %token <voidval>       SIZE
 %token <voidval>       UPPER
 %token <voidval>       LOWER
@@ -215,18 +247,14 @@ yyerror PARAMS ((char *));
 %token <ivar>          GDB_VARIABLE    /* Convenience variable */
 %token <voidval>       GDB_ASSIGNMENT  /* Assign value to somewhere */
 
-%type <voidval>                location
 %type <voidval>                access_name
 %type <voidval>                primitive_value
-%type <voidval>                location_contents
 %type <voidval>                value_name
 %type <voidval>                literal
 %type <voidval>                tuple
 %type <voidval>                value_string_element
 %type <voidval>                value_string_slice
-%type <voidval>                value_array_element
 %type <voidval>                value_array_slice
-%type <voidval>                value_structure_field
 %type <voidval>                expression_conversion
 %type <voidval>                value_procedure_call
 %type <voidval>                value_built_in_routine_call
@@ -249,7 +277,6 @@ yyerror PARAMS ((char *));
 %type <voidval>                operand_4
 %type <voidval>                operand_5
 %type <voidval>                operand_6
-%type <voidval>                integer_literal_expression
 %type <voidval>                synonym_name
 %type <voidval>                value_enumeration_name
 %type <voidval>                value_do_with_name
@@ -259,17 +286,13 @@ yyerror PARAMS ((char *));
 %type <voidval>                left_element
 %type <voidval>                right_element
 %type <voidval>                slice_size
-%type <voidval>                array_primitive_value
 %type <voidval>                expression_list
 %type <voidval>                lower_element
 %type <voidval>                upper_element
 %type <voidval>                first_element
-%type <voidval>                structure_primitive_value
-%type <voidval>                field_name
-%type <voidval>                mode_argument
+%type <tval>           mode_argument
 %type <voidval>                upper_lower_argument
 %type <voidval>                length_argument
-%type <voidval>                mode_name
 %type <voidval>                array_mode_name
 %type <voidval>                string_mode_name
 %type <voidval>                variant_structure_mode_name
@@ -278,13 +301,20 @@ yyerror PARAMS ((char *));
 %type <voidval>                subexpression
 %type <voidval>                case_label_specification
 %type <voidval>                buffer_location
-
 %type <voidval>                single_assignment_action
+%type <tsym>           mode_name
 
 %%
 
 /* Z.200, 5.3.1 */
 
+start  :       value { }
+       |       mode_name
+                       { write_exp_elt_opcode(OP_TYPE);
+                         write_exp_elt_type($1.type);
+                         write_exp_elt_opcode(OP_TYPE);}
+       ;
+
 value          :       expression
                        {
                          $$ = 0;       /* FIXME */
@@ -295,19 +325,7 @@ value              :       expression
                        }
                ;
 
-undefined_value        :       FIXME
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
-/* Z.200, 4.2.1 */
-
-location       :       access_name
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       FIXME
+undefined_value        :       FIXME_01
                        {
                          $$ = 0;       /* FIXME */
                        }
@@ -318,6 +336,7 @@ location    :       access_name
 access_name    :       LOCATION_NAME
                        {
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_block (NULL);
                          write_exp_elt_sym ($1.sym);
                          write_exp_elt_opcode (OP_VAR_VALUE);
                        }
@@ -339,7 +358,7 @@ access_name :       LOCATION_NAME
                          write_exp_elt_intern ($1);
                          write_exp_elt_opcode (OP_INTERNALVAR); 
                        }
-               |       FIXME
+               |       FIXME_03
                        {
                          $$ = 0;       /* FIXME */
                        }
@@ -358,9 +377,26 @@ expression_list    :       expression
 
 /* Z.200, 5.2.1 */
 
-primitive_value        :       location_contents
+primitive_value        :
+                       access_name
+               |       primitive_value '('
+                               /* This is to save the value of arglist_len
+                                  being accumulated for each dimension. */
+                               { start_arglist (); }
+                       expression_list ')'
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (MULTI_SUBSCRIPT);
+                         write_exp_elt_longcst ((LONGEST) end_arglist ());
+                         write_exp_elt_opcode (MULTI_SUBSCRIPT);
+                       }
+               |       primitive_value FIELD_NAME
+                       { write_exp_elt_opcode (STRUCTOP_STRUCT);
+                         write_exp_string ($2);
+                         write_exp_elt_opcode (STRUCTOP_STRUCT);
+                       }
+               |       primitive_value POINTER
+                       {
+                         write_exp_elt_opcode (UNOP_IND);
                        }
                 |      value_name
                        {
@@ -382,18 +418,10 @@ primitive_value   :       location_contents
                        {
                          $$ = 0;       /* FIXME */
                        }
-                |      value_array_element
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                 |      value_array_slice
                        {
                          $$ = 0;       /* FIXME */
                        }
-                |      value_structure_field
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                 |      expression_conversion
                        {
                          $$ = 0;       /* FIXME */
@@ -420,14 +448,6 @@ primitive_value    :       location_contents
                        }
                ;
 
-/* Z.200, 5.2.2 */
-
-location_contents:     location
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               ;
-
 /* Z.200, 5.2.3 */
 
 value_name     :       synonym_name
@@ -449,6 +469,7 @@ value_name  :       synonym_name
                |       GENERAL_PROCEDURE_NAME
                        {
                          write_exp_elt_opcode (OP_VAR_VALUE);
+                         write_exp_elt_block (NULL);
                          write_exp_elt_sym ($1.sym);
                          write_exp_elt_opcode (OP_VAR_VALUE);
                        }
@@ -493,7 +514,9 @@ literal             :       INTEGER_LITERAL
                        }
                |       CHARACTER_STRING_LITERAL
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (OP_STRING);
+                         write_exp_string ($1);
+                         write_exp_elt_opcode (OP_STRING);
                        }
                |       BIT_STRING_LITERAL
                        {
@@ -505,7 +528,7 @@ literal             :       INTEGER_LITERAL
 
 /* Z.200, 5.2.5 */
 
-tuple          :       FIXME
+tuple          :       FIXME_04
                        {
                          $$ = 0;       /* FIXME */
                        }
@@ -532,35 +555,13 @@ value_string_slice:       string_primitive_value '(' left_element ':' right_element ')
                        }
                ;
 
-/* Z.200, 5.2.8 */
-
-value_array_element:   array_primitive_value '('
-                               /* This is to save the value of arglist_len
-                                  being accumulated for each dimension. */
-                               { start_arglist (); }
-                       expression_list ')'
-                       {
-                         write_exp_elt_opcode (MULTI_SUBSCRIPT);
-                         write_exp_elt_longcst ((LONGEST) end_arglist ());
-                         write_exp_elt_opcode (MULTI_SUBSCRIPT);
-                       }
-               ;
-
 /* Z.200, 5.2.9 */
 
-value_array_slice:     array_primitive_value '(' lower_element ':' upper_element ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       array_primitive_value '(' first_element UP slice_size ')'
+value_array_slice:     primitive_value '(' lower_element ':' upper_element ')'
                        {
                          $$ = 0;       /* FIXME */
                        }
-               ;
-
-/* Z.200, 5.2.10 */
-
-value_structure_field: structure_primitive_value '.' field_name
+               |       primitive_value '(' first_element UP slice_size ')'
                        {
                          $$ = 0;       /* FIXME */
                        }
@@ -568,15 +569,17 @@ value_structure_field:    structure_primitive_value '.' field_name
 
 /* Z.200, 5.2.11 */
 
-expression_conversion: mode_name '(' expression ')'
+expression_conversion: mode_name parenthesised_expression
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (UNOP_CAST);
+                         write_exp_elt_type ($1.type);
+                         write_exp_elt_opcode (UNOP_CAST);
                        }
                ;
 
 /* Z.200, 5.2.12 */
 
-value_procedure_call:  FIXME
+value_procedure_call:  FIXME_05
                        {
                          $$ = 0;       /* FIXME */
                        }
@@ -592,7 +595,7 @@ value_built_in_routine_call:        chill_value_built_in_routine_call
 
 /* Z.200, 5.2.14 */
 
-start_expression:      FIXME
+start_expression:      FIXME_06
                        {
                          $$ = 0;       /* FIXME */
                        }       /* Not in GNU-Chill */
@@ -600,7 +603,7 @@ start_expression:   FIXME
 
 /* Z.200, 5.2.15 */
 
-zero_adic_operator:    FIXME
+zero_adic_operator:    FIXME_07
                        {
                          $$ = 0;       /* FIXME */
                        }
@@ -620,6 +623,10 @@ expression :       operand_0
                        {
                          $$ = 0;       /* FIXME */
                        }
+               |       single_assignment_action
+                       {
+                         $$ = 0;       /* FIXME */
+                       }
                |       conditional_expression
                        {
                          $$ = 0;       /* FIXME */
@@ -682,10 +689,6 @@ operand_0  :       operand_1
                        {
                          write_exp_elt_opcode (BINOP_BITWISE_XOR);
                        }
-               |       single_assignment_action
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
                ;
 
 /* Z.200, 5.3.4 */
@@ -736,7 +739,7 @@ operand_2   :       operand_3
                        }
                |       operand_2 IN operand_3
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (BINOP_IN);
                        }
                ;
 
@@ -757,7 +760,7 @@ operand_3   :       operand_4
                        }
                |       operand_3 SLASH_SLASH operand_4
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (BINOP_CONCAT);
                        }
                ;
 
@@ -799,17 +802,19 @@ operand_5 :       operand_6
                        {
                          write_exp_elt_opcode (UNOP_LOGICAL_NOT);
                        }
-               |       '(' integer_literal_expression ')' operand_6
+               |       parenthesised_expression literal
+/* We require the string operand to be a literal, to avoid some
+   nasty parsing ambiguities. */
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (BINOP_CONCAT);
                        }
                ;
 
 /* Z.200, 5.3.9 */
 
-operand_6      :       POINTER location
+operand_6      :       POINTER primitive_value
                        {
-                         $$ = 0;       /* FIXME */
+                         write_exp_elt_opcode (UNOP_ADDR);
                        }
                |       RECEIVE buffer_location
                        {
@@ -825,7 +830,7 @@ operand_6   :       POINTER location
 /* Z.200, 6.2 */
 
 single_assignment_action :
-                       location GDB_ASSIGNMENT value
+                       primitive_value GDB_ASSIGNMENT value
                        {
                          write_exp_elt_opcode (BINOP_ASSIGN);
                        }
@@ -854,22 +859,21 @@ chill_value_built_in_routine_call :
                        {
                          $$ = 0;       /* FIXME */
                        }
-               |       MAX '(' expression ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       MIN '(' expression ')'
+               |       MAX_TOKEN '(' expression ')'
                        {
                          $$ = 0;       /* FIXME */
                        }
-               |       SIZE '(' location ')'
+               |       MIN_TOKEN '(' expression ')'
                        {
                          $$ = 0;       /* FIXME */
                        }
+               |       SIZE '(' expression ')'
+                       { write_exp_elt_opcode (UNOP_SIZEOF); }
                |       SIZE '(' mode_argument ')'
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
+                       { write_exp_elt_opcode (OP_LONG);
+                         write_exp_elt_type (builtin_type_int);
+                         write_exp_elt_longcst ((LONGEST) TYPE_LENGTH ($3));
+                         write_exp_elt_opcode (OP_LONG); }
                |       UPPER '(' upper_lower_argument ')'
                        {
                          $$ = 0;       /* FIXME */
@@ -886,7 +890,7 @@ chill_value_built_in_routine_call :
 
 mode_argument :                mode_name
                        {
-                         $$ = 0;       /* FIXME */
+                         $$ = $1.type;
                        }
                |       array_mode_name '(' expression ')'
                        {
@@ -902,11 +906,10 @@ mode_argument :           mode_name
                        }
                ;
 
-upper_lower_argument : location
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       expression
+mode_name :            TYPENAME
+               ;
+
+upper_lower_argument : expression
                        {
                          $$ = 0;       /* FIXME */
                        }
@@ -916,62 +919,75 @@ upper_lower_argument :    location
                        }
                ;
 
-length_argument :      location
-                       {
-                         $$ = 0;       /* FIXME */
-                       }
-               |       expression
+length_argument :      expression
                        {
                          $$ = 0;       /* FIXME */
                        }
                ;
 
-/* Z.200, 12.4.3 */
-/* FIXME:  For now we just accept only a single integer literal. */
+/* Things which still need productions... */
 
-integer_literal_expression:
-                       INTEGER_LITERAL
-                       {
-                         $$ = 0;
-                       }
-               ;
+array_mode_name                :       FIXME_08 { $$ = 0; }
+string_mode_name       :       FIXME_09 { $$ = 0; }
+variant_structure_mode_name:   FIXME_10 { $$ = 0; }
+synonym_name           :       FIXME_11 { $$ = 0; }
+value_enumeration_name         :       FIXME_12 { $$ = 0; }
+value_do_with_name     :       FIXME_13 { $$ = 0; }
+value_receive_name     :       FIXME_14 { $$ = 0; }
+string_primitive_value         :       FIXME_15 { $$ = 0; }
+start_element          :       FIXME_16 { $$ = 0; }
+left_element           :       FIXME_17 { $$ = 0; }
+right_element          :       FIXME_18 { $$ = 0; }
+slice_size             :       FIXME_19 { $$ = 0; }
+lower_element          :       FIXME_20 { $$ = 0; }
+upper_element          :       FIXME_21 { $$ = 0; }
+first_element          :       FIXME_22 { $$ = 0; }
+boolean_expression     :       FIXME_26 { $$ = 0; }
+case_selector_list     :       FIXME_27 { $$ = 0; }
+subexpression          :       FIXME_28 { $$ = 0; }
+case_label_specification:      FIXME_29 { $$ = 0; }
+buffer_location        :       FIXME_30 { $$ = 0; }
 
-/* Z.200, 12.4.3 */
+%%
 
-array_primitive_value :        primitive_value
-                       {
-                         $$ = 0;
-                       }
-               ;
+/* Implementation of a dynamically expandable buffer for processing input
+   characters acquired through lexptr and building a value to return in
+   yylval. */
 
+static char *tempbuf;          /* Current buffer contents */
+static int tempbufsize;                /* Size of allocated buffer */
+static int tempbufindex;       /* Current index into buffer */
 
-/* Things which still need productions... */
+#define GROWBY_MIN_SIZE 64     /* Minimum amount to grow buffer by */
 
-array_mode_name                :       FIXME { $$ = 0; }
-string_mode_name       :       FIXME { $$ = 0; }
-variant_structure_mode_name:   FIXME { $$ = 0; }
-synonym_name           :       FIXME { $$ = 0; }
-value_enumeration_name         :       FIXME { $$ = 0; }
-value_do_with_name     :       FIXME { $$ = 0; }
-value_receive_name     :       FIXME { $$ = 0; }
-string_primitive_value         :       FIXME { $$ = 0; }
-start_element          :       FIXME { $$ = 0; }
-left_element           :       FIXME { $$ = 0; }
-right_element          :       FIXME { $$ = 0; }
-slice_size             :       FIXME { $$ = 0; }
-lower_element          :       FIXME { $$ = 0; }
-upper_element          :       FIXME { $$ = 0; }
-first_element          :       FIXME { $$ = 0; }
-structure_primitive_value:     FIXME { $$ = 0; }
-field_name             :       FIXME { $$ = 0; }
-mode_name              :       FIXME { $$ = 0; }
-boolean_expression     :       FIXME { $$ = 0; }
-case_selector_list     :       FIXME { $$ = 0; }
-subexpression          :       FIXME { $$ = 0; }
-case_label_specification:      FIXME { $$ = 0; }
-buffer_location        :       FIXME { $$ = 0; }
+#define CHECKBUF(size) \
+  do { \
+    if (tempbufindex + (size) >= tempbufsize) \
+      { \
+       growbuf_by_size (size); \
+      } \
+  } while (0);
 
-%%
+/* Grow the static temp buffer if necessary, including allocating the first one
+   on demand. */
+
+static void
+growbuf_by_size (count)
+     int count;
+{
+  int growby;
+
+  growby = max (count, GROWBY_MIN_SIZE);
+  tempbufsize += growby;
+  if (tempbuf == NULL)
+    {
+      tempbuf = (char *) malloc (tempbufsize);
+    }
+  else
+    {
+      tempbuf = (char *) realloc (tempbuf, tempbufsize);
+    }
+}
 
 /* Try to consume a simple name string token.  If successful, returns
    a pointer to a nullbyte terminated copy of the name that can be used
@@ -982,15 +998,17 @@ match_simple_name_string ()
 {
   char *tokptr = lexptr;
 
-  if (isalpha (*tokptr))
+  if (isalpha (*tokptr) || *tokptr == '_')
     {
+      char *result;
       do {
        tokptr++;
-      } while (isalpha (*tokptr) || isdigit (*tokptr) || (*tokptr == '_'));
+      } while (isalnum (*tokptr) || (*tokptr == '_'));
       yylval.sval.ptr = lexptr;
       yylval.sval.length = tokptr - lexptr;
       lexptr = tokptr;
-      return (copy_name (yylval.sval));
+      result = copy_name (yylval.sval);
+      return result;
     }
   return (NULL);
 }
@@ -1013,7 +1031,9 @@ decode_integer_value (base, tokptrptr, ivalptr)
 
   while (*tokptr != '\0')
     {
-      temp = tolower (*tokptr);
+      temp = *tokptr;
+      if (isupper (temp))
+        temp = tolower (temp);
       tokptr++;
       switch (temp)
        {
@@ -1151,7 +1171,6 @@ match_float_literal ()
   char *tokptr = lexptr;
   char *buf;
   char *copy;
-  char ch;
   double dval;
   extern double strtod ();
   
@@ -1270,6 +1289,48 @@ match_float_literal ()
   return (0);
 }
 
+/* Recognize a string literal.  A string literal is a sequence
+   of characters enclosed in matching single or double quotes, except that
+   a single character inside single quotes is a character literal, which
+   we reject as a string literal.  To embed the terminator character inside
+   a string, it is simply doubled (I.E. "this""is""one""string") */
+
+static int
+match_string_literal ()
+{
+  char *tokptr = lexptr;
+
+  for (tempbufindex = 0, tokptr++; *tokptr != '\0'; tokptr++)
+    {
+      CHECKBUF (1);
+      if (*tokptr == *lexptr)
+       {
+         if (*(tokptr + 1) == *lexptr)
+           {
+             tokptr++;
+           }
+         else
+           {
+             break;
+           }
+       }
+      tempbuf[tempbufindex++] = *tokptr;
+    }
+  if (*tokptr == '\0'                                  /* no terminator */
+      || (tempbufindex == 1 && *tokptr == '\''))       /* char literal */
+    {
+      return (0);
+    }
+  else
+    {
+      tempbuf[tempbufindex] = '\0';
+      yylval.sval.ptr = tempbuf;
+      yylval.sval.length = tempbufindex;
+      lexptr = ++tokptr;
+      return (CHARACTER_STRING_LITERAL);
+    }
+}
+
 /* Recognize a character literal.  A character literal is single character
    or a control sequence, enclosed in single quotes.  A control sequence
    is a comma separated list of one or more integer literals, enclosed
@@ -1280,6 +1341,15 @@ match_float_literal ()
    As a GNU chill extension, the syntax C'xx' is also recognized as a 
    character literal, where xx is a hex value for the character.
 
+   Note that more than a single character, enclosed in single quotes, is
+   a string literal.
+
+   Also note that the control sequence form is not in GNU Chill since it
+   is ambiguous with the string literal form using single quotes.  I.E.
+   is '^(7)' a character literal or a string literal.  In theory it it
+   possible to tell by context, but GNU Chill doesn't accept the control
+   sequence form, so neither do we (for now the code is disabled).
+
    Returns CHARACTER_LITERAL if a match is found.
    */
 
@@ -1289,7 +1359,7 @@ match_character_literal ()
   char *tokptr = lexptr;
   int ival = 0;
   
-  if ((tolower (*tokptr) == 'c') && (*(tokptr + 1) == '\''))
+  if ((*tokptr == 'c' || *tokptr == 'C') && (*(tokptr + 1) == '\''))
     {
       /* We have a GNU chill extension form, so skip the leading "C'",
         decode the hex value, and then ensure that we have a trailing
@@ -1310,6 +1380,7 @@ match_character_literal ()
       
       if ((*tokptr == '^') && (*(tokptr + 1) == '('))
        {
+#if 0     /* Disable, see note above. -fnf */
          /* Match and decode a control sequence.  Return zero if we don't
             find a valid integer literal, or if the next unconsumed character
             after the integer literal is not the trailing ')'.
@@ -1320,6 +1391,9 @@ match_character_literal ()
            {
              return (0);
            }
+#else
+         return (0);
+#endif
        }
       else
        {
@@ -1383,10 +1457,9 @@ match_bitstring_literal ()
   int bitcount = 0;
   int base;
   int digit;
-  static char *tempbuf;
-  static int tempbufsize;
-  static int tempbufindex;
   
+  tempbufindex = 0;
+
   /* Look for the required explicit base specifier. */
   
   switch (*tokptr++)
@@ -1417,7 +1490,9 @@ match_bitstring_literal ()
   
   while (*tokptr != '\0' && *tokptr != '\'')
     {
-      digit = tolower (*tokptr);
+      digit = *tokptr;
+      if (isupper (digit))
+        digit = tolower (digit);
       tokptr++;
       switch (digit)
        {
@@ -1448,20 +1523,7 @@ match_bitstring_literal ()
          for (mask = (base >> 1); mask > 0; mask >>= 1)
            {
              bitcount++;
-             /* Grow the static temp buffer if necessary, including allocating
-                the first one on demand. */
-             if (tempbufindex >= tempbufsize)
-               {
-                 tempbufsize += 64;
-                 if (tempbuf == NULL)
-                   {
-                     tempbuf = (char *) malloc (tempbufsize);
-                   }
-                 else
-                   {
-                     tempbuf = (char *) realloc (tempbuf, tempbufsize);
-                   }
-               }
+             CHECKBUF (1);
              if (digit & mask)
                {
                  tempbuf[tempbufindex] |= (1 << bitoffset);
@@ -1550,7 +1612,7 @@ match_dollar_tokens ()
              && !isalnum (tokptr[namelength]))
            {
              yylval.lval = regno;
-             lexptr += namelength + 1;
+             lexptr += namelength;
              return (GDB_REGNAME);
            }
        }
@@ -1623,49 +1685,38 @@ struct token
   int token;
 };
 
-static const struct token tokentab6[] =
-{
-    { "LENGTH", LENGTH }
-};
-
-static const struct token tokentab5[] =
+static const struct token idtokentab[] =
 {
-    { "LOWER", LOWER },
-    { "UPPER", UPPER },
-    { "ANDIF", ANDIF }
-};
-
-static const struct token tokentab4[] =
-{
-    { "PRED", PRED },
-    { "SUCC", SUCC },
-    { "CARD", CARD },
-    { "SIZE", SIZE },
-    { "ORIF", ORIF }
-};
-
-static const struct token tokentab3[] =
-{
-    { "NUM", NUM },
-    { "ABS", ABS },
-    { "MAX", MAX },
-    { "MIN", MIN },
-    { "MOD", MOD },
-    { "REM", REM },
-    { "NOT", NOT },
-    { "XOR", LOGXOR },
-    { "AND", LOGAND }
+    { "length", LENGTH },
+    { "lower", LOWER },
+    { "upper", UPPER },
+    { "andif", ANDIF },
+    { "pred", PRED },
+    { "succ", SUCC },
+    { "card", CARD },
+    { "size", SIZE },
+    { "orif", ORIF },
+    { "num", NUM },
+    { "abs", ABS },
+    { "max", MAX_TOKEN },
+    { "min", MIN_TOKEN },
+    { "mod", MOD },
+    { "rem", REM },
+    { "not", NOT },
+    { "xor", LOGXOR },
+    { "and", LOGAND },
+    { "in", IN },
+    { "or", LOGIOR }
 };
 
 static const struct token tokentab2[] =
 {
     { ":=", GDB_ASSIGNMENT },
     { "//", SLASH_SLASH },
+    { "->", POINTER },
     { "/=", NOTEQUAL },
     { "<=", LEQ },
-    { ">=", GTR },
-    { "IN", IN },
-    { "OR", LOGIOR }
+    { ">=", GTR }
 };
 
 /* Read one token, getting characters through lexptr.  */
@@ -1677,7 +1728,7 @@ yylex ()
 {
     unsigned int i;
     int token;
-    char *simplename;
+    char *inputname;
     struct symbol *sym;
 
     /* Skip over any leading whitespace. */
@@ -1696,9 +1747,7 @@ yylex ()
            case ';':
            case '!':
            case '+':
-           case '-':
            case '*':
-           case '/':
            case '(':
            case ')':
            case '[':
@@ -1707,12 +1756,31 @@ yylex ()
        }
     /* Look for characters which start a particular kind of multicharacter
        token, such as a character literal, register name, convenience
-       variable name, etc. */
+       variable name, string literal, etc. */
     switch (*lexptr)
       {
+       case '\'':
+       case '\"':
+         /* First try to match a string literal, which is any
+            sequence of characters enclosed in matching single or double
+            quotes, except that a single character inside single quotes
+            is a character literal, so we have to catch that case also. */
+         token = match_string_literal ();
+         if (token != 0)
+           {
+             return (token);
+           }
+         if (*lexptr == '\'')
+           {
+             token = match_character_literal ();
+             if (token != 0)
+               {
+                 return (token);
+               }
+           }
+         break;
         case 'C':
         case 'c':
-       case '\'':
          token = match_character_literal ();
          if (token != 0)
            {
@@ -1727,42 +1795,6 @@ yylex ()
            }
          break;
       }
-    /* See if it is a special token of length 6.  */
-    for (i = 0; i < sizeof (tokentab6) / sizeof (tokentab6[0]); i++)
-       {
-           if (STREQN (lexptr, tokentab6[i].operator, 6))
-               {
-                   lexptr += 6;
-                   return (tokentab6[i].token);
-               }
-       }
-    /* See if it is a special token of length 5.  */
-    for (i = 0; i < sizeof (tokentab5) / sizeof (tokentab5[0]); i++)
-       {
-           if (STREQN (lexptr, tokentab5[i].operator, 5))
-               {
-                   lexptr += 5;
-                   return (tokentab5[i].token);
-               }
-       }
-    /* See if it is a special token of length 4.  */
-    for (i = 0; i < sizeof (tokentab4) / sizeof (tokentab4[0]); i++)
-       {
-           if (STREQN (lexptr, tokentab4[i].operator, 4))
-               {
-                   lexptr += 4;
-                   return (tokentab4[i].token);
-               }
-       }
-    /* See if it is a special token of length 3.  */
-    for (i = 0; i < sizeof (tokentab3) / sizeof (tokentab3[0]); i++)
-       {
-           if (STREQN (lexptr, tokentab3[i].operator, 3))
-               {
-                   lexptr += 3;
-                   return (tokentab3[i].token);
-               }
-       }
     /* See if it is a special token of length 2.  */
     for (i = 0; i < sizeof (tokentab2) / sizeof (tokentab2[0]); i++)
        {
@@ -1777,25 +1809,13 @@ yylex ()
        would already have found it. */
     switch (*lexptr)
        {
+           case '-':
            case ':':
            case '/':
            case '<':
            case '>':
                return (*lexptr++);
        }
-    /* Look for other special tokens. */
-    if (STREQN (lexptr, "TRUE", 4)) /* FIXME:  What about lowercase? */
-       {
-           yylval.ulval = 1;
-           lexptr += 4;
-           return (BOOLEAN_LITERAL);
-       }
-    if (STREQN (lexptr, "FALSE", 5)) /* FIXME:  What about lowercase? */
-       {
-           yylval.ulval = 0;
-           lexptr += 5;
-           return (BOOLEAN_LITERAL);
-       }
     /* Look for a float literal before looking for an integer literal, so
        we match as much of the input stream as possible. */
     token = match_float_literal ();
@@ -1820,12 +1840,46 @@ yylex ()
        the token from lexptr, so we can't back out if we later find that
        we can't classify what sort of name it is. */
 
-    simplename = match_simple_name_string ();
-    if (simplename != NULL)
+    inputname = match_simple_name_string ();
+
+    if (inputname != NULL)
       {
-       sym = lookup_symbol (simplename, expression_context_block,
+       char *simplename = (char*) alloca (strlen (inputname));
+
+       char *dptr = simplename, *sptr = inputname;
+       for (; *sptr; sptr++)
+         *dptr++ = isupper (*sptr) ? tolower(*sptr) : *sptr;
+
+       /* See if it is a reserved identifier. */
+       for (i = 0; i < sizeof (idtokentab) / sizeof (idtokentab[0]); i++)
+           {
+               if (STREQ (simplename, idtokentab[i].operator))
+                   {
+                       return (idtokentab[i].token);
+                   }
+           }
+
+       /* Look for other special tokens. */
+       if (STREQ (simplename, "true"))
+           {
+               yylval.ulval = 1;
+               return (BOOLEAN_LITERAL);
+           }
+       if (STREQ (simplename, "false"))
+           {
+               yylval.ulval = 0;
+               return (BOOLEAN_LITERAL);
+           }
+
+       sym = lookup_symbol (inputname, expression_context_block,
                             VAR_NAMESPACE, (int *) NULL,
                             (struct symtab **) NULL);
+       if (sym == NULL && strcmp (inputname, simplename) != 0)
+         {
+           sym = lookup_symbol (simplename, expression_context_block,
+                                VAR_NAMESPACE, (int *) NULL,
+                                (struct symtab **) NULL);
+         }
        if (sym != NULL)
          {
            yylval.ssym.stoken.ptr = NULL;
@@ -1844,8 +1898,11 @@ yylex ()
              case LOC_ARG:
              case LOC_REF_ARG:
              case LOC_REGPARM:
+             case LOC_REGPARM_ADDR:
              case LOC_LOCAL:
              case LOC_LOCAL_ARG:
+             case LOC_BASEREG:
+             case LOC_BASEREG_ARG:
                if (innermost_block == NULL
                    || contained_in (block_found, innermost_block))
                  {
@@ -1857,10 +1914,13 @@ yylex ()
              case LOC_LABEL:
                return (LOCATION_NAME);
                break;
-             case LOC_UNDEF:
              case LOC_TYPEDEF:
+               yylval.tsym.type = SYMBOL_TYPE (sym);
+               return TYPENAME;
+             case LOC_UNDEF:
              case LOC_CONST_BYTES:
-               error ("Symbol \"%s\" names no location.", simplename);
+             case LOC_OPTIMIZED_OUT:
+               error ("Symbol \"%s\" names no location.", inputname);
                break;
              }
          }
@@ -1870,7 +1930,7 @@ yylex ()
          }
        else
          {
-           error ("No symbol \"%s\" in current context.", simplename);
+           error ("No symbol \"%s\" in current context.", inputname);
          }
       }
 
@@ -1880,7 +1940,12 @@ yylex ()
     switch (*lexptr)
       {
        case '.':                       /* Not float for example. */
-         return (*lexptr++);
+         lexptr++;
+         while (isspace (*lexptr)) lexptr++;
+         inputname = match_simple_name_string ();
+         if (!inputname)
+           return '.';
+         return FIELD_NAME;
       }
 
     return (ILLEGAL_TOKEN);
@@ -1888,15 +1953,7 @@ yylex ()
 
 void
 yyerror (msg)
-     char *msg;        /* unused */
+     char *msg;
 {
-  printf ("Parsing:  %s\n", lexptr);
-  if (yychar < 256)
-    {
-      error ("Invalid syntax in expression near character '%c'.", yychar);
-    }
-  else
-    {
-      error ("Invalid syntax in expression");
-    }
+  error ("A %s in expression, near `%s'.", (msg ? msg : "error"), lexptr);
 }
This page took 0.036815 seconds and 4 git commands to generate.