PageRenderTime 60ms CodeModel.GetById 26ms RepoModel.GetById 0ms app.codeStats 0ms

/opensource.apple.com/source/gdb/gdb-186.1/src/gdb/jv-exp.y

#
Happy | 1489 lines | 1315 code | 174 blank | 0 comment | 0 complexity | d534bc5cafcca8bf5b854ee25e6d5e8f MD5 | raw file
Possible License(s): LGPL-2.0, MPL-2.0, GPL-2.0, ISC, LGPL-2.1, Apache-2.0, MPL-2.0-no-copyleft-exception, BSD-3-Clause, WTFPL, MIT, AGPL-1.0, AGPL-3.0
  1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  3. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
  4. <head>
  5. <title>jv-exp.y</title>
  6. <style type="text/css">
  7. .enscript-comment { font-style: italic; color: rgb(178,34,34); }
  8. .enscript-function-name { font-weight: bold; color: rgb(0,0,255); }
  9. .enscript-variable-name { font-weight: bold; color: rgb(184,134,11); }
  10. .enscript-keyword { font-weight: bold; color: rgb(160,32,240); }
  11. .enscript-reference { font-weight: bold; color: rgb(95,158,160); }
  12. .enscript-string { font-weight: bold; color: rgb(188,143,143); }
  13. .enscript-builtin { font-weight: bold; color: rgb(218,112,214); }
  14. .enscript-type { font-weight: bold; color: rgb(34,139,34); }
  15. .enscript-highlight { text-decoration: underline; color: 0; }
  16. </style>
  17. </head>
  18. <body id="top">
  19. <h1 style="margin:8px;" id="f1">jv-exp.y&nbsp;&nbsp;&nbsp;<span style="font-weight: normal; font-size: 0.5em;">[<a href="?txt">plain text</a>]</span></h1>
  20. <hr/>
  21. <div></div>
  22. <pre>
  23. /* YACC parser for Java expressions, for GDB.
  24. Copyright (C) 1997, 1998, 1999.
  25. Free Software Foundation, Inc.
  26. This file is part of GDB.
  27. This program is free software; you can redistribute it and/or modify
  28. it under the terms of the GNU General Public License as published by
  29. the Free Software Foundation; either version 2 of the License, or
  30. (at your option) any later version.
  31. This program is distributed in the hope that it will be useful,
  32. but WITHOUT ANY WARRANTY; without even the implied warranty of
  33. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  34. GNU General Public License for more details.
  35. You should have received a copy of the GNU General Public License
  36. along with this program; if not, write to the Free Software
  37. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
  38. /* Parse a Java expression from text in a string,
  39. and return the result as a struct expression pointer.
  40. That structure contains arithmetic operations in reverse polish,
  41. with constants represented by operations that are followed by special data.
  42. See expression.h for the details of the format.
  43. What is important here is that it can be built up sequentially
  44. during the process of parsing; the lower levels of the tree always
  45. come first in the result. Well, almost always; see ArrayAccess.
  46. Note that malloc's and realloc's in this file are transformed to
  47. xmalloc and xrealloc respectively by the same sed command in the
  48. makefile that remaps any other malloc/realloc inserted by the parser
  49. generator. Doing this with #defines and trying to control the interaction
  50. with include files (&lt;malloc.h&gt; and &lt;stdlib.h&gt; for example) just became
  51. too messy, particularly when such includes can be inserted at random
  52. times by the parser generator. */
  53. %{
  54. #include &quot;defs.h&quot;
  55. #include &quot;gdb_string.h&quot;
  56. #include &lt;ctype.h&gt;
  57. #include &quot;expression.h&quot;
  58. #include &quot;value.h&quot;
  59. #include &quot;parser-defs.h&quot;
  60. #include &quot;language.h&quot;
  61. #include &quot;jv-lang.h&quot;
  62. #include &quot;bfd.h&quot; /* Required by objfiles.h. */
  63. #include &quot;symfile.h&quot; /* Required by objfiles.h. */
  64. #include &quot;objfiles.h&quot; /* For have_full_symbols and have_partial_symbols */
  65. #include &quot;top.h&quot;
  66. /* Remap normal yacc parser interface names (yyparse, yylex, yyerror, etc),
  67. as well as gratuitiously global symbol names, so we can have multiple
  68. yacc generated parsers in gdb. Note that these are only the variables
  69. produced by yacc. If other parser generators (bison, byacc, etc) produce
  70. additional global names that conflict at link time, then those parser
  71. generators need to be fixed instead of adding those names to this list. */
  72. #define yymaxdepth java_maxdepth
  73. #define yyparse java_parse
  74. #define yylex java_lex
  75. #define yyerror java_error
  76. #define yylval java_lval
  77. #define yychar java_char
  78. #define yydebug java_debug
  79. #define yypact java_pact
  80. #define yyr1 java_r1
  81. #define yyr2 java_r2
  82. #define yydef java_def
  83. #define yychk java_chk
  84. #define yypgo java_pgo
  85. #define yyact java_act
  86. #define yyexca java_exca
  87. #define yyerrflag java_errflag
  88. #define yynerrs java_nerrs
  89. #define yyps java_ps
  90. #define yypv java_pv
  91. #define yys java_s
  92. #define yy_yys java_yys
  93. #define yystate java_state
  94. #define yytmp java_tmp
  95. #define yyv java_v
  96. #define yy_yyv java_yyv
  97. #define yyval java_val
  98. #define yylloc java_lloc
  99. #define yyreds java_reds /* With YYDEBUG defined */
  100. #define yytoks java_toks /* With YYDEBUG defined */
  101. #define yylhs java_yylhs
  102. #define yylen java_yylen
  103. #define yydefred java_yydefred
  104. #define yydgoto java_yydgoto
  105. #define yysindex java_yysindex
  106. #define yyrindex java_yyrindex
  107. #define yygindex java_yygindex
  108. #define yytable java_yytable
  109. #define yycheck java_yycheck
  110. #ifndef YYDEBUG
  111. #define YYDEBUG 0 /* Default to no yydebug support */
  112. #endif
  113. int yyparse (void);
  114. static int yylex (void);
  115. void yyerror (char *);
  116. static struct type *java_type_from_name (struct stoken);
  117. static void push_expression_name (struct stoken);
  118. static void push_fieldnames (struct stoken);
  119. static struct expression *copy_exp (struct expression *, int);
  120. static void insert_exp (int, struct expression *);
  121. %}
  122. /* Although the yacc &quot;value&quot; of an expression is not used,
  123. since the result is stored in the structure being created,
  124. other node types do have values. */
  125. %union
  126. {
  127. LONGEST lval;
  128. struct {
  129. LONGEST val;
  130. struct type *type;
  131. } typed_val_int;
  132. struct {
  133. DOUBLEST dval;
  134. struct type *type;
  135. } typed_val_float;
  136. struct symbol *sym;
  137. struct type *tval;
  138. struct stoken sval;
  139. struct ttype tsym;
  140. struct symtoken ssym;
  141. struct block *bval;
  142. enum exp_opcode opcode;
  143. struct internalvar *ivar;
  144. int *ivec;
  145. }
  146. %{
  147. /* YYSTYPE gets defined by %union */
  148. static int parse_number (char *, int, int, YYSTYPE *);
  149. %}
  150. %type &lt;lval&gt; rcurly Dims Dims_opt
  151. %type &lt;tval&gt; ClassOrInterfaceType ClassType /* ReferenceType Type ArrayType */
  152. %type &lt;tval&gt; IntegralType FloatingPointType NumericType PrimitiveType ArrayType PrimitiveOrArrayType
  153. %token &lt;typed_val_int&gt; INTEGER_LITERAL
  154. %token &lt;typed_val_float&gt; FLOATING_POINT_LITERAL
  155. %token &lt;sval&gt; IDENTIFIER
  156. %token &lt;sval&gt; STRING_LITERAL
  157. %token &lt;lval&gt; BOOLEAN_LITERAL
  158. %token &lt;tsym&gt; TYPENAME
  159. %type &lt;sval&gt; Name SimpleName QualifiedName ForcedName
  160. /* A NAME_OR_INT is a symbol which is not known in the symbol table,
  161. but which would parse as a valid number in the current input radix.
  162. E.g. &quot;c&quot; when input_radix==16. Depending on the parse, it will be
  163. turned into a name or into a number. */
  164. %token &lt;sval&gt; NAME_OR_INT
  165. %token ERROR
  166. /* Special type cases, put in to allow the parser to distinguish different
  167. legal basetypes. */
  168. %token LONG SHORT BYTE INT CHAR BOOLEAN DOUBLE FLOAT
  169. %token VARIABLE
  170. %token &lt;opcode&gt; ASSIGN_MODIFY
  171. %token THIS SUPER NEW
  172. %left ','
  173. %right '=' ASSIGN_MODIFY
  174. %right '?'
  175. %left OROR
  176. %left ANDAND
  177. %left '|'
  178. %left '^'
  179. %left '&amp;'
  180. %left EQUAL NOTEQUAL
  181. %left '&lt;' '&gt;' LEQ GEQ
  182. %left LSH RSH
  183. %left '+' '-'
  184. %left '*' '/' '%'
  185. %right INCREMENT DECREMENT
  186. %right '.' '[' '('
  187. %%
  188. start : exp1
  189. | type_exp
  190. ;
  191. type_exp: PrimitiveOrArrayType
  192. {
  193. write_exp_elt_opcode(OP_TYPE);
  194. write_exp_elt_type($1);
  195. write_exp_elt_opcode(OP_TYPE);
  196. }
  197. ;
  198. PrimitiveOrArrayType:
  199. PrimitiveType
  200. | ArrayType
  201. ;
  202. StringLiteral:
  203. STRING_LITERAL
  204. {
  205. write_exp_elt_opcode (OP_STRING);
  206. write_exp_string ($1);
  207. write_exp_elt_opcode (OP_STRING);
  208. }
  209. ;
  210. Literal:
  211. INTEGER_LITERAL
  212. { write_exp_elt_opcode (OP_LONG);
  213. write_exp_elt_type ($1.type);
  214. write_exp_elt_longcst ((LONGEST)($1.val));
  215. write_exp_elt_opcode (OP_LONG); }
  216. | NAME_OR_INT
  217. { YYSTYPE val;
  218. parse_number ($1.ptr, $1.length, 0, &amp;val);
  219. write_exp_elt_opcode (OP_LONG);
  220. write_exp_elt_type (val.typed_val_int.type);
  221. write_exp_elt_longcst ((LONGEST)val.typed_val_int.val);
  222. write_exp_elt_opcode (OP_LONG);
  223. }
  224. | FLOATING_POINT_LITERAL
  225. { write_exp_elt_opcode (OP_DOUBLE);
  226. write_exp_elt_type ($1.type);
  227. write_exp_elt_dblcst ($1.dval);
  228. write_exp_elt_opcode (OP_DOUBLE); }
  229. | BOOLEAN_LITERAL
  230. { write_exp_elt_opcode (OP_LONG);
  231. write_exp_elt_type (java_boolean_type);
  232. write_exp_elt_longcst ((LONGEST)$1);
  233. write_exp_elt_opcode (OP_LONG); }
  234. | StringLiteral
  235. ;
  236. /* UNUSED:
  237. Type:
  238. PrimitiveType
  239. | ReferenceType
  240. ;
  241. */
  242. PrimitiveType:
  243. NumericType
  244. | BOOLEAN
  245. { $$ = java_boolean_type; }
  246. ;
  247. NumericType:
  248. IntegralType
  249. | FloatingPointType
  250. ;
  251. IntegralType:
  252. BYTE
  253. { $$ = java_byte_type; }
  254. | SHORT
  255. { $$ = java_short_type; }
  256. | INT
  257. { $$ = java_int_type; }
  258. | LONG
  259. { $$ = java_long_type; }
  260. | CHAR
  261. { $$ = java_char_type; }
  262. ;
  263. FloatingPointType:
  264. FLOAT
  265. { $$ = java_float_type; }
  266. | DOUBLE
  267. { $$ = java_double_type; }
  268. ;
  269. /* UNUSED:
  270. ReferenceType:
  271. ClassOrInterfaceType
  272. | ArrayType
  273. ;
  274. */
  275. ClassOrInterfaceType:
  276. Name
  277. { $$ = java_type_from_name ($1); }
  278. ;
  279. ClassType:
  280. ClassOrInterfaceType
  281. ;
  282. ArrayType:
  283. PrimitiveType Dims
  284. { $$ = java_array_type ($1, $2); }
  285. | Name Dims
  286. { $$ = java_array_type (java_type_from_name ($1), $2); }
  287. ;
  288. Name:
  289. IDENTIFIER
  290. | QualifiedName
  291. ;
  292. ForcedName:
  293. SimpleName
  294. | QualifiedName
  295. ;
  296. SimpleName:
  297. IDENTIFIER
  298. | NAME_OR_INT
  299. ;
  300. QualifiedName:
  301. Name '.' SimpleName
  302. { $$.length = $1.length + $3.length + 1;
  303. if ($1.ptr + $1.length + 1 == $3.ptr
  304. &amp;&amp; $1.ptr[$1.length] == '.')
  305. $$.ptr = $1.ptr; /* Optimization. */
  306. else
  307. {
  308. $$.ptr = (char *) malloc ($$.length + 1);
  309. make_cleanup (free, $$.ptr);
  310. sprintf ($$.ptr, &quot;%.*s.%.*s&quot;,
  311. $1.length, $1.ptr, $3.length, $3.ptr);
  312. } }
  313. ;
  314. /*
  315. type_exp: type
  316. { write_exp_elt_opcode(OP_TYPE);
  317. write_exp_elt_type($1);
  318. write_exp_elt_opcode(OP_TYPE);}
  319. ;
  320. */
  321. /* Expressions, including the comma operator. */
  322. exp1 : Expression
  323. | exp1 ',' Expression
  324. { write_exp_elt_opcode (BINOP_COMMA); }
  325. ;
  326. Primary:
  327. PrimaryNoNewArray
  328. | ArrayCreationExpression
  329. ;
  330. PrimaryNoNewArray:
  331. Literal
  332. | THIS
  333. { write_exp_elt_opcode (OP_THIS);
  334. write_exp_elt_opcode (OP_THIS); }
  335. | '(' Expression ')'
  336. | ClassInstanceCreationExpression
  337. | FieldAccess
  338. | MethodInvocation
  339. | ArrayAccess
  340. | lcurly ArgumentList rcurly
  341. { write_exp_elt_opcode (OP_ARRAY);
  342. write_exp_elt_longcst ((LONGEST) 0);
  343. write_exp_elt_longcst ((LONGEST) $3);
  344. write_exp_elt_opcode (OP_ARRAY); }
  345. ;
  346. lcurly:
  347. '{'
  348. { start_arglist (); }
  349. ;
  350. rcurly:
  351. '}'
  352. { $$ = end_arglist () - 1; }
  353. ;
  354. ClassInstanceCreationExpression:
  355. NEW ClassType '(' ArgumentList_opt ')'
  356. { error (&quot;FIXME - ClassInstanceCreationExpression&quot;); }
  357. ;
  358. ArgumentList:
  359. Expression
  360. { arglist_len = 1; }
  361. | ArgumentList ',' Expression
  362. { arglist_len++; }
  363. ;
  364. ArgumentList_opt:
  365. /* EMPTY */
  366. { arglist_len = 0; }
  367. | ArgumentList
  368. ;
  369. ArrayCreationExpression:
  370. NEW PrimitiveType DimExprs Dims_opt
  371. { error (&quot;FIXME - ArrayCreatiionExpression&quot;); }
  372. | NEW ClassOrInterfaceType DimExprs Dims_opt
  373. { error (&quot;FIXME - ArrayCreatiionExpression&quot;); }
  374. ;
  375. DimExprs:
  376. DimExpr
  377. | DimExprs DimExpr
  378. ;
  379. DimExpr:
  380. '[' Expression ']'
  381. ;
  382. Dims:
  383. '[' ']'
  384. { $$ = 1; }
  385. | Dims '[' ']'
  386. { $$ = $1 + 1; }
  387. ;
  388. Dims_opt:
  389. Dims
  390. | /* EMPTY */
  391. { $$ = 0; }
  392. ;
  393. FieldAccess:
  394. Primary '.' SimpleName
  395. { push_fieldnames ($3); }
  396. | VARIABLE '.' SimpleName
  397. { push_fieldnames ($3); }
  398. /*| SUPER '.' SimpleName { FIXME } */
  399. ;
  400. MethodInvocation:
  401. Name '(' ArgumentList_opt ')'
  402. { error (&quot;method invocation not implemented&quot;); }
  403. | Primary '.' SimpleName '(' ArgumentList_opt ')'
  404. { error (&quot;method invocation not implemented&quot;); }
  405. | SUPER '.' SimpleName '(' ArgumentList_opt ')'
  406. { error (&quot;method invocation not implemented&quot;); }
  407. ;
  408. ArrayAccess:
  409. Name '[' Expression ']'
  410. {
  411. /* Emit code for the Name now, then exchange it in the
  412. expout array with the Expression's code. We could
  413. introduce a OP_SWAP code or a reversed version of
  414. BINOP_SUBSCRIPT, but that makes the rest of GDB pay
  415. for our parsing kludges. */
  416. struct expression *name_expr;
  417. push_expression_name ($1);
  418. name_expr = copy_exp (expout, expout_ptr);
  419. expout_ptr -= name_expr-&gt;nelts;
  420. insert_exp (expout_ptr-length_of_subexp (expout, expout_ptr),
  421. name_expr);
  422. free (name_expr);
  423. write_exp_elt_opcode (BINOP_SUBSCRIPT);
  424. }
  425. | VARIABLE '[' Expression ']'
  426. { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
  427. | PrimaryNoNewArray '[' Expression ']'
  428. { write_exp_elt_opcode (BINOP_SUBSCRIPT); }
  429. ;
  430. PostfixExpression:
  431. Primary
  432. | Name
  433. { push_expression_name ($1); }
  434. | VARIABLE
  435. /* Already written by write_dollar_variable. */
  436. | PostIncrementExpression
  437. | PostDecrementExpression
  438. ;
  439. PostIncrementExpression:
  440. PostfixExpression INCREMENT
  441. { write_exp_elt_opcode (UNOP_POSTINCREMENT); }
  442. ;
  443. PostDecrementExpression:
  444. PostfixExpression DECREMENT
  445. { write_exp_elt_opcode (UNOP_POSTDECREMENT); }
  446. ;
  447. UnaryExpression:
  448. PreIncrementExpression
  449. | PreDecrementExpression
  450. | '+' UnaryExpression
  451. | '-' UnaryExpression
  452. { write_exp_elt_opcode (UNOP_NEG); }
  453. | '*' UnaryExpression
  454. { write_exp_elt_opcode (UNOP_IND); } /*FIXME not in Java */
  455. | UnaryExpressionNotPlusMinus
  456. ;
  457. PreIncrementExpression:
  458. INCREMENT UnaryExpression
  459. { write_exp_elt_opcode (UNOP_PREINCREMENT); }
  460. ;
  461. PreDecrementExpression:
  462. DECREMENT UnaryExpression
  463. { write_exp_elt_opcode (UNOP_PREDECREMENT); }
  464. ;
  465. UnaryExpressionNotPlusMinus:
  466. PostfixExpression
  467. | '~' UnaryExpression
  468. { write_exp_elt_opcode (UNOP_COMPLEMENT); }
  469. | '!' UnaryExpression
  470. { write_exp_elt_opcode (UNOP_LOGICAL_NOT); }
  471. | CastExpression
  472. ;
  473. CastExpression:
  474. '(' PrimitiveType Dims_opt ')' UnaryExpression
  475. { write_exp_elt_opcode (UNOP_CAST);
  476. write_exp_elt_type (java_array_type ($2, $3));
  477. write_exp_elt_opcode (UNOP_CAST); }
  478. | '(' Expression ')' UnaryExpressionNotPlusMinus
  479. {
  480. int exp_size = expout_ptr;
  481. int last_exp_size = length_of_subexp(expout, expout_ptr);
  482. struct type *type;
  483. int i;
  484. int base = expout_ptr - last_exp_size - 3;
  485. if (base &lt; 0 || expout-&gt;elts[base+2].opcode != OP_TYPE)
  486. error (&quot;invalid cast expression&quot;);
  487. type = expout-&gt;elts[base+1].type;
  488. /* Remove the 'Expression' and slide the
  489. UnaryExpressionNotPlusMinus down to replace it. */
  490. for (i = 0; i &lt; last_exp_size; i++)
  491. expout-&gt;elts[base + i] = expout-&gt;elts[base + i + 3];
  492. expout_ptr -= 3;
  493. if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
  494. type = lookup_pointer_type (type);
  495. write_exp_elt_opcode (UNOP_CAST);
  496. write_exp_elt_type (type);
  497. write_exp_elt_opcode (UNOP_CAST);
  498. }
  499. | '(' Name Dims ')' UnaryExpressionNotPlusMinus
  500. { write_exp_elt_opcode (UNOP_CAST);
  501. write_exp_elt_type (java_array_type (java_type_from_name ($2), $3));
  502. write_exp_elt_opcode (UNOP_CAST); }
  503. ;
  504. MultiplicativeExpression:
  505. UnaryExpression
  506. | MultiplicativeExpression '*' UnaryExpression
  507. { write_exp_elt_opcode (BINOP_MUL); }
  508. | MultiplicativeExpression '/' UnaryExpression
  509. { write_exp_elt_opcode (BINOP_DIV); }
  510. | MultiplicativeExpression '%' UnaryExpression
  511. { write_exp_elt_opcode (BINOP_REM); }
  512. ;
  513. AdditiveExpression:
  514. MultiplicativeExpression
  515. | AdditiveExpression '+' MultiplicativeExpression
  516. { write_exp_elt_opcode (BINOP_ADD); }
  517. | AdditiveExpression '-' MultiplicativeExpression
  518. { write_exp_elt_opcode (BINOP_SUB); }
  519. ;
  520. ShiftExpression:
  521. AdditiveExpression
  522. | ShiftExpression LSH AdditiveExpression
  523. { write_exp_elt_opcode (BINOP_LSH); }
  524. | ShiftExpression RSH AdditiveExpression
  525. { write_exp_elt_opcode (BINOP_RSH); }
  526. /* | ShiftExpression &gt;&gt;&gt; AdditiveExpression { FIXME } */
  527. ;
  528. RelationalExpression:
  529. ShiftExpression
  530. | RelationalExpression '&lt;' ShiftExpression
  531. { write_exp_elt_opcode (BINOP_LESS); }
  532. | RelationalExpression '&gt;' ShiftExpression
  533. { write_exp_elt_opcode (BINOP_GTR); }
  534. | RelationalExpression LEQ ShiftExpression
  535. { write_exp_elt_opcode (BINOP_LEQ); }
  536. | RelationalExpression GEQ ShiftExpression
  537. { write_exp_elt_opcode (BINOP_GEQ); }
  538. /* | RelationalExpresion INSTANCEOF ReferenceType { FIXME } */
  539. ;
  540. EqualityExpression:
  541. RelationalExpression
  542. | EqualityExpression EQUAL RelationalExpression
  543. { write_exp_elt_opcode (BINOP_EQUAL); }
  544. | EqualityExpression NOTEQUAL RelationalExpression
  545. { write_exp_elt_opcode (BINOP_NOTEQUAL); }
  546. ;
  547. AndExpression:
  548. EqualityExpression
  549. | AndExpression '&amp;' EqualityExpression
  550. { write_exp_elt_opcode (BINOP_BITWISE_AND); }
  551. ;
  552. ExclusiveOrExpression:
  553. AndExpression
  554. | ExclusiveOrExpression '^' AndExpression
  555. { write_exp_elt_opcode (BINOP_BITWISE_XOR); }
  556. ;
  557. InclusiveOrExpression:
  558. ExclusiveOrExpression
  559. | InclusiveOrExpression '|' ExclusiveOrExpression
  560. { write_exp_elt_opcode (BINOP_BITWISE_IOR); }
  561. ;
  562. ConditionalAndExpression:
  563. InclusiveOrExpression
  564. | ConditionalAndExpression ANDAND InclusiveOrExpression
  565. { write_exp_elt_opcode (BINOP_LOGICAL_AND); }
  566. ;
  567. ConditionalOrExpression:
  568. ConditionalAndExpression
  569. | ConditionalOrExpression OROR ConditionalAndExpression
  570. { write_exp_elt_opcode (BINOP_LOGICAL_OR); }
  571. ;
  572. ConditionalExpression:
  573. ConditionalOrExpression
  574. | ConditionalOrExpression '?' Expression ':' ConditionalExpression
  575. { write_exp_elt_opcode (TERNOP_COND); }
  576. ;
  577. AssignmentExpression:
  578. ConditionalExpression
  579. | Assignment
  580. ;
  581. Assignment:
  582. LeftHandSide '=' ConditionalExpression
  583. { write_exp_elt_opcode (BINOP_ASSIGN); }
  584. | LeftHandSide ASSIGN_MODIFY ConditionalExpression
  585. { write_exp_elt_opcode (BINOP_ASSIGN_MODIFY);
  586. write_exp_elt_opcode ($2);
  587. write_exp_elt_opcode (BINOP_ASSIGN_MODIFY); }
  588. ;
  589. LeftHandSide:
  590. ForcedName
  591. { push_expression_name ($1); }
  592. | VARIABLE
  593. /* Already written by write_dollar_variable. */
  594. | FieldAccess
  595. | ArrayAccess
  596. ;
  597. Expression:
  598. AssignmentExpression
  599. ;
  600. %%
  601. /* Take care of parsing a number (anything that starts with a digit).
  602. Set yylval and return the token type; update lexptr.
  603. LEN is the number of characters in it. */
  604. /*** Needs some error checking for the float case ***/
  605. static int
  606. parse_number (p, len, parsed_float, putithere)
  607. register char *p;
  608. register int len;
  609. int parsed_float;
  610. YYSTYPE *putithere;
  611. {
  612. register ULONGEST n = 0;
  613. ULONGEST limit, limit_div_base;
  614. register int c;
  615. register int base = input_radix;
  616. struct type *type;
  617. if (parsed_float)
  618. {
  619. /* It's a float since it contains a point or an exponent. */
  620. char c;
  621. int num = 0; /* number of tokens scanned by scanf */
  622. char saved_char = p[len];
  623. p[len] = 0; /* null-terminate the token */
  624. if (sizeof (putithere-&gt;typed_val_float.dval) &lt;= sizeof (float))
  625. num = sscanf (p, &quot;%g%c&quot;, (float *) &amp;putithere-&gt;typed_val_float.dval, &amp;c);
  626. else if (sizeof (putithere-&gt;typed_val_float.dval) &lt;= sizeof (double))
  627. num = sscanf (p, &quot;%lg%c&quot;, (double *) &amp;putithere-&gt;typed_val_float.dval, &amp;c);
  628. else
  629. {
  630. #ifdef SCANF_HAS_LONG_DOUBLE
  631. num = sscanf (p, &quot;%Lg%c&quot;, &amp;putithere-&gt;typed_val_float.dval, &amp;c);
  632. #else
  633. /* Scan it into a double, then assign it to the long double.
  634. This at least wins with values representable in the range
  635. of doubles. */
  636. double temp;
  637. num = sscanf (p, &quot;%lg%c&quot;, &amp;temp, &amp;c);
  638. putithere-&gt;typed_val_float.dval = temp;
  639. #endif
  640. }
  641. p[len] = saved_char; /* restore the input stream */
  642. if (num != 1) /* check scanf found ONLY a float ... */
  643. return ERROR;
  644. /* See if it has `f' or `d' suffix (float or double). */
  645. c = tolower (p[len - 1]);
  646. if (c == 'f' || c == 'F')
  647. putithere-&gt;typed_val_float.type = builtin_type_float;
  648. else if (isdigit (c) || c == '.' || c == 'd' || c == 'D')
  649. putithere-&gt;typed_val_float.type = builtin_type_double;
  650. else
  651. return ERROR;
  652. return FLOATING_POINT_LITERAL;
  653. }
  654. /* Handle base-switching prefixes 0x, 0t, 0d, 0 */
  655. if (p[0] == '0')
  656. switch (p[1])
  657. {
  658. case 'x':
  659. case 'X':
  660. if (len &gt;= 3)
  661. {
  662. p += 2;
  663. base = 16;
  664. len -= 2;
  665. }
  666. break;
  667. case 't':
  668. case 'T':
  669. case 'd':
  670. case 'D':
  671. if (len &gt;= 3)
  672. {
  673. p += 2;
  674. base = 10;
  675. len -= 2;
  676. }
  677. break;
  678. default:
  679. base = 8;
  680. break;
  681. }
  682. c = p[len-1];
  683. limit = (ULONGEST)0xffffffff;
  684. if (c == 'l' || c == 'L')
  685. {
  686. type = java_long_type;
  687. len--;
  688. /* A paranoid calculation of (1&lt;&lt;64)-1. */
  689. limit = ((limit &lt;&lt; 16) &lt;&lt; 16) | limit;
  690. }
  691. else
  692. {
  693. type = java_int_type;
  694. }
  695. limit_div_base = limit / (ULONGEST) base;
  696. while (--len &gt;= 0)
  697. {
  698. c = *p++;
  699. if (c &gt;= '0' &amp;&amp; c &lt;= '9')
  700. c -= '0';
  701. else if (c &gt;= 'A' &amp;&amp; c &lt;= 'Z')
  702. c -= 'A' - 10;
  703. else if (c &gt;= 'a' &amp;&amp; c &lt;= 'z')
  704. c -= 'a' - 10;
  705. else
  706. return ERROR; /* Char not a digit */
  707. if (c &gt;= base)
  708. return ERROR;
  709. if (n &gt; limit_div_base
  710. || (n *= base) &gt; limit - c)
  711. error (&quot;Numeric constant too large.&quot;);
  712. n += c;
  713. }
  714. putithere-&gt;typed_val_int.val = n;
  715. putithere-&gt;typed_val_int.type = type;
  716. return INTEGER_LITERAL;
  717. }
  718. struct token
  719. {
  720. char *operator;
  721. int token;
  722. enum exp_opcode opcode;
  723. };
  724. static const struct token tokentab3[] =
  725. {
  726. {&quot;&gt;&gt;=&quot;, ASSIGN_MODIFY, BINOP_RSH},
  727. {&quot;&lt;&lt;=&quot;, ASSIGN_MODIFY, BINOP_LSH}
  728. };
  729. static const struct token tokentab2[] =
  730. {
  731. {&quot;+=&quot;, ASSIGN_MODIFY, BINOP_ADD},
  732. {&quot;-=&quot;, ASSIGN_MODIFY, BINOP_SUB},
  733. {&quot;*=&quot;, ASSIGN_MODIFY, BINOP_MUL},
  734. {&quot;/=&quot;, ASSIGN_MODIFY, BINOP_DIV},
  735. {&quot;%=&quot;, ASSIGN_MODIFY, BINOP_REM},
  736. {&quot;|=&quot;, ASSIGN_MODIFY, BINOP_BITWISE_IOR},
  737. {&quot;&amp;=&quot;, ASSIGN_MODIFY, BINOP_BITWISE_AND},
  738. {&quot;^=&quot;, ASSIGN_MODIFY, BINOP_BITWISE_XOR},
  739. {&quot;++&quot;, INCREMENT, BINOP_END},
  740. {&quot;--&quot;, DECREMENT, BINOP_END},
  741. {&quot;&amp;&amp;&quot;, ANDAND, BINOP_END},
  742. {&quot;||&quot;, OROR, BINOP_END},
  743. {&quot;&lt;&lt;&quot;, LSH, BINOP_END},
  744. {&quot;&gt;&gt;&quot;, RSH, BINOP_END},
  745. {&quot;==&quot;, EQUAL, BINOP_END},
  746. {&quot;!=&quot;, NOTEQUAL, BINOP_END},
  747. {&quot;&lt;=&quot;, LEQ, BINOP_END},
  748. {&quot;&gt;=&quot;, GEQ, BINOP_END}
  749. };
  750. /* Read one token, getting characters through lexptr. */
  751. static int
  752. yylex ()
  753. {
  754. int c;
  755. int namelen;
  756. unsigned int i;
  757. char *tokstart;
  758. char *tokptr;
  759. int tempbufindex;
  760. static char *tempbuf;
  761. static int tempbufsize;
  762. retry:
  763. tokstart = lexptr;
  764. /* See if it is a special token of length 3. */
  765. for (i = 0; i &lt; sizeof tokentab3 / sizeof tokentab3[0]; i++)
  766. if (STREQN (tokstart, tokentab3[i].operator, 3))
  767. {
  768. lexptr += 3;
  769. yylval.opcode = tokentab3[i].opcode;
  770. return tokentab3[i].token;
  771. }
  772. /* See if it is a special token of length 2. */
  773. for (i = 0; i &lt; sizeof tokentab2 / sizeof tokentab2[0]; i++)
  774. if (STREQN (tokstart, tokentab2[i].operator, 2))
  775. {
  776. lexptr += 2;
  777. yylval.opcode = tokentab2[i].opcode;
  778. return tokentab2[i].token;
  779. }
  780. switch (c = *tokstart)
  781. {
  782. case 0:
  783. return 0;
  784. case ' ':
  785. case '\t':
  786. case '\n':
  787. lexptr++;
  788. goto retry;
  789. case '\'':
  790. /* We either have a character constant ('0' or '\177' for example)
  791. or we have a quoted symbol reference ('foo(int,int)' in C++
  792. for example). */
  793. lexptr++;
  794. c = *lexptr++;
  795. if (c == '\\')
  796. c = parse_escape (&amp;lexptr);
  797. else if (c == '\'')
  798. error (&quot;Empty character constant.&quot;);
  799. yylval.typed_val_int.val = c;
  800. yylval.typed_val_int.type = java_char_type;
  801. c = *lexptr++;
  802. if (c != '\'')
  803. {
  804. namelen = skip_quoted (tokstart, gdb_completer_word_break_characters)
  805. - tokstart;
  806. if (namelen &gt; 2)
  807. {
  808. lexptr = tokstart + namelen;
  809. if (lexptr[-1] != '\'')
  810. error (&quot;Unmatched single quote.&quot;);
  811. namelen -= 2;
  812. tokstart++;
  813. goto tryname;
  814. }
  815. error (&quot;Invalid character constant.&quot;);
  816. }
  817. return INTEGER_LITERAL;
  818. case '(':
  819. paren_depth++;
  820. lexptr++;
  821. return c;
  822. case ')':
  823. if (paren_depth == 0)
  824. return 0;
  825. paren_depth--;
  826. lexptr++;
  827. return c;
  828. case ',':
  829. if (comma_terminates &amp;&amp; paren_depth == 0)
  830. return 0;
  831. lexptr++;
  832. return c;
  833. case '.':
  834. /* Might be a floating point number. */
  835. if (lexptr[1] &lt; '0' || lexptr[1] &gt; '9')
  836. goto symbol; /* Nope, must be a symbol. */
  837. /* FALL THRU into number case. */
  838. case '0':
  839. case '1':
  840. case '2':
  841. case '3':
  842. case '4':
  843. case '5':
  844. case '6':
  845. case '7':
  846. case '8':
  847. case '9':
  848. {
  849. /* It's a number. */
  850. int got_dot = 0, got_e = 0, toktype;
  851. register char *p = tokstart;
  852. int hex = input_radix &gt; 10;
  853. if (c == '0' &amp;&amp; (p[1] == 'x' || p[1] == 'X'))
  854. {
  855. p += 2;
  856. hex = 1;
  857. }
  858. else if (c == '0' &amp;&amp; (p[1]=='t' || p[1]=='T' || p[1]=='d' || p[1]=='D'))
  859. {
  860. p += 2;
  861. hex = 0;
  862. }
  863. for (;; ++p)
  864. {
  865. /* This test includes !hex because 'e' is a valid hex digit
  866. and thus does not indicate a floating point number when
  867. the radix is hex. */
  868. if (!hex &amp;&amp; !got_e &amp;&amp; (*p == 'e' || *p == 'E'))
  869. got_dot = got_e = 1;
  870. /* This test does not include !hex, because a '.' always indicates
  871. a decimal floating point number regardless of the radix. */
  872. else if (!got_dot &amp;&amp; *p == '.')
  873. got_dot = 1;
  874. else if (got_e &amp;&amp; (p[-1] == 'e' || p[-1] == 'E')
  875. &amp;&amp; (*p == '-' || *p == '+'))
  876. /* This is the sign of the exponent, not the end of the
  877. number. */
  878. continue;
  879. /* We will take any letters or digits. parse_number will
  880. complain if past the radix, or if L or U are not final. */
  881. else if ((*p &lt; '0' || *p &gt; '9')
  882. &amp;&amp; ((*p &lt; 'a' || *p &gt; 'z')
  883. &amp;&amp; (*p &lt; 'A' || *p &gt; 'Z')))
  884. break;
  885. }
  886. toktype = parse_number (tokstart, p - tokstart, got_dot|got_e, &amp;yylval);
  887. if (toktype == ERROR)
  888. {
  889. char *err_copy = (char *) alloca (p - tokstart + 1);
  890. memcpy (err_copy, tokstart, p - tokstart);
  891. err_copy[p - tokstart] = 0;
  892. error (&quot;Invalid number \&quot;%s\&quot;.&quot;, err_copy);
  893. }
  894. lexptr = p;
  895. return toktype;
  896. }
  897. case '+':
  898. case '-':
  899. case '*':
  900. case '/':
  901. case '%':
  902. case '|':
  903. case '&amp;':
  904. case '^':
  905. case '~':
  906. case '!':
  907. case '&lt;':
  908. case '&gt;':
  909. case '[':
  910. case ']':
  911. case '?':
  912. case ':':
  913. case '=':
  914. case '{':
  915. case '}':
  916. symbol:
  917. lexptr++;
  918. return c;
  919. case '&quot;':
  920. /* Build the gdb internal form of the input string in tempbuf,
  921. translating any standard C escape forms seen. Note that the
  922. buffer is null byte terminated *only* for the convenience of
  923. debugging gdb itself and printing the buffer contents when
  924. the buffer contains no embedded nulls. Gdb does not depend
  925. upon the buffer being null byte terminated, it uses the length
  926. string instead. This allows gdb to handle C strings (as well
  927. as strings in other languages) with embedded null bytes */
  928. tokptr = ++tokstart;
  929. tempbufindex = 0;
  930. do {
  931. /* Grow the static temp buffer if necessary, including allocating
  932. the first one on demand. */
  933. if (tempbufindex + 1 &gt;= tempbufsize)
  934. {
  935. tempbuf = (char *) realloc (tempbuf, tempbufsize += 64);
  936. }
  937. switch (*tokptr)
  938. {
  939. case '\0':
  940. case '&quot;':
  941. /* Do nothing, loop will terminate. */
  942. break;
  943. case '\\':
  944. tokptr++;
  945. c = parse_escape (&amp;tokptr);
  946. if (c == -1)
  947. {
  948. continue;
  949. }
  950. tempbuf[tempbufindex++] = c;
  951. break;
  952. default:
  953. tempbuf[tempbufindex++] = *tokptr++;
  954. break;
  955. }
  956. } while ((*tokptr != '&quot;') &amp;&amp; (*tokptr != '\0'));
  957. if (*tokptr++ != '&quot;')
  958. {
  959. error (&quot;Unterminated string in expression.&quot;);
  960. }
  961. tempbuf[tempbufindex] = '\0'; /* See note above */
  962. yylval.sval.ptr = tempbuf;
  963. yylval.sval.length = tempbufindex;
  964. lexptr = tokptr;
  965. return (STRING_LITERAL);
  966. }
  967. if (!(c == '_' || c == '$'
  968. || (c &gt;= 'a' &amp;&amp; c &lt;= 'z') || (c &gt;= 'A' &amp;&amp; c &lt;= 'Z')))
  969. /* We must have come across a bad character (e.g. ';'). */
  970. error (&quot;Invalid character '%c' in expression.&quot;, c);
  971. /* It's a name. See how long it is. */
  972. namelen = 0;
  973. for (c = tokstart[namelen];
  974. (c == '_'
  975. || c == '$'
  976. || (c &gt;= '0' &amp;&amp; c &lt;= '9')
  977. || (c &gt;= 'a' &amp;&amp; c &lt;= 'z')
  978. || (c &gt;= 'A' &amp;&amp; c &lt;= 'Z')
  979. || c == '&lt;');
  980. )
  981. {
  982. if (c == '&lt;')
  983. {
  984. int i = namelen;
  985. while (tokstart[++i] &amp;&amp; tokstart[i] != '&gt;');
  986. if (tokstart[i] == '&gt;')
  987. namelen = i;
  988. }
  989. c = tokstart[++namelen];
  990. }
  991. /* The token &quot;if&quot; terminates the expression and is NOT
  992. removed from the input stream. */
  993. if (namelen == 2 &amp;&amp; tokstart[0] == 'i' &amp;&amp; tokstart[1] == 'f')
  994. {
  995. return 0;
  996. }
  997. lexptr += namelen;
  998. tryname:
  999. /* Catch specific keywords. Should be done with a data structure. */
  1000. switch (namelen)
  1001. {
  1002. case 7:
  1003. if (STREQN (tokstart, &quot;boolean&quot;, 7))
  1004. return BOOLEAN;
  1005. break;
  1006. case 6:
  1007. if (STREQN (tokstart, &quot;double&quot;, 6))
  1008. return DOUBLE;
  1009. break;
  1010. case 5:
  1011. if (STREQN (tokstart, &quot;short&quot;, 5))
  1012. return SHORT;
  1013. if (STREQN (tokstart, &quot;false&quot;, 5))
  1014. {
  1015. yylval.lval = 0;
  1016. return BOOLEAN_LITERAL;
  1017. }
  1018. if (STREQN (tokstart, &quot;super&quot;, 5))
  1019. return SUPER;
  1020. if (STREQN (tokstart, &quot;float&quot;, 5))
  1021. return FLOAT;
  1022. break;
  1023. case 4:
  1024. if (STREQN (tokstart, &quot;long&quot;, 4))
  1025. return LONG;
  1026. if (STREQN (tokstart, &quot;byte&quot;, 4))
  1027. return BYTE;
  1028. if (STREQN (tokstart, &quot;char&quot;, 4))
  1029. return CHAR;
  1030. if (STREQN (tokstart, &quot;true&quot;, 4))
  1031. {
  1032. yylval.lval = 1;
  1033. return BOOLEAN_LITERAL;
  1034. }
  1035. if (current_language-&gt;la_language == language_cplus
  1036. &amp;&amp; STREQN (tokstart, &quot;this&quot;, 4))
  1037. {
  1038. static const char this_name[] =
  1039. { CPLUS_MARKER, 't', 'h', 'i', 's', '\0' };
  1040. if (lookup_symbol (this_name, expression_context_block,
  1041. VAR_NAMESPACE, (int *) NULL,
  1042. (struct symtab **) NULL))
  1043. return THIS;
  1044. }
  1045. break;
  1046. case 3:
  1047. if (STREQN (tokstart, &quot;int&quot;, 3))
  1048. return INT;
  1049. if (STREQN (tokstart, &quot;new&quot;, 3))
  1050. return NEW;
  1051. break;
  1052. default:
  1053. break;
  1054. }
  1055. yylval.sval.ptr = tokstart;
  1056. yylval.sval.length = namelen;
  1057. if (*tokstart == '$')
  1058. {
  1059. write_dollar_variable (yylval.sval);
  1060. return VARIABLE;
  1061. }
  1062. /* Input names that aren't symbols but ARE valid hex numbers,
  1063. when the input radix permits them, can be names or numbers
  1064. depending on the parse. Note we support radixes &gt; 16 here. */
  1065. if (((tokstart[0] &gt;= 'a' &amp;&amp; tokstart[0] &lt; 'a' + input_radix - 10) ||
  1066. (tokstart[0] &gt;= 'A' &amp;&amp; tokstart[0] &lt; 'A' + input_radix - 10)))
  1067. {
  1068. YYSTYPE newlval; /* Its value is ignored. */
  1069. int hextype = parse_number (tokstart, namelen, 0, &amp;newlval);
  1070. if (hextype == INTEGER_LITERAL)
  1071. return NAME_OR_INT;
  1072. }
  1073. return IDENTIFIER;
  1074. }
  1075. void
  1076. yyerror (msg)
  1077. char *msg;
  1078. {
  1079. error (&quot;A %s in expression, near `%s'.&quot;, (msg ? msg : &quot;error&quot;), lexptr);
  1080. }
  1081. static struct type *
  1082. java_type_from_name (name)
  1083. struct stoken name;
  1084. {
  1085. char *tmp = copy_name (name);
  1086. struct type *typ = java_lookup_class (tmp);
  1087. if (typ == NULL || TYPE_CODE (typ) != TYPE_CODE_STRUCT)
  1088. error (&quot;No class named %s.&quot;, tmp);
  1089. return typ;
  1090. }
  1091. /* If NAME is a valid variable name in this scope, push it and return 1.
  1092. Otherwise, return 0. */
  1093. static int
  1094. push_variable (name)
  1095. struct stoken name;
  1096. {
  1097. char *tmp = copy_name (name);
  1098. int is_a_field_of_this = 0;
  1099. struct symbol *sym;
  1100. sym = lookup_symbol (tmp, expression_context_block, VAR_NAMESPACE,
  1101. &amp;is_a_field_of_this, (struct symtab **) NULL);
  1102. if (sym &amp;&amp; SYMBOL_CLASS (sym) != LOC_TYPEDEF)
  1103. {
  1104. if (symbol_read_needs_frame (sym))
  1105. {
  1106. if (innermost_block == 0 ||
  1107. contained_in (block_found, innermost_block))
  1108. innermost_block = block_found;
  1109. }
  1110. write_exp_elt_opcode (OP_VAR_VALUE);
  1111. /* We want to use the selected frame, not another more inner frame
  1112. which happens to be in the same block. */
  1113. write_exp_elt_block (NULL);
  1114. write_exp_elt_sym (sym);
  1115. write_exp_elt_opcode (OP_VAR_VALUE);
  1116. return 1;
  1117. }
  1118. if (is_a_field_of_this)
  1119. {
  1120. /* it hangs off of `this'. Must not inadvertently convert from a
  1121. method call to data ref. */
  1122. if (innermost_block == 0 ||
  1123. contained_in (block_found, innermost_block))
  1124. innermost_block = block_found;
  1125. write_exp_elt_opcode (OP_THIS);
  1126. write_exp_elt_opcode (OP_THIS);
  1127. write_exp_elt_opcode (STRUCTOP_PTR);
  1128. write_exp_string (name);
  1129. write_exp_elt_opcode (STRUCTOP_PTR);
  1130. return 1;
  1131. }
  1132. return 0;
  1133. }
  1134. /* Assuming a reference expression has been pushed, emit the
  1135. STRUCTOP_STRUCT ops to access the field named NAME. If NAME is a
  1136. qualified name (has '.'), generate a field access for each part. */
  1137. static void
  1138. push_fieldnames (name)
  1139. struct stoken name;
  1140. {
  1141. int i;
  1142. struct stoken token;
  1143. token.ptr = name.ptr;
  1144. for (i = 0; ; i++)
  1145. {
  1146. if (i == name.length || name.ptr[i] == '.')
  1147. {
  1148. /* token.ptr is start of current field name. */
  1149. token.length = &amp;name.ptr[i] - token.ptr;
  1150. write_exp_elt_opcode (STRUCTOP_STRUCT);
  1151. write_exp_string (token);
  1152. write_exp_elt_opcode (STRUCTOP_STRUCT);
  1153. token.ptr += token.length + 1;
  1154. }
  1155. if (i &gt;= name.length)
  1156. break;
  1157. }
  1158. }
  1159. /* Helper routine for push_expression_name.
  1160. Handle a qualified name, where DOT_INDEX is the index of the first '.' */
  1161. static void
  1162. push_qualified_expression_name (name, dot_index)
  1163. struct stoken name;
  1164. int dot_index;
  1165. {
  1166. struct stoken token;
  1167. char *tmp;
  1168. struct type *typ;
  1169. token.ptr = name.ptr;
  1170. token.length = dot_index;
  1171. if (push_variable (token))
  1172. {
  1173. token.ptr = name.ptr + dot_index + 1;
  1174. token.length = name.length - dot_index - 1;
  1175. push_fieldnames (token);
  1176. return;
  1177. }
  1178. token.ptr = name.ptr;
  1179. for (;;)
  1180. {
  1181. token.length = dot_index;
  1182. tmp = copy_name (token);
  1183. typ = java_lookup_class (tmp);
  1184. if (typ != NULL)
  1185. {
  1186. if (dot_index == name.length)
  1187. {
  1188. write_exp_elt_opcode(OP_TYPE);
  1189. write_exp_elt_type(typ);
  1190. write_exp_elt_opcode(OP_TYPE);
  1191. return;
  1192. }
  1193. dot_index++; /* Skip '.' */
  1194. name.ptr += dot_index;
  1195. name.length -= dot_index;
  1196. dot_index = 0;
  1197. while (dot_index &lt; name.length &amp;&amp; name.ptr[dot_index] != '.')
  1198. dot_index++;
  1199. token.ptr = name.ptr;
  1200. token.length = dot_index;
  1201. write_exp_elt_opcode (OP_SCOPE);
  1202. write_exp_elt_type (typ);
  1203. write_exp_string (token);
  1204. write_exp_elt_opcode (OP_SCOPE);
  1205. if (dot_index &lt; name.length)
  1206. {
  1207. dot_index++;
  1208. name.ptr += dot_index;
  1209. name.length -= dot_index;
  1210. push_fieldnames (name);
  1211. }
  1212. return;
  1213. }
  1214. else if (dot_index &gt;= name.length)
  1215. break;
  1216. dot_index++; /* Skip '.' */
  1217. while (dot_index &lt; name.length &amp;&amp; name.ptr[dot_index] != '.')
  1218. dot_index++;
  1219. }
  1220. error (&quot;unknown type `%.*s'&quot;, name.length, name.ptr);
  1221. }
  1222. /* Handle Name in an expression (or LHS).
  1223. Handle VAR, TYPE, TYPE.FIELD1....FIELDN and VAR.FIELD1....FIELDN. */
  1224. static void
  1225. push_expression_name (name)
  1226. struct stoken name;
  1227. {
  1228. char *tmp;
  1229. struct type *typ;
  1230. char *ptr;
  1231. int i;
  1232. for (i = 0; i &lt; name.length; i++)
  1233. {
  1234. if (name.ptr[i] == '.')
  1235. {
  1236. /* It's a Qualified Expression Name. */
  1237. push_qualified_expression_name (name, i);
  1238. return;
  1239. }
  1240. }
  1241. /* It's a Simple Expression Name. */
  1242. if (push_variable (name))
  1243. return;
  1244. tmp = copy_name (name);
  1245. typ = java_lookup_class (tmp);
  1246. if (typ != NULL)
  1247. {
  1248. write_exp_elt_opcode(OP_TYPE);
  1249. write_exp_elt_type(typ);
  1250. write_exp_elt_opcode(OP_TYPE);
  1251. }
  1252. else
  1253. {
  1254. struct minimal_symbol *msymbol;
  1255. msymbol = lookup_minimal_symbol (tmp, NULL, NULL);
  1256. if (msymbol != NULL)
  1257. {
  1258. write_exp_msymbol (msymbol,
  1259. lookup_function_type (builtin_type_int),
  1260. builtin_type_int);
  1261. }
  1262. else if (!have_full_symbols () &amp;&amp; !have_partial_symbols ())
  1263. error (&quot;No symbol table is loaded. Use the \&quot;file\&quot; command.&quot;);
  1264. else
  1265. error (&quot;No symbol \&quot;%s\&quot; in current context.&quot;, tmp);
  1266. }
  1267. }
  1268. /* The following two routines, copy_exp and insert_exp, aren't specific to
  1269. Java, so they could go in parse.c, but their only purpose is to support
  1270. the parsing kludges we use in this file, so maybe it's best to isolate
  1271. them here. */
  1272. /* Copy the expression whose last element is at index ENDPOS - 1 in EXPR
  1273. into a freshly malloc'ed struct expression. Its language_defn is set
  1274. to null. */
  1275. static struct expression *
  1276. copy_exp (expr, endpos)
  1277. struct expression *expr;
  1278. int endpos;
  1279. {
  1280. int len = length_of_subexp (expr, endpos);
  1281. struct expression *new
  1282. = (struct expression *) malloc (sizeof (*new) + EXP_ELEM_TO_BYTES (len));
  1283. new-&gt;nelts = len;
  1284. memcpy (new-&gt;elts, expr-&gt;elts + endpos - len, EXP_ELEM_TO_BYTES (len));
  1285. new-&gt;language_defn = 0;
  1286. return new;
  1287. }
  1288. /* Insert the expression NEW into the current expression (expout) at POS. */
  1289. static void
  1290. insert_exp (pos, new)
  1291. int pos;
  1292. struct expression *new;
  1293. {
  1294. int newlen = new-&gt;nelts;
  1295. /* Grow expout if necessary. In this function's only use at present,
  1296. this should never be necessary. */
  1297. if (expout_ptr + newlen &gt; expout_size)
  1298. {
  1299. expout_size = max (expout_size * 2, expout_ptr + newlen + 10);
  1300. expout = (struct expression *)
  1301. realloc ((char *) expout, (sizeof (struct expression)
  1302. + EXP_ELEM_TO_BYTES (expout_size)));
  1303. }
  1304. {
  1305. int i;
  1306. for (i = expout_ptr - 1; i &gt;= pos; i--)
  1307. expout-&gt;elts[i + newlen] = expout-&gt;elts[i];
  1308. }
  1309. memcpy (expout-&gt;elts + pos, new-&gt;elts, EXP_ELEM_TO_BYTES (newlen));
  1310. expout_ptr += newlen;
  1311. }
  1312. </pre>
  1313. <hr />
  1314. </body></html>