gdb/d-exp.y - gdb
- %{
- #include "defs.h"
- #include <ctype.h>
- #include "expression.h"
- #include "value.h"
- #include "parser-defs.h"
- #include "language.h"
- #include "c-lang.h"
- #include "d-lang.h"
- #include "bfd.h"
- #include "symfile.h"
- #include "objfiles.h"
- #include "charset.h"
- #include "block.h"
- #define parse_type(ps) builtin_type (parse_gdbarch (ps))
- #define parse_d_type(ps) builtin_d_type (parse_gdbarch (ps))
- #define yymaxdepth d_maxdepth
- #define yyparse d_parse_internal
- #define yylex d_lex
- #define yyerror d_error
- #define yylval d_lval
- #define yychar d_char
- #define yydebug d_debug
- #define yypact d_pact
- #define yyr1 d_r1
- #define yyr2 d_r2
- #define yydef d_def
- #define yychk d_chk
- #define yypgo d_pgo
- #define yyact d_act
- #define yyexca d_exca
- #define yyerrflag d_errflag
- #define yynerrs d_nerrs
- #define yyps d_ps
- #define yypv d_pv
- #define yys d_s
- #define yy_yys d_yys
- #define yystate d_state
- #define yytmp d_tmp
- #define yyv d_v
- #define yy_yyv d_yyv
- #define yyval d_val
- #define yylloc d_lloc
- #define yyreds d_reds
- #define yytoks d_toks
- #define yyname d_name
- #define yyrule d_rule
- #define yylhs d_yylhs
- #define yylen d_yylen
- #define yydefre d_yydefred
- #define yydgoto d_yydgoto
- #define yysindex d_yysindex
- #define yyrindex d_yyrindex
- #define yygindex d_yygindex
- #define yytable d_yytable
- #define yycheck d_yycheck
- #define yyss d_yyss
- #define yysslim d_yysslim
- #define yyssp d_yyssp
- #define yystacksize d_yystacksize
- #define yyvs d_yyvs
- #define yyvsp d_yyvsp
- #ifndef YYDEBUG
- #define YYDEBUG 1
- #endif
- #define YYFPRINTF parser_fprintf
- staticstructNULL
- intvoid
- staticintvoid
- voidchar
- %}
- %union
- {
- struct {
- LONGEST val;
- struct type *type;
- } typed_val_int;
- struct {
- DOUBLEST dval;
- struct type *type;
- } typed_val_float;
- struct symbol *sym;
- struct type *tval;
- struct typed_stoken tsval;
- struct stoken sval;
- struct ttype tsym;
- struct symtoken ssym;
- int ival;
- struct block *bval;
- enum exp_opcode opcode;
- struct stoken_vector svec;
- }
- %{
- staticintstructconstchar
- intint
- staticvoidstructstruct
- %}
- %token <sval> IDENTIFIER
- %token <tsym> TYPENAME
- %token <voidval> COMPLETE
- %token <sval> NAME_OR_INT
- %token <typed_val_int> INTEGER_LITERAL
- %token <typed_val_float> FLOAT_LITERAL
- %token <tsval> CHARACTER_LITERAL
- %token <tsval> STRING_LITERAL
- %type <svec> StringExp
- %type <tval> BasicType TypeExp
- %type <sval> IdentifierExp
- %type <ival> ArrayLiteral
- %token ENTRY
- %token ERROR
- %token TRUE_KEYWORD FALSE_KEYWORD NULL_KEYWORD
- %token SUPER_KEYWORD
- %token CAST_KEYWORD SIZEOF_KEYWORD
- %token TYPEOF_KEYWORD TYPEID_KEYWORD
- %token INIT_KEYWORD
- %token IMMUTABLE_KEYWORD CONST_KEYWORD SHARED_KEYWORD
- %token STRUCT_KEYWORD UNION_KEYWORD
- %token CLASS_KEYWORD INTERFACE_KEYWORD
- %token ENUM_KEYWORD TEMPLATE_KEYWORD
- %token DELEGATE_KEYWORD FUNCTION_KEYWORD
- %token <sval> DOLLAR_VARIABLE
- %token <opcode> ASSIGN_MODIFY
- %left ','
- %right '=' ASSIGN_MODIFY
- %right '?'
- %left OROR
- %left ANDAND
- %left '|'
- %left '^'
- %left '&'
- %left EQUAL NOTEQUAL '<' '>' LEQ GEQ
- %right LSH RSH
- %left '+' '-'
- %left '*' '/' '%'
- %right HATHAT
- %left IDENTITY NOTIDENTITY
- %right INCREMENT DECREMENT
- %right '.' '[' '('
- %token DOTDOT
- %%
- start :
- Expression
- | TypeExp
- ;
- /* Expressions, including the comma operator. */
- Expression:
- CommaExpression
- ;
- CommaExpression:
- AssignExpression
- | AssignExpression ',' CommaExpression
- { write_exp_elt_opcode (pstate, BINOP_COMMA); }
- ;
- AssignExpression:
- ConditionalExpression
- | ConditionalExpression '=' AssignExpression
- { write_exp_elt_opcode (pstate, BINOP_ASSIGN); }
- | ConditionalExpression ASSIGN_MODIFY AssignExpression
- { write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY);
- write_exp_elt_opcode (pstate, $2);
- write_exp_elt_opcode (pstate, BINOP_ASSIGN_MODIFY); }
- ;
- ConditionalExpression:
- OrOrExpression
- | OrOrExpression '?' Expression ':' ConditionalExpression
- { write_exp_elt_opcode (pstate, TERNOP_COND); }
- ;
- OrOrExpression:
- AndAndExpression
- | OrOrExpression OROR AndAndExpression
- { write_exp_elt_opcode (pstate, BINOP_LOGICAL_OR); }
- ;
- AndAndExpression:
- OrExpression
- | AndAndExpression ANDAND OrExpression
- { write_exp_elt_opcode (pstate, BINOP_LOGICAL_AND); }
- ;
- OrExpression:
- XorExpression
- | OrExpression '|' XorExpression
- { write_exp_elt_opcode (pstate, BINOP_BITWISE_IOR); }
- ;
- XorExpression:
- AndExpression
- | XorExpression '^' AndExpression
- { write_exp_elt_opcode (pstate, BINOP_BITWISE_XOR); }
- ;
- AndExpression:
- CmpExpression
- | AndExpression '&' CmpExpression
- { write_exp_elt_opcode (pstate, BINOP_BITWISE_AND); }
- ;
- CmpExpression:
- ShiftExpression
- | EqualExpression
- | IdentityExpression
- | RelExpression
- ;
- EqualExpression:
- ShiftExpression EQUAL ShiftExpression
- { write_exp_elt_opcode (pstate, BINOP_EQUAL); }
- | ShiftExpression NOTEQUAL ShiftExpression
- { write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); }
- ;
- IdentityExpression:
- ShiftExpression IDENTITY ShiftExpression
- { write_exp_elt_opcode (pstate, BINOP_EQUAL); }
- | ShiftExpression NOTIDENTITY ShiftExpression
- { write_exp_elt_opcode (pstate, BINOP_NOTEQUAL); }
- ;
- RelExpression:
- ShiftExpression '<' ShiftExpression
- { write_exp_elt_opcode (pstate, BINOP_LESS); }
- | ShiftExpression LEQ ShiftExpression
- { write_exp_elt_opcode (pstate, BINOP_LEQ); }
- | ShiftExpression '>' ShiftExpression
- { write_exp_elt_opcode (pstate, BINOP_GTR); }
- | ShiftExpression GEQ ShiftExpression
- { write_exp_elt_opcode (pstate, BINOP_GEQ); }
- ;
- ShiftExpression:
- AddExpression
- | ShiftExpression LSH AddExpression
- { write_exp_elt_opcode (pstate, BINOP_LSH); }
- | ShiftExpression RSH AddExpression
- { write_exp_elt_opcode (pstate, BINOP_RSH); }
- ;
- AddExpression:
- MulExpression
- | AddExpression '+' MulExpression
- { write_exp_elt_opcode (pstate, BINOP_ADD); }
- | AddExpression '-' MulExpression
- { write_exp_elt_opcode (pstate, BINOP_SUB); }
- | AddExpression '~' MulExpression
- { write_exp_elt_opcode (pstate, BINOP_CONCAT); }
- ;
- MulExpression:
- UnaryExpression
- | MulExpression '*' UnaryExpression
- { write_exp_elt_opcode (pstate, BINOP_MUL); }
- | MulExpression '/' UnaryExpression
- { write_exp_elt_opcode (pstate, BINOP_DIV); }
- | MulExpression '%' UnaryExpression
- { write_exp_elt_opcode (pstate, BINOP_REM); }
- UnaryExpression:
- '&' UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_ADDR); }
- | INCREMENT UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_PREINCREMENT); }
- | DECREMENT UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_PREDECREMENT); }
- | '*' UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_IND); }
- | '-' UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_NEG); }
- | '+' UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_PLUS); }
- | '!' UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_LOGICAL_NOT); }
- | '~' UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_COMPLEMENT); }
- | CastExpression
- | PowExpression
- ;
- CastExpression:
- CAST_KEYWORD '(' TypeExp ')' UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_CAST);
- write_exp_elt_type (pstate, $3);
- write_exp_elt_opcode (pstate, UNOP_CAST); }
-
- | '(' TypeExp ')' UnaryExpression
- { write_exp_elt_opcode (pstate, UNOP_CAST);
- write_exp_elt_type (pstate, $2);
- write_exp_elt_opcode (pstate, UNOP_CAST); }
- ;
- PowExpression:
- PostfixExpression
- | PostfixExpression HATHAT UnaryExpression
- { write_exp_elt_opcode (pstate, BINOP_EXP); }
- ;
- PostfixExpression:
- PrimaryExpression
- | PostfixExpression INCREMENT
- { write_exp_elt_opcode (pstate, UNOP_POSTINCREMENT); }
- | PostfixExpression DECREMENT
- { write_exp_elt_opcode (pstate, UNOP_POSTDECREMENT); }
- | CallExpression
- | IndexExpression
- | SliceExpression
- ;
- ArgumentList:
- AssignExpression
- { arglist_len = 1; }
- | ArgumentList ',' AssignExpression
- { arglist_len++; }
- ;
- ArgumentList_opt:
-
- { arglist_len = 0; }
- | ArgumentList
- ;
- CallExpression:
- PostfixExpression '('
- { start_arglist (); }
- ArgumentList_opt ')'
- { write_exp_elt_opcode (pstate, OP_FUNCALL);
- write_exp_elt_longcst (pstate, (LONGEST) end_arglist ());
- write_exp_elt_opcode (pstate, OP_FUNCALL); }
- ;
- IndexExpression:
- PostfixExpression '[' ArgumentList ']'
- { if (arglist_len > 0)
- {
- write_exp_elt_opcode (pstate, MULTI_SUBSCRIPT);
- write_exp_elt_longcst (pstate, (LONGEST) arglist_len);
- write_exp_elt_opcode (pstate, MULTI_SUBSCRIPT);
- }
- else
- write_exp_elt_opcode (pstate, BINOP_SUBSCRIPT);
- }
- ;
- SliceExpression:
- PostfixExpression '[' ']'
- { }
- | PostfixExpression '[' AssignExpression DOTDOT AssignExpression ']'
- { write_exp_elt_opcode (pstate, TERNOP_SLICE); }
- ;
- PrimaryExpression:
- '(' Expression ')'
- { }
- | IdentifierExp
- { push_expression_name (pstate, $1); }
- | IdentifierExp '.' COMPLETE
- { struct stoken s;
- s.ptr = "";
- s.length = 0;
- push_expression_name (pstate, $1);
- mark_struct_expression (pstate);
- write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
- write_exp_string (pstate, s);
- write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
- | IdentifierExp '.' IDENTIFIER COMPLETE
- { push_expression_name (pstate, $1);
- mark_struct_expression (pstate);
- write_exp_elt_opcode (pstate, STRUCTOP_STRUCT);
- write_exp_string (pstate, $3);
- write_exp_elt_opcode (pstate, STRUCTOP_STRUCT); }
- | DOLLAR_VARIABLE
- { write_dollar_variable (pstate, $1); }
- | NAME_OR_INT
- { YYSTYPE val;
- parse_number (pstate, $1.ptr, $1.length, 0, &val);
- write_exp_elt_opcode (pstate, OP_LONG);
- write_exp_elt_type (pstate, val.typed_val_int.type);
- write_exp_elt_longcst (pstate,
- (LONGEST) val.typed_val_int.val);
- write_exp_elt_opcode (pstate, OP_LONG); }
- | NULL_KEYWORD
- { struct type *type = parse_d_type (pstate)->builtin_void;
- type = lookup_pointer_type (type);
- write_exp_elt_opcode (pstate, OP_LONG);
- write_exp_elt_type (pstate, type);
- write_exp_elt_longcst (pstate, (LONGEST) 0);
- write_exp_elt_opcode (pstate, OP_LONG); }
- | TRUE_KEYWORD
- { write_exp_elt_opcode (pstate, OP_BOOL);
- write_exp_elt_longcst (pstate, (LONGEST) 1);
- write_exp_elt_opcode (pstate, OP_BOOL); }
- | FALSE_KEYWORD
- { write_exp_elt_opcode (pstate, OP_BOOL);
- write_exp_elt_longcst (pstate, (LONGEST) 0);
- write_exp_elt_opcode (pstate, OP_BOOL); }
- | INTEGER_LITERAL
- { write_exp_elt_opcode (pstate, OP_LONG);
- write_exp_elt_type (pstate, $1.type);
- write_exp_elt_longcst (pstate, (LONGEST)($1.val));
- write_exp_elt_opcode (pstate, OP_LONG); }
- | FLOAT_LITERAL
- { write_exp_elt_opcode (pstate, OP_DOUBLE);
- write_exp_elt_type (pstate, $1.type);
- write_exp_elt_dblcst (pstate, $1.dval);
- write_exp_elt_opcode (pstate, OP_DOUBLE); }
- | CHARACTER_LITERAL
- { struct stoken_vector vec;
- vec.len = 1;
- vec.tokens = &$1;
- write_exp_string_vector (pstate, $1.type, &vec); }
- | StringExp
- { int i;
- write_exp_string_vector (pstate, 0, &$1);
- for (i = 0; i < $1.len; ++i)
- free ($1.tokens[i].ptr);
- free ($1.tokens); }
- | ArrayLiteral
- { write_exp_elt_opcode (pstate, OP_ARRAY);
- write_exp_elt_longcst (pstate, (LONGEST) 0);
- write_exp_elt_longcst (pstate, (LONGEST) $1 - 1);
- write_exp_elt_opcode (pstate, OP_ARRAY); }
- ;
- ArrayLiteral:
- '[' ArgumentList_opt ']'
- { $$ = arglist_len; }
- ;
- IdentifierExp:
- IDENTIFIER
- | IdentifierExp '.' IDENTIFIER
- { $$.length = $1.length + $3.length + 1;
- if ($1.ptr + $1.length + 1 == $3.ptr
- && $1.ptr[$1.length] == '.')
- $$.ptr = $1.ptr;
- else
- {
- char *buf = malloc ($$.length + 1);
- make_cleanup (free, buf);
- sprintf (buf, "%.*s.%.*s",
- $1.length, $1.ptr, $3.length, $3.ptr);
- $$.ptr = buf;
- }
- }
- ;
- StringExp:
- STRING_LITERAL
- {
- struct typed_stoken *vec = XNEW (struct typed_stoken);
- $$.len = 1;
- $$.tokens = vec;
- vec->type = $1.type;
- vec->length = $1.length;
- vec->ptr = malloc ($1.length + 1);
- memcpy (vec->ptr, $1.ptr, $1.length + 1);
- }
- | StringExp STRING_LITERAL
- {
- char *p;
- ++$$.len;
- $$.tokens = realloc ($$.tokens,
- $$.len * sizeof (struct typed_stoken));
- p = malloc ($2.length + 1);
- memcpy (p, $2.ptr, $2.length + 1);
- $$.tokens[$$.len - 1].type = $2.type;
- $$.tokens[$$.len - 1].length = $2.length;
- $$.tokens[$$.len - 1].ptr = p;
- }
- ;
- TypeExp:
- BasicType
- { write_exp_elt_opcode (pstate, OP_TYPE);
- write_exp_elt_type (pstate, $1);
- write_exp_elt_opcode (pstate, OP_TYPE); }
- | BasicType BasicType2
- { $$ = follow_types ($1);
- write_exp_elt_opcode (pstate, OP_TYPE);
- write_exp_elt_type (pstate, $$);
- write_exp_elt_opcode (pstate, OP_TYPE);
- }
- ;
- BasicType2:
- '*'
- { push_type (tp_pointer); }
- | '*' BasicType2
- { push_type (tp_pointer); }
- | '[' INTEGER_LITERAL ']'
- { push_type_int ($2.val);
- push_type (tp_array); }
- | '[' INTEGER_LITERAL ']' BasicType2
- { push_type_int ($2.val);
- push_type (tp_array); }
- ;
- BasicType:
- TYPENAME
- { $$ = $1.type; }
- | CLASS_KEYWORD IdentifierExp
- { $$ = lookup_struct (copy_name ($2),
- expression_context_block); }
- | CLASS_KEYWORD COMPLETE
- { mark_completion_tag (TYPE_CODE_STRUCT, "", 0);
- $$ = NULL; }
- | CLASS_KEYWORD IdentifierExp COMPLETE
- { mark_completion_tag (TYPE_CODE_STRUCT, $2.ptr, $2.length);
- $$ = NULL; }
- | STRUCT_KEYWORD IdentifierExp
- { $$ = lookup_struct (copy_name ($2),
- expression_context_block); }
- | STRUCT_KEYWORD COMPLETE
- { mark_completion_tag (TYPE_CODE_STRUCT, "", 0);
- $$ = NULL; }
- | STRUCT_KEYWORD IdentifierExp COMPLETE
- { mark_completion_tag (TYPE_CODE_STRUCT, $2.ptr, $2.length);
- $$ = NULL; }
- | UNION_KEYWORD IdentifierExp
- { $$ = lookup_union (copy_name ($2),
- expression_context_block); }
- | UNION_KEYWORD COMPLETE
- { mark_completion_tag (TYPE_CODE_UNION, "", 0);
- $$ = NULL; }
- | UNION_KEYWORD IdentifierExp COMPLETE
- { mark_completion_tag (TYPE_CODE_UNION, $2.ptr, $2.length);
- $$ = NULL; }
- | ENUM_KEYWORD IdentifierExp
- { $$ = lookup_enum (copy_name ($2),
- expression_context_block); }
- | ENUM_KEYWORD COMPLETE
- { mark_completion_tag (TYPE_CODE_ENUM, "", 0);
- $$ = NULL; }
- | ENUM_KEYWORD IdentifierExp COMPLETE
- { mark_completion_tag (TYPE_CODE_ENUM, $2.ptr, $2.length);
- $$ = NULL; }
- ;
- %%
- static int
- parse_number (struct parser_state *ps, const char *p,
- int len, int parsed_float, YYSTYPE *putithere)
- {
- ULONGEST n = 0;
- ULONGEST prevn = 0;
- ULONGEST un;
- int i = 0;
- int c;
- int base = input_radix;
- int unsigned_p = 0;
- int long_p = 0;
-
- int found_suffix = 0;
- ULONGEST high_bit;
- struct type *signed_type;
- struct type *unsigned_type;
- if (parsed_float)
- {
- const struct builtin_d_type *builtin_d_types;
- const char *suffix;
- int suffix_len;
- char *s, *sp;
-
- s = (char *) alloca (len + 1);
- sp = s;
- while (len-- > 0)
- {
- if (*p != '_')
- *sp++ = *p;
- p++;
- }
- *sp = '\0';
- len = strlen (s);
- if (! parse_float (s, len, &putithere->typed_val_float.dval, &suffix))
- return ERROR;
- suffix_len = s + len - suffix;
- if (suffix_len == 0)
- {
- putithere->typed_val_float.type
- = parse_d_type (ps)->builtin_double;
- }
- else if (suffix_len == 1)
- {
-
- if (tolower (*suffix) == 'f')
- {
- putithere->typed_val_float.type
- = parse_d_type (ps)->builtin_float;
- }
- else if (tolower (*suffix) == 'l')
- {
- putithere->typed_val_float.type
- = parse_d_type (ps)->builtin_real;
- }
- else if (tolower (*suffix) == 'i')
- {
- putithere->typed_val_float.type
- = parse_d_type (ps)->builtin_idouble;
- }
- else
- return ERROR;
- }
- else if (suffix_len == 2)
- {
-
- if (tolower (suffix[0]) == 'f' && tolower (suffix[1] == 'i'))
- {
- putithere->typed_val_float.type
- = parse_d_type (ps)->builtin_ifloat;
- }
- else if (tolower (suffix[0]) == 'l' && tolower (suffix[1] == 'i'))
- {
- putithere->typed_val_float.type
- = parse_d_type (ps)->builtin_ireal;
- }
- else
- return ERROR;
- }
- else
- return ERROR;
- return FLOAT_LITERAL;
- }
-
- if (p[0] == '0')
- switch (p[1])
- {
- case 'x':
- case 'X':
- if (len >= 3)
- {
- p += 2;
- base = 16;
- len -= 2;
- }
- break;
- case 'b':
- case 'B':
- if (len >= 3)
- {
- p += 2;
- base = 2;
- len -= 2;
- }
- break;
- default:
- base = 8;
- break;
- }
- while (len-- > 0)
- {
- c = *p++;
- if (c == '_')
- continue;
- if (c >= 'A' && c <= 'Z')
- c += 'a' - 'A';
- if (c != 'l' && c != 'u')
- n *= base;
- if (c >= '0' && c <= '9')
- {
- if (found_suffix)
- return ERROR;
- n += i = c - '0';
- }
- else
- {
- if (base > 10 && c >= 'a' && c <= 'f')
- {
- if (found_suffix)
- return ERROR;
- n += i = c - 'a' + 10;
- }
- else if (c == 'l' && long_p == 0)
- {
- long_p = 1;
- found_suffix = 1;
- }
- else if (c == 'u' && unsigned_p == 0)
- {
- unsigned_p = 1;
- found_suffix = 1;
- }
- else
- return ERROR;
- }
- if (i >= base)
- return ERROR;
-
- if (c != 'l' && c != 'u')
- {
- ULONGEST n2 = prevn * base;
- if ((n2 / base != prevn) || (n2 + i < prevn))
- error (_("Numeric constant too large."));
- }
- prevn = n;
- }
-
- un = (ULONGEST) n >> 2;
- if (long_p == 0 && (un >> 30) == 0)
- {
- high_bit = ((ULONGEST) 1) << 31;
- signed_type = parse_d_type (ps)->builtin_int;
-
- if (base == 10 && !unsigned_p)
- unsigned_type = parse_d_type (ps)->builtin_long;
- else
- unsigned_type = parse_d_type (ps)->builtin_uint;
- }
- else
- {
- int shift;
- if (sizeof (ULONGEST) * HOST_CHAR_BIT < 64)
-
- shift = (sizeof (ULONGEST) * HOST_CHAR_BIT - 1);
- else
- shift = 63;
- high_bit = (ULONGEST) 1 << shift;
- signed_type = parse_d_type (ps)->builtin_long;
- unsigned_type = parse_d_type (ps)->builtin_ulong;
- }
- putithere->typed_val_int.val = n;
-
- if (unsigned_p || (n & high_bit))
- putithere->typed_val_int.type = unsigned_type;
- else
- putithere->typed_val_int.type = signed_type;
- return INTEGER_LITERAL;
- }
- static struct obstack tempbuf;
- static int tempbuf_init;
- static int
- parse_string_or_char (const char *tokptr, const char **outptr,
- struct typed_stoken *value, int *host_chars)
- {
- int quote;
-
- if (!tempbuf_init)
- tempbuf_init = 1;
- else
- obstack_free (&tempbuf, NULL);
- obstack_init (&tempbuf);
-
- quote = *tokptr;
- ++tokptr;
- *host_chars = 0;
- while (*tokptr)
- {
- char c = *tokptr;
- if (c == '\\')
- {
- ++tokptr;
- *host_chars += c_parse_escape (&tokptr, &tempbuf);
- }
- else if (c == quote)
- break;
- else
- {
- obstack_1grow (&tempbuf, c);
- ++tokptr;
- FIXME
- ++*host_chars;
- }
- }
- if (*tokptr != quote)
- {
- if (quote == '"' || quote == '`')
- error (_("Unterminated string in expression."));
- else
- error (_("Unmatched single quote."));
- }
- ++tokptr;
- FIXME
- if (quote == '\'')
- value->type = C_CHAR;
- else
- value->type = C_STRING;
- value->ptr = obstack_base (&tempbuf);
- value->length = obstack_object_size (&tempbuf);
- *outptr = tokptr;
- return quote == '\'' ? CHARACTER_LITERAL : STRING_LITERAL;
- }
- struct token
- {
- char *operator;
- int token;
- enum exp_opcode opcode;
- };
- static const struct token tokentab3[] =
- {
- {"^^=", ASSIGN_MODIFY, BINOP_EXP},
- {"<<=", ASSIGN_MODIFY, BINOP_LSH},
- {">>=", ASSIGN_MODIFY, BINOP_RSH},
- };
- static const struct token tokentab2[] =
- {
- {"+=", ASSIGN_MODIFY, BINOP_ADD},
- {"-=", ASSIGN_MODIFY, BINOP_SUB},
- {"*=", ASSIGN_MODIFY, BINOP_MUL},
- {"/=", ASSIGN_MODIFY, BINOP_DIV},
- {"%=", ASSIGN_MODIFY, BINOP_REM},
- {"|=", ASSIGN_MODIFY, BINOP_BITWISE_IOR},
- {"&=", ASSIGN_MODIFY, BINOP_BITWISE_AND},
- {"^=", ASSIGN_MODIFY, BINOP_BITWISE_XOR},
- {"++", INCREMENT, BINOP_END},
- {"--", DECREMENT, BINOP_END},
- {"&&", ANDAND, BINOP_END},
- {"||", OROR, BINOP_END},
- {"^^", HATHAT, BINOP_END},
- {"<<", LSH, BINOP_END},
- {">>", RSH, BINOP_END},
- {"==", EQUAL, BINOP_END},
- {"!=", NOTEQUAL, BINOP_END},
- {"<=", LEQ, BINOP_END},
- {">=", GEQ, BINOP_END},
- {"..", DOTDOT, BINOP_END},
- };
- static const struct token ident_tokens[] =
- {
- {"is", IDENTITY, BINOP_END},
- {"!is", NOTIDENTITY, BINOP_END},
- {"cast", CAST_KEYWORD, OP_NULL},
- {"const", CONST_KEYWORD, OP_NULL},
- {"immutable", IMMUTABLE_KEYWORD, OP_NULL},
- {"shared", SHARED_KEYWORD, OP_NULL},
- {"super", SUPER_KEYWORD, OP_NULL},
- {"null", NULL_KEYWORD, OP_NULL},
- {"true", TRUE_KEYWORD, OP_NULL},
- {"false", FALSE_KEYWORD, OP_NULL},
- {"init", INIT_KEYWORD, OP_NULL},
- {"sizeof", SIZEOF_KEYWORD, OP_NULL},
- {"typeof", TYPEOF_KEYWORD, OP_NULL},
- {"typeid", TYPEID_KEYWORD, OP_NULL},
- {"delegate", DELEGATE_KEYWORD, OP_NULL},
- {"function", FUNCTION_KEYWORD, OP_NULL},
- {"struct", STRUCT_KEYWORD, OP_NULL},
- {"union", UNION_KEYWORD, OP_NULL},
- {"class", CLASS_KEYWORD, OP_NULL},
- {"interface", INTERFACE_KEYWORD, OP_NULL},
- {"enum", ENUM_KEYWORD, OP_NULL},
- {"template", TEMPLATE_KEYWORD, OP_NULL},
- };
- static struct type *
- d_type_from_name (struct stoken name)
- {
- struct symbol *sym;
- char *copy = copy_name (name);
- sym = lookup_symbol (copy, expression_context_block,
- STRUCT_DOMAIN, NULL);
- if (sym != NULL)
- return SYMBOL_TYPE (sym);
- return NULL;
- }
- static struct type *
- d_module_from_name (struct stoken name)
- {
- struct symbol *sym;
- char *copy = copy_name (name);
- sym = lookup_symbol (copy, expression_context_block,
- MODULE_DOMAIN, NULL);
- if (sym != NULL)
- return SYMBOL_TYPE (sym);
- return NULL;
- }
- static int
- push_variable (struct parser_state *ps, struct stoken name)
- {
- char *copy = copy_name (name);
- struct field_of_this_result is_a_field_of_this;
- struct symbol *sym;
- sym = lookup_symbol (copy, expression_context_block, VAR_DOMAIN,
- &is_a_field_of_this);
- if (sym && SYMBOL_CLASS (sym) != LOC_TYPEDEF)
- {
- if (symbol_read_needs_frame (sym))
- {
- if (innermost_block == 0 ||
- contained_in (block_found, innermost_block))
- innermost_block = block_found;
- }
- write_exp_elt_opcode (ps, OP_VAR_VALUE);
-
- write_exp_elt_block (ps, NULL);
- write_exp_elt_sym (ps, sym);
- write_exp_elt_opcode (ps, OP_VAR_VALUE);
- return 1;
- }
- if (is_a_field_of_this.type != NULL)
- {
-
- if (innermost_block == 0 ||
- contained_in (block_found, innermost_block))
- innermost_block = block_found;
- write_exp_elt_opcode (ps, OP_THIS);
- write_exp_elt_opcode (ps, OP_THIS);
- write_exp_elt_opcode (ps, STRUCTOP_PTR);
- write_exp_string (ps, name);
- write_exp_elt_opcode (ps, STRUCTOP_PTR);
- return 1;
- }
- return 0;
- }
- static void
- push_fieldnames (struct parser_state *ps, struct stoken name)
- {
- int i;
- struct stoken token;
- token.ptr = name.ptr;
- for (i = 0; ; i++)
- {
- if (i == name.length || name.ptr[i] == '.')
- {
-
- token.length = &name.ptr[i] - token.ptr;
- write_exp_elt_opcode (ps, STRUCTOP_PTR);
- write_exp_string (ps, token);
- write_exp_elt_opcode (ps, STRUCTOP_PTR);
- token.ptr += token.length + 1;
- }
- if (i >= name.length)
- break;
- }
- }
- static void
- push_type_name (struct parser_state *ps, struct type *type,
- struct stoken name, int dot_index)
- {
- if (dot_index == name.length)
- {
- write_exp_elt_opcode (ps, OP_TYPE);
- write_exp_elt_type (ps, type);
- write_exp_elt_opcode (ps, OP_TYPE);
- }
- else
- {
- struct stoken token;
- token.ptr = name.ptr;
- token.length = dot_index;
- dot_index = 0;
- while (dot_index < name.length && name.ptr[dot_index] != '.')
- dot_index++;
- token.ptr = name.ptr;
- token.length = dot_index;
- write_exp_elt_opcode (ps, OP_SCOPE);
- write_exp_elt_type (ps, type);
- write_exp_string (ps, token);
- write_exp_elt_opcode (ps, OP_SCOPE);
- if (dot_index < name.length)
- {
- dot_index++;
- name.ptr += dot_index;
- name.length -= dot_index;
- push_fieldnames (ps, name);
- }
- }
- }
- static int
- push_module_name (struct parser_state *ps, struct type *module,
- struct stoken name, int dot_index)
- {
- if (dot_index == name.length)
- {
- write_exp_elt_opcode (ps, OP_TYPE);
- write_exp_elt_type (ps, module);
- write_exp_elt_opcode (ps, OP_TYPE);
- return 1;
- }
- else
- {
- struct symbol *sym;
- char *copy;
- copy = copy_name (name);
- sym = lookup_symbol_in_static_block (copy, expression_context_block,
- VAR_DOMAIN);
- if (sym != NULL)
- sym = lookup_global_symbol (copy, expression_context_block,
- VAR_DOMAIN);
- if (sym != NULL)
- {
- if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
- {
- write_exp_elt_opcode (ps, OP_VAR_VALUE);
- write_exp_elt_block (ps, NULL);
- write_exp_elt_sym (ps, sym);
- write_exp_elt_opcode (ps, OP_VAR_VALUE);
- }
- else
- {
- write_exp_elt_opcode (ps, OP_TYPE);
- write_exp_elt_type (ps, SYMBOL_TYPE (sym));
- write_exp_elt_opcode (ps, OP_TYPE);
- }
- return 1;
- }
- }
- return 0;
- }
- static void
- push_expression_name (struct parser_state *ps, struct stoken name)
- {
- struct stoken token;
- struct type *typ;
- struct bound_minimal_symbol msymbol;
- char *copy;
- int doti;
-
- if (push_variable (ps, name) != 0)
- return;
-
- typ = d_module_from_name (name);
- if (typ != NULL)
- {
- if (push_module_name (ps, typ, name, name.length) != 0)
- return;
- }
-
- typ = d_type_from_name (name);
- if (typ != NULL)
- {
- push_type_name (ps, typ, name, name.length);
- return;
- }
-
- for (doti = 0; doti < name.length; doti++)
- {
- if (name.ptr[doti] == '.')
- {
- token.ptr = name.ptr;
- token.length = doti;
- if (push_variable (ps, token) != 0)
- {
- token.ptr = name.ptr + doti + 1;
- token.length = name.length - doti - 1;
- push_fieldnames (ps, token);
- return;
- }
- break;
- }
- }
-
- if (doti < name.length)
- {
- token.ptr = name.ptr;
- for (;;)
- {
- token.length = doti;
-
- typ = d_module_from_name (token);
- if (typ != NULL)
- {
- if (push_module_name (ps, typ, name, doti) != 0)
- return;
- }
-
- typ = d_type_from_name (token);
- if (typ != NULL)
- {
- push_type_name (ps, typ, name, doti);
- return;
- }
- if (doti >= name.length)
- break;
- doti++;
- while (doti < name.length && name.ptr[doti] != '.')
- doti++;
- }
- }
-
- copy = copy_name (name);
- msymbol = lookup_bound_minimal_symbol (copy);
- if (msymbol.minsym != NULL)
- write_exp_msymbol (ps, msymbol);
- else if (!have_full_symbols () && !have_partial_symbols ())
- error (_("No symbol table is loaded. Use the \"file\" command"));
- else
- error (_("No symbol \"%s\" in current context."), copy);
- }
- static int saw_name_at_eof;
- static int last_was_structop;
- static int
- yylex (void)
- {
- int c;
- int namelen;
- unsigned int i;
- const char *tokstart;
- int saw_structop = last_was_structop;
- char *copy;
- last_was_structop = 0;
- retry:
- prev_lexptr = lexptr;
- tokstart = lexptr;
-
- for (i = 0; i < sizeof tokentab3 / sizeof tokentab3[0]; i++)
- if (strncmp (tokstart, tokentab3[i].operator, 3) == 0)
- {
- lexptr += 3;
- yylval.opcode = tokentab3[i].opcode;
- return tokentab3[i].token;
- }
-
- for (i = 0; i < sizeof tokentab2 / sizeof tokentab2[0]; i++)
- if (strncmp (tokstart, tokentab2[i].operator, 2) == 0)
- {
- lexptr += 2;
- yylval.opcode = tokentab2[i].opcode;
- return tokentab2[i].token;
- }
- switch (c = *tokstart)
- {
- case 0:
-
- if (saw_name_at_eof)
- {
- saw_name_at_eof = 0;
- return COMPLETE;
- }
- else if (saw_structop)
- return COMPLETE;
- else
- return 0;
- case ' ':
- case '\t':
- case '\n':
- lexptr++;
- goto retry;
- case '[':
- case '(':
- paren_depth++;
- lexptr++;
- return c;
- case ']':
- case ')':
- if (paren_depth == 0)
- return 0;
- paren_depth--;
- lexptr++;
- return c;
- case ',':
- if (comma_terminates && paren_depth == 0)
- return 0;
- lexptr++;
- return c;
- case '.':
-
- if (lexptr[1] < '0' || lexptr[1] > '9')
- {
- if (parse_completion)
- last_was_structop = 1;
- goto symbol;
- }
-
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- {
-
- int got_dot = 0, got_e = 0, toktype;
- const char *p = tokstart;
- int hex = input_radix > 10;
- if (c == '0' && (p[1] == 'x' || p[1] == 'X'))
- {
- p += 2;
- hex = 1;
- }
- for (;; ++p)
- {
-
- if ((!hex && !got_e && tolower (p[0]) == 'e')
- || (hex && !got_e && tolower (p[0] == 'p')))
- got_dot = got_e = 1;
-
- else if (!got_dot && (p[0] == '.' && p[1] != '.'))
- got_dot = 1;
-
- else if (got_e && (tolower (p[-1]) == 'e' || tolower (p[-1]) == 'p')
- && (*p == '-' || *p == '+'))
- continue;
-
- else if ((*p < '0' || *p > '9') && (*p != '_') &&
- ((*p < 'a' || *p > 'z') && (*p < 'A' || *p > 'Z')))
- break;
- }
- toktype = parse_number (pstate, tokstart, p - tokstart,
- got_dot|got_e, &yylval);
- if (toktype == ERROR)
- {
- char *err_copy = (char *) alloca (p - tokstart + 1);
- memcpy (err_copy, tokstart, p - tokstart);
- err_copy[p - tokstart] = 0;
- error (_("Invalid number \"%s\"."), err_copy);
- }
- lexptr = p;
- return toktype;
- }
- case '@':
- {
- const char *p = &tokstart[1];
- size_t len = strlen ("entry");
- while (isspace (*p))
- p++;
- if (strncmp (p, "entry", len) == 0 && !isalnum (p[len])
- && p[len] != '_')
- {
- lexptr = &p[len];
- return ENTRY;
- }
- }
-
- case '+':
- case '-':
- case '*':
- case '/':
- case '%':
- case '|':
- case '&':
- case '^':
- case '~':
- case '!':
- case '<':
- case '>':
- case '?':
- case ':':
- case '=':
- case '{':
- case '}':
- symbol:
- lexptr++;
- return c;
- case '\'':
- case '"':
- case '`':
- {
- int host_len;
- int result = parse_string_or_char (tokstart, &lexptr, &yylval.tsval,
- &host_len);
- if (result == CHARACTER_LITERAL)
- {
- if (host_len == 0)
- error (_("Empty character constant."));
- else if (host_len > 2 && c == '\'')
- {
- ++tokstart;
- namelen = lexptr - tokstart - 1;
- goto tryname;
- }
- else if (host_len > 1)
- error (_("Invalid character constant."));
- }
- return result;
- }
- }
- if (!(c == '_' || c == '$'
- || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')))
-
- error (_("Invalid character '%c' in expression"), c);
-
- namelen = 0;
- for (c = tokstart[namelen];
- (c == '_' || c == '$' || (c >= '0' && c <= '9')
- || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'));)
- c = tokstart[++namelen];
-
- if (namelen == 2 && tokstart[0] == 'i' && tokstart[1] == 'f')
- return 0;
-
- if (namelen >= 1
- && (strncmp (tokstart, "thread", namelen) == 0
- || strncmp (tokstart, "task", namelen) == 0)
- && (tokstart[namelen] == ' ' || tokstart[namelen] == '\t'))
- {
- const char *p = tokstart + namelen + 1;
- while (*p == ' ' || *p == '\t')
- p++;
- if (*p >= '0' && *p <= '9')
- return 0;
- }
- lexptr += namelen;
- tryname:
- yylval.sval.ptr = tokstart;
- yylval.sval.length = namelen;
-
- copy = copy_name (yylval.sval);
- for (i = 0; i < sizeof ident_tokens / sizeof ident_tokens[0]; i++)
- if (strcmp (copy, ident_tokens[i].operator) == 0)
- {
-
- yylval.opcode = ident_tokens[i].opcode;
- return ident_tokens[i].token;
- }
- if (*tokstart == '$')
- return DOLLAR_VARIABLE;
- yylval.tsym.type
- = language_lookup_primitive_type (parse_language (pstate),
- parse_gdbarch (pstate), copy);
- if (yylval.tsym.type != NULL)
- return TYPENAME;
-
- if ((tokstart[0] >= 'a' && tokstart[0] < 'a' + input_radix - 10)
- || (tokstart[0] >= 'A' && tokstart[0] < 'A' + input_radix - 10))
- {
- YYSTYPE newlval;
- int hextype = parse_number (pstate, tokstart, namelen, 0, &newlval);
- if (hextype == INTEGER_LITERAL)
- return NAME_OR_INT;
- }
- if (parse_completion && *lexptr == '\0')
- saw_name_at_eof = 1;
- return IDENTIFIER;
- }
- int
- d_parse (struct parser_state *par_state)
- {
- int result;
- struct cleanup *back_to;
-
- gdb_assert (par_state != NULL);
- pstate = par_state;
- back_to = make_cleanup (null_cleanup, NULL);
- make_cleanup_restore_integer (&yydebug);
- make_cleanup_clear_parser_state (&pstate);
- yydebug = parser_debug;
-
- last_was_structop = 0;
- saw_name_at_eof = 0;
- result = yyparse ();
- do_cleanups (back_to);
- return result;
- }
- void
- yyerror (char *msg)
- {
- if (prev_lexptr)
- lexptr = prev_lexptr;
- error (_("A %s in expression, near `%s'."), (msg ? msg : "error"), lexptr);
- }