parse.y 42 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717
  1. /* YACC parser for C syntax.
  2. Copyright (C) 1987 Free Software Foundation, Inc.
  3. This file is part of GNU CC.
  4. GNU CC is distributed in the hope that it will be useful,
  5. but WITHOUT ANY WARRANTY. No author or distributor
  6. accepts responsibility to anyone for the consequences of using it
  7. or for whether it serves any particular purpose or works at all,
  8. unless he says so in writing. Refer to the GNU CC General Public
  9. License for full details.
  10. Everyone is granted permission to copy, modify and redistribute
  11. GNU CC, but only under the conditions described in the
  12. GNU CC General Public License. A copy of this license is
  13. supposed to have been given to you along with GNU CC so you
  14. can know your rights and responsibilities. It should be in a
  15. file named COPYING. Among other things, the copyright notice
  16. and this notice must be preserved on all copies. */
  17. /* To whomever it may concern: I have heard that such a thing was once
  18. written by AT&T, but I have never seen it. */
  19. %{
  20. #include "config.h"
  21. #include "tree.h"
  22. #include "parse.h"
  23. #include "c-tree.h"
  24. %}
  25. %start program
  26. %union {long itype; tree ttype; enum tree_code code}
  27. /* all identifiers that are not reserved words
  28. and are not declared typedefs in the current block */
  29. %token IDENTIFIER
  30. /* all identifiers that are declared typedefs in the current block.
  31. In some contexts, they are treated just like IDENTIFIER,
  32. but they can also serve as typespecs in declarations. */
  33. %token TYPENAME
  34. /* reserved words that specify storage class.
  35. yylval contains an IDENTIFER_NODE which indicates which one. */
  36. %token SCSPEC
  37. /* reserved words that specify type.
  38. yylval contains an IDENTIFER_NODE which indicates which one. */
  39. %token TYPESPEC
  40. /* reserved words that modify type: "const" or "volatile".
  41. yylval contains an IDENTIFER_NODE which indicates which one. */
  42. %token TYPEMOD
  43. /* character or numeric constants.
  44. yylval is the node for the constant. */
  45. %token CONSTANT
  46. /* String constants in raw form.
  47. yylval is a STRING_CST node. */
  48. %token STRING
  49. /* "...", used for functions with variable arglists. */
  50. %token ELLIPSIS
  51. /* the reserved words */
  52. %token SIZEOF ENUM STRUCT UNION IF ELSE WHILE DO FOR SWITCH CASE DEFAULT
  53. %token BREAK CONTINUE RETURN GOTO ASM
  54. /* Define the operator tokens and their precedences.
  55. The value is an integer because, if used, it is the tree code
  56. to use in the expression made from the operator. */
  57. %right <code> ASSIGN '='
  58. %right <code> '?' ':'
  59. %left <code> OROR
  60. %left <code> ANDAND
  61. %left <code> '|'
  62. %left <code> '^'
  63. %left <code> '&'
  64. %left <code> EQCOMPARE
  65. %left <code> ARITHCOMPARE
  66. %left <code> LSHIFT RSHIFT
  67. %left <code> '+' '-'
  68. %left <code> '*' '/' '%'
  69. %right <code> UNARY PLUSPLUS MINUSMINUS
  70. %left HYPERUNARY
  71. %left <code> POINTSAT '.'
  72. %type <code> unop
  73. %type <ttype> identifier IDENTIFIER TYPENAME CONSTANT expr nonnull_exprlist exprlist
  74. %type <ttype> expr_no_commas primary string STRING
  75. %type <ttype> typed_declspecs scspecs typespecs typespec SCSPEC TYPESPEC TYPEMOD
  76. %type <ttype> initdecls notype_initdecls initdcl notype_initdcl
  77. %type <ttype> init initlist
  78. %type <ttype> declarator
  79. %type <ttype> notype_declarator after_type_declarator
  80. %type <ttype> structsp component_decl_list component_decl components component_declarator
  81. %type <ttype> enumlist enumerator
  82. %type <ttype> typename absdcl absdcl1 typemods
  83. %type <ttype> stmts
  84. %type <ttype> pushlevel compstmt stmt xexpr parmlist parms parm identifiers
  85. %{
  86. /* the declaration found for the last IDENTIFIER token read in.
  87. yylex must look this up to detect typedefs, which get token type TYPENAME,
  88. so it is left around in case the identifier is not a typedef but is
  89. used in a context which makes it a reference to a variable. */
  90. static tree lastiddecl;
  91. tree current_function_decl, current_switch_stmt, current_block;
  92. tree current_continue_label, current_break_label;
  93. tree continue_label_stack, break_label_stack;
  94. static void pushbreak(), popbreak();
  95. static tree finish_compound_stmt();
  96. static tree make_pointer_declarator ();
  97. static tree combine_strings ();
  98. /* list of types and structure classes of the current declaration */
  99. tree current_declspecs;
  100. char *input_filename; /* file being read */
  101. %}
  102. %%
  103. program:
  104. extdefs
  105. ;
  106. /* the reason for the strange actions in this rule
  107. is so that notype_initdecls when reached via datadef
  108. can find a valid list of type and sc specs in $0. */
  109. extdefs:
  110. {$<ttype>$ = NULL_TREE} extdef
  111. | extdefs {$<ttype>$ = NULL_TREE} extdef
  112. ;
  113. extdef:
  114. fndef
  115. | datadef
  116. | ASM '(' STRING ')' ';'
  117. { assemble_asm ($3); }
  118. ;
  119. datadef:
  120. setspecs notype_initdecls ';'
  121. | scspecs setspecs notype_initdecls ';'
  122. {}
  123. | typed_declspecs setspecs initdecls ';'
  124. {}
  125. | scspecs ';'
  126. { yyerror ("empty declaration"); }
  127. | typed_declspecs ';'
  128. { shadow_tag ($1); }
  129. | error ';'
  130. | error '}'
  131. | ';'
  132. ;
  133. fndef:
  134. typed_declspecs setspecs declarator
  135. { if (! start_function ($1, $3))
  136. YYFAIL; }
  137. xdecls
  138. { store_parm_decls (); }
  139. compstmt
  140. { finish_function (input_filename, @7.first_line, $7); }
  141. | typed_declspecs setspecs declarator error
  142. { }
  143. | scspecs setspecs notype_declarator
  144. { if (! start_function ($1, $3))
  145. YYFAIL; }
  146. xdecls
  147. { store_parm_decls (); }
  148. compstmt
  149. { finish_function (input_filename, @7.first_line, $7); }
  150. | scspecs setspecs notype_declarator error
  151. { }
  152. | setspecs notype_declarator
  153. { if (! start_function (0, $2))
  154. YYFAIL; }
  155. xdecls
  156. { store_parm_decls (); }
  157. compstmt
  158. { finish_function (input_filename, @6.first_line, $6); }
  159. | setspecs notype_declarator error
  160. ;
  161. identifier:
  162. IDENTIFIER
  163. | TYPENAME
  164. ;
  165. unop: '&'
  166. { $$ = ADDR_EXPR; }
  167. | '-'
  168. { $$ = NEGATE_EXPR; }
  169. | '+'
  170. { $$ = CONVERT_EXPR; }
  171. | PLUSPLUS
  172. { $$ = PREINCREMENT_EXPR; }
  173. | MINUSMINUS
  174. { $$ = PREDECREMENT_EXPR; }
  175. | '~'
  176. { $$ = BIT_NOT_EXPR; }
  177. | '!'
  178. { $$ = TRUTH_NOT_EXPR; }
  179. ;
  180. expr: nonnull_exprlist
  181. { $$ = build_compound_expr($1); }
  182. ;
  183. exprlist:
  184. /* empty */
  185. { $$ = NULL_TREE; }
  186. | nonnull_exprlist
  187. ;
  188. nonnull_exprlist:
  189. expr_no_commas
  190. { $$ = build_tree_list (NULL_TREE, $1); }
  191. | nonnull_exprlist ',' expr_no_commas
  192. { chainon ($1, build_tree_list (NULL_TREE, $3)); }
  193. ;
  194. expr_no_commas:
  195. primary
  196. | '*' expr_no_commas %prec UNARY
  197. { $$ = build_indirect_ref ($2); }
  198. | unop expr_no_commas %prec UNARY
  199. { $$ = build_unary_op ($1, $2, 0); }
  200. | '(' typename ')' expr_no_commas %prec UNARY
  201. { $$ = build_c_cast (groktypename($2), $4); }
  202. | SIZEOF expr_no_commas %prec UNARY
  203. { $$ = c_sizeof (TREE_TYPE ($2)); }
  204. | SIZEOF '(' typename ')' %prec HYPERUNARY
  205. { $$ = c_sizeof (groktypename($3)); }
  206. | expr_no_commas '+' expr_no_commas
  207. { $$ = build_binary_op ($2, $1, $3); }
  208. | expr_no_commas '-' expr_no_commas
  209. { $$ = build_binary_op ($2, $1, $3); }
  210. | expr_no_commas '*' expr_no_commas
  211. { $$ = build_binary_op ($2, $1, $3); }
  212. | expr_no_commas '/' expr_no_commas
  213. { $$ = build_binary_op ($2, $1, $3); }
  214. | expr_no_commas '%' expr_no_commas
  215. { $$ = build_binary_op ($2, $1, $3); }
  216. | expr_no_commas LSHIFT expr_no_commas
  217. { $$ = build_binary_op ($2, $1, $3); }
  218. | expr_no_commas RSHIFT expr_no_commas
  219. { $$ = build_binary_op ($2, $1, $3); }
  220. | expr_no_commas ARITHCOMPARE expr_no_commas
  221. { $$ = build_binary_op ($2, $1, $3); }
  222. | expr_no_commas EQCOMPARE expr_no_commas
  223. { $$ = build_binary_op ($2, $1, $3); }
  224. | expr_no_commas '&' expr_no_commas
  225. { $$ = build_binary_op ($2, $1, $3); }
  226. | expr_no_commas '|' expr_no_commas
  227. { $$ = build_binary_op ($2, $1, $3); }
  228. | expr_no_commas '^' expr_no_commas
  229. { $$ = build_binary_op ($2, $1, $3); }
  230. | expr_no_commas ANDAND expr_no_commas
  231. { $$ = build_binary_op (TRUTH_ANDIF_EXPR, $1, $3); }
  232. | expr_no_commas OROR expr_no_commas
  233. { $$ = build_binary_op (TRUTH_ORIF_EXPR, $1, $3); }
  234. | expr_no_commas '?' expr ':' expr_no_commas
  235. { $$ = build_conditional_expr($1, $3, $5); }
  236. | expr_no_commas '=' expr_no_commas
  237. { $$ = build_modify_expr($1, $3); }
  238. | expr_no_commas ASSIGN expr_no_commas
  239. { register tree tem
  240. = duplicate_reference ($1);
  241. $$ = build_modify_expr(tem, build_binary_op ($2, tem, $3)); }
  242. ;
  243. primary:
  244. IDENTIFIER
  245. { $$ = lastiddecl;
  246. if (!$$)
  247. {
  248. if (yychar == YYEMPTY)
  249. yychar = YYLEX;
  250. if (yychar == '(')
  251. $$ = implicitly_declare($1);
  252. else
  253. {
  254. yyerror("variable %s used but not declared",
  255. IDENTIFIER_POINTER ($1));
  256. $$ = error_mark_node;
  257. }
  258. }
  259. if (TREE_CODE ($$) == CONST_DECL)
  260. $$ = DECL_INITIAL ($$);
  261. }
  262. | CONSTANT
  263. | string
  264. { $$ = combine_strings ($1); }
  265. | '(' expr ')'
  266. { $$ = $2; }
  267. | '(' error ')'
  268. { $$ = error_mark_node; }
  269. | primary '(' exprlist ')' %prec '.'
  270. { $$ = build_function_call ($1, $3); }
  271. | primary '[' expr ']' %prec '.'
  272. { $$ = build_array_ref ($1, $3); }
  273. | primary '.' identifier
  274. { $$ = build_component_ref($1, $3); }
  275. | primary POINTSAT identifier
  276. { $$ = build_component_ref(build_indirect_ref ($1), $3); }
  277. | primary PLUSPLUS
  278. { $$ = build_unary_op (POSTINCREMENT_EXPR, $1, 0); }
  279. | primary MINUSMINUS
  280. { $$ = build_unary_op (POSTDECREMENT_EXPR, $1, 0); }
  281. ;
  282. /* Produces a STRING_CST with perhaps more STRING_CSTs chained onto it. */
  283. string:
  284. STRING
  285. | string STRING
  286. { $$ = chainon ($1, $2); }
  287. ;
  288. xdecls:
  289. /* empty */
  290. | decls
  291. ;
  292. decls:
  293. decl
  294. | errstmt
  295. | decls decl
  296. | decl errstmt
  297. ;
  298. /* records the type and storage class specs to use for processing
  299. the declarators that follow */
  300. setspecs: /* empty */
  301. { current_declspecs = $<ttype>0; }
  302. ;
  303. decl:
  304. typed_declspecs setspecs initdecls ';'
  305. {}
  306. | scspecs setspecs notype_initdecls ';'
  307. {}
  308. | typed_declspecs ';'
  309. { shadow_tag ($1); }
  310. | scspecs ';'
  311. { warning ("empty declaration"); }
  312. ;
  313. /* declspecs which contain at least one type specifier.
  314. A typedef'd name following these is taken as a name to be declared. */
  315. typed_declspecs:
  316. typespec
  317. { $$ = build_tree_list (NULL_TREE, $1); }
  318. | scspecs typespec
  319. { $$ = tree_cons (NULL_TREE, $2, $1); }
  320. | typed_declspecs TYPESPEC
  321. { $$ = tree_cons (NULL_TREE, $2, $1); }
  322. | typed_declspecs TYPEMOD
  323. { $$ = tree_cons (NULL_TREE, $2, $1); }
  324. | typed_declspecs structsp
  325. { $$ = tree_cons (NULL_TREE, $2, $1); }
  326. | typed_declspecs SCSPEC
  327. { $$ = tree_cons (NULL_TREE, $2, $1); }
  328. ;
  329. /* declspecs which contain no type specifiers.
  330. The identifier to which they apply must not be a typedef'd name. */
  331. scspecs: SCSPEC
  332. { $$ = build_tree_list (NULL_TREE, $1); }
  333. | scspecs SCSPEC
  334. { $$ = tree_cons (NULL_TREE, $2, $1); }
  335. ;
  336. /* used instead of declspecs where storage classes are not allowed
  337. (typenames, structure components, and parameters) */
  338. typespecs:
  339. typespec
  340. { $$ = build_tree_list (NULL_TREE, $1); }
  341. | typespecs TYPESPEC
  342. { $$ = tree_cons (NULL_TREE, $2, $1); }
  343. | typespecs TYPEMOD
  344. { $$ = tree_cons (NULL_TREE, $2, $1); }
  345. | typespecs structsp
  346. { $$ = tree_cons (NULL_TREE, $2, $1); }
  347. ;
  348. typespec: TYPESPEC
  349. | TYPEMOD
  350. | structsp
  351. | TYPENAME
  352. ;
  353. initdecls:
  354. initdcl
  355. | initdecls ',' initdcl
  356. ;
  357. notype_initdecls:
  358. notype_initdcl
  359. | notype_initdecls ',' initdcl
  360. ;
  361. initdcl:
  362. declarator '='
  363. { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  364. init
  365. /* Note how the declaration of the variable is in effect while its init is parsed! */
  366. { finish_decl (input_filename, @1.first_line, $<ttype>3, $4); }
  367. | declarator
  368. { tree d = start_decl ($1, current_declspecs, 0);
  369. finish_decl (input_filename, @1.first_line, d, NULL_TREE); }
  370. ;
  371. notype_initdcl:
  372. notype_declarator '='
  373. { $<ttype>$ = start_decl ($1, current_declspecs, 1); }
  374. init
  375. /* Note how the declaration of the variable is in effect while its init is parsed! */
  376. { finish_decl (input_filename, @1.first_line, $<ttype>3, $4); }
  377. | notype_declarator
  378. { tree d = start_decl ($1, current_declspecs, 0);
  379. finish_decl (input_filename, @1.first_line, d, NULL_TREE); }
  380. ;
  381. init:
  382. expr_no_commas
  383. | '{' initlist '}'
  384. { $$ = build1 (CONSTRUCTOR, nreverse ($2)); }
  385. | '{' initlist ',' '}'
  386. { $$ = build1 (CONSTRUCTOR, nreverse ($2)); }
  387. ;
  388. /* This chain is built in reverse order,
  389. and put in forward order where initlist is used. */
  390. initlist:
  391. init
  392. { $$ = build_tree_list (NULL_TREE, $1); }
  393. | initlist ',' init
  394. { $$ = tree_cons (NULL, $3, $1); }
  395. ;
  396. /* Any kind of declarator (thus, all declarators allowed
  397. after an explicit typespec). */
  398. declarator:
  399. after_type_declarator
  400. | notype_declarator
  401. ;
  402. /* A declarator that is allowed only after an explicit typespec. */
  403. after_type_declarator:
  404. after_type_declarator '(' parmlist ')' %prec '.'
  405. { $$ = build2 (CALL_EXPR, $1, $3); }
  406. | after_type_declarator '(' identifiers ')' %prec '.'
  407. { $$ = build2 (CALL_EXPR, $1, $3); }
  408. | after_type_declarator '(' error ')' %prec '.'
  409. { $$ = build2 (CALL_EXPR, $1, NULL_TREE); }
  410. | after_type_declarator '[' expr ']' %prec '.'
  411. { $$ = build2 (ARRAY_REF, $1, $3); }
  412. | after_type_declarator '[' ']' %prec '.'
  413. { $$ = build2 (ARRAY_REF, $1, NULL_TREE); }
  414. | TYPENAME
  415. ;
  416. /* A declarator allowed whether or not there has been
  417. an explicit typespec. These cannot redeclare a typedef-name. */
  418. notype_declarator:
  419. notype_declarator '(' parmlist ')' %prec '.'
  420. { $$ = build2 (CALL_EXPR, $1, $3); }
  421. | notype_declarator '(' identifiers ')' %prec '.'
  422. { $$ = build2 (CALL_EXPR, $1, $3); }
  423. | notype_declarator '(' error ')' %prec '.'
  424. { $$ = build2 (CALL_EXPR, $1, NULL_TREE); }
  425. | '(' notype_declarator ')'
  426. { $$ = $2; }
  427. | '*' typemods notype_declarator %prec UNARY
  428. { $$ = make_pointer_declarator ($2, $3); }
  429. | notype_declarator '[' expr ']' %prec '.'
  430. { $$ = build2 (ARRAY_REF, $1, $3); }
  431. | notype_declarator '[' ']' %prec '.'
  432. { $$ = build2 (ARRAY_REF, $1, NULL_TREE); }
  433. | IDENTIFIER
  434. ;
  435. structsp:
  436. STRUCT identifier '{' component_decl_list '}'
  437. { $$ = build_struct (RECORD_TYPE, input_filename, @1.first_line, $2, $4, 0); }
  438. | STRUCT '{' component_decl_list '}'
  439. { $$ = build_struct (RECORD_TYPE, input_filename, @1.first_line, NULL_TREE, $3, 0); }
  440. | STRUCT identifier
  441. { $$ = build_struct (RECORD_TYPE, input_filename, @1.first_line, $2, NULL_TREE, 1); }
  442. | UNION identifier '{' component_decl_list '}'
  443. { $$ = build_struct (UNION_TYPE, input_filename, @1.first_line, $2, $4, 0); }
  444. | UNION '{' component_decl_list '}'
  445. { $$ = build_struct (UNION_TYPE, input_filename, @1.first_line, NULL_TREE, $3, 0); }
  446. | UNION identifier
  447. { $$ = build_struct (UNION_TYPE, input_filename, @1.first_line, $2, NULL_TREE, 1); }
  448. | ENUM identifier '{'
  449. { $$ = start_enum ($2); }
  450. enumlist '}'
  451. { $$ = finish_enum ($<ttype>4, nreverse ($5)); }
  452. | ENUM '{'
  453. { $$ = start_enum (NULL_TREE); }
  454. enumlist '}'
  455. { $$ = finish_enum ($<ttype>3, nreverse ($4)); }
  456. | ENUM identifier
  457. { $$ = xref_enum ($2); }
  458. ;
  459. component_decl_list: /* empty */
  460. { $$ = NULL_TREE; }
  461. | component_decl
  462. | component_decl_list ';' component_decl
  463. { $$ = chainon ($1, $3); }
  464. | component_decl_list ';'
  465. ;
  466. component_decl:
  467. typespecs setspecs components
  468. { $$ = $3; }
  469. | error
  470. { $$ == NULL_TREE; }
  471. ;
  472. components:
  473. /* empty */
  474. { $$ = NULL_TREE; }
  475. | component_declarator
  476. | components ',' component_declarator
  477. { $$ = chainon ($1, $3); }
  478. ;
  479. component_declarator:
  480. declarator
  481. { $$ = grokfield (input_filename, @1.first_line, $1, current_declspecs, NULL_TREE); }
  482. | declarator ':' expr_no_commas
  483. { $$ = grokfield (input_filename, @1.first_line, $1, current_declspecs, $3); }
  484. | ':' expr_no_commas
  485. { $$ = grokfield (input_filename, @1.first_line, NULL_TREE, current_declspecs, $2); }
  486. ;
  487. /* We chain the enumerators in reverse order.
  488. They are put in forward order where enumlist is used.
  489. (The order used to be significant, but no longer is so.
  490. However, we still maintain the order, just to be clean.) */
  491. enumlist:
  492. enumerator
  493. | enumlist ',' enumerator
  494. { $$ = chainon ($3, $1); }
  495. | enumlist ','
  496. ;
  497. enumerator:
  498. identifier
  499. { $$ = build_enumerator ($1, NULL_TREE); }
  500. | identifier '=' expr_no_commas
  501. { $$ = build_enumerator ($1, $3); }
  502. ;
  503. typename:
  504. typespecs absdcl
  505. { $$ = build_tree_list ($1, $2); }
  506. ;
  507. absdcl: /* an absolute declarator */
  508. /* empty */
  509. { $$ = NULL_TREE; }
  510. | absdcl1
  511. ;
  512. typemods:
  513. /* empty */
  514. { $$ = NULL_TREE; }
  515. | typemods TYPEMOD
  516. { $$ = tree_cons (NULL_TREE, $2, $1); }
  517. ;
  518. absdcl1: /* a nonempty absolute declarator */
  519. '(' absdcl1 ')'
  520. { $$ = $2; }
  521. | '*' typemods absdcl1 %prec UNARY
  522. { $$ = make_pointer_declarator ($2, $3); }
  523. | '*' typemods %prec UNARY
  524. { $$ = make_pointer_declarator ($2, NULL_TREE); }
  525. | absdcl1 '(' parmlist ')' %prec '.'
  526. { $$ = build2 (CALL_EXPR, $1, $3); }
  527. | absdcl1 '[' expr ']' %prec '.'
  528. { $$ = build2 (ARRAY_REF, $1, $3); }
  529. | absdcl1 '[' ']' %prec '.'
  530. { $$ = build2 (ARRAY_REF, $1, NULL_TREE); }
  531. | '(' parmlist ')' %prec '.'
  532. { $$ = build2 (CALL_EXPR, NULL_TREE, $2); }
  533. | '[' expr ']' %prec '.'
  534. { $$ = build2 (ARRAY_REF, NULL_TREE, $2); }
  535. | '[' ']' %prec '.'
  536. { $$ = build2 (ARRAY_REF, NULL_TREE, NULL_TREE); }
  537. ;
  538. /* at least one statement, the first of which parses without error. */
  539. /* stmts is used only after decls, so an invalid first statement
  540. is actually regarded as an invalid decl and part of the decls. */
  541. /* To speed things up, we actually chain the statements in
  542. reverse order and return them that way.
  543. They are put into forward order where stmts is used. */
  544. stmts:
  545. stmt
  546. | stmts stmt
  547. { $$ = chainon ($2, $1); }
  548. | stmts errstmt
  549. ;
  550. errstmt: error ';'
  551. ;
  552. /* build the LET_STMT node before parsing its contents,
  553. so that any LET_STMTs within the context can have their display pointers
  554. set up to point at this one. */
  555. pushlevel: /* empty */
  556. { pushlevel();
  557. $$ = current_block;
  558. current_block
  559. = build_let (input_filename, 0, 0, 0, $$, 0);
  560. }
  561. ;
  562. compstmt: '{' '}'
  563. { $$ = build_compound (input_filename, @1.first_line, 0); }
  564. | '{' pushlevel decls stmts '}'
  565. { $$ = finish_compound_stmt (current_block, nreverse ($4),
  566. $2, @1.first_line); }
  567. | '{' pushlevel decls '}'
  568. { $$ = finish_compound_stmt (current_block, NULL_TREE,
  569. $2, @1.first_line); }
  570. | '{' pushlevel error '}'
  571. { $$ = error_mark_node;
  572. current_block = $2;
  573. poplevel(); }
  574. | '{' pushlevel stmts '}'
  575. { $$ = finish_compound_stmt (current_block, nreverse ($3), $2,
  576. @1.first_line); }
  577. ;
  578. stmt: compstmt
  579. | expr ';'
  580. { $$ = build_expr_stmt (input_filename, @1.first_line, $1); }
  581. | IF '(' expr ')' stmt
  582. { $$ = build_if (input_filename, @1.first_line, default_conversion ($3), $5, 0); }
  583. | IF '(' expr ')' stmt ELSE stmt
  584. { $$ = build_if (input_filename, @1.first_line, default_conversion ($3), $5, $7); }
  585. | WHILE
  586. { pushbreak(1); }
  587. '(' expr ')' stmt
  588. { $$ = build_loop (input_filename, @1.first_line,
  589. chainon (build_exit (input_filename, @4.first_line,
  590. default_conversion ($4)),
  591. chainon ($6, current_continue_label)));
  592. $$ = build_compound (input_filename, @1.first_line, chainon ($$, current_break_label));
  593. popbreak(1); }
  594. | DO
  595. { pushbreak(1); }
  596. stmt WHILE '(' expr ')' ';'
  597. { $$ = build_loop (input_filename, @1.first_line,
  598. chainon ($3, chainon(current_continue_label,
  599. build_exit (input_filename, @6.first_line,
  600. default_conversion ($6)))));
  601. $$ = build_compound (input_filename, @1.first_line, chainon ($$, current_break_label));
  602. popbreak(1); }
  603. | FOR
  604. { pushbreak(1); }
  605. '(' xexpr ';' xexpr ';' xexpr ')' stmt
  606. { $$ = build_compound (input_filename, @1.first_line,
  607. chainon ($4 ? build_expr_stmt (input_filename, @4.first_line, $4) : NULL_TREE,
  608. build_loop (input_filename, @1.first_line,
  609. chainon ($6 ? build_exit (input_filename, @6.first_line,
  610. default_conversion ($6))
  611. : NULL_TREE,
  612. chainon (chainon ($10, current_continue_label),
  613. $8 ? build_expr_stmt (input_filename, @8.first_line, $8) : NULL_TREE)))));
  614. $$ = build_compound (input_filename, @1.first_line, chainon ($$, current_break_label));
  615. popbreak(1); }
  616. | SWITCH '(' expr ')'
  617. { $<ttype>$ = current_switch_stmt;
  618. pushbreak(0);
  619. current_switch_stmt
  620. = build_switch_stmt (input_filename, @1.first_line,
  621. default_conversion ($3)); }
  622. stmt
  623. { $$ = build_compound (input_filename, @1.first_line,
  624. chainon(current_switch_stmt,
  625. chainon($6, current_break_label)));
  626. finish_switch_stmt (current_switch_stmt, current_break_label);
  627. popbreak (0);
  628. current_switch_stmt = $<ttype>5; }
  629. | CASE expr ':' stmt
  630. { register tree value = fold($2);
  631. tree l = build_label (input_filename, @1.first_line, NULL_TREE, current_block);
  632. if (TREE_CODE (value) != INTEGER_CST)
  633. {
  634. yyerror("case label does not reduce to an integer constant");
  635. value = error_mark_node;
  636. }
  637. pushcase(value, l);
  638. $$ = build_compound (input_filename, @1.first_line, chainon(l, $4));
  639. }
  640. | DEFAULT ':' stmt
  641. {
  642. tree l = build_label (input_filename, @1.first_line, 0, current_block);
  643. pushcase(NULL_TREE, l);
  644. $$ = build_compound (input_filename, @1.first_line, chainon(l, $3));
  645. }
  646. | BREAK ';'
  647. { if (current_break_label)
  648. $$ = build_goto (input_filename, @1.first_line, STMT_BODY (current_break_label));
  649. else
  650. {
  651. yyerror("break statement not within a do, for, while or switch statement");
  652. $$ = error_mark_node;
  653. }
  654. }
  655. | CONTINUE ';'
  656. { if (current_continue_label)
  657. $$ = build_goto (input_filename, @1.first_line, STMT_BODY (current_continue_label));
  658. else
  659. {
  660. yyerror("continue statement not within a do, for or while statement");
  661. $$ = error_mark_node;
  662. }
  663. }
  664. | RETURN ';'
  665. { $$ = build_return (input_filename, @1.first_line, NULL_TREE); }
  666. | RETURN expr ';'
  667. { $$ = build_return_stmt (input_filename, @1.first_line, $2); }
  668. | GOTO identifier ';'
  669. { pushgoto($$ = build_goto (input_filename, @1.first_line, $2)); }
  670. | ASM '(' STRING ')' ';'
  671. { $$ = build_asm_stmt (input_filename, @1.first_line, $3); }
  672. | identifier ':' stmt
  673. { $$ = build_compound (input_filename, @1.first_line, chainon (build_label (input_filename, @1.first_line, $1, current_block), $3)); }
  674. | ';'
  675. { $$ = build_compound (input_filename, @1.first_line, 0); }
  676. ;
  677. xexpr:
  678. /* empty */
  679. { $$ = NULL_TREE; }
  680. | expr
  681. ;
  682. /* This is what appears inside the parens in a function declarator.
  683. Is value is represented in the format that grokdeclarator expects. */
  684. parmlist: /* empty */
  685. { $$ = NULL_TREE; }
  686. | parms
  687. { $$ = chainon ($1, build_tree_list (NULL_TREE,
  688. void_type_node)); }
  689. | parms ',' ELLIPSIS
  690. ;
  691. /* A nonempty list of parameter declarations or type names. */
  692. parms:
  693. parm
  694. { $$ = build_tree_list (NULL_TREE, $1); }
  695. | parms ',' parm
  696. { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
  697. ;
  698. parm:
  699. typespecs declarator
  700. { $$ = build_tree_list ($1, $2) ; }
  701. | typespecs absdcl
  702. { $$ = build_tree_list ($1, $2); }
  703. ;
  704. /* A nonempty list of identifiers. */
  705. identifiers:
  706. IDENTIFIER
  707. { $$ = build_tree_list (NULL_TREE, $1); }
  708. | identifiers ',' IDENTIFIER
  709. { $$ = chainon ($1, build_tree_list (NULL_TREE, $3)); }
  710. ;
  711. %%
  712. static tree
  713. finish_compound_stmt(block, stmts, outer_block, line)
  714. tree block, stmts, outer_block;
  715. int line;
  716. {
  717. register tree decls = getdecls();
  718. register tree tags = gettags ();
  719. if (decls || tags)
  720. {
  721. finish_block (block, decls, tags, stmts);
  722. poplevel();
  723. current_block = outer_block;
  724. STMT_SOURCE_LINE (block) = line;
  725. return block;
  726. }
  727. else
  728. {
  729. current_block = outer_block;
  730. poplevel();
  731. return build_compound (input_filename, line, stmts);
  732. }
  733. }
  734. static void
  735. pushbreak(a)
  736. int a;
  737. {
  738. if (current_break_label)
  739. TREE_CHAIN (current_break_label) = break_label_stack;
  740. break_label_stack = current_break_label;
  741. current_break_label = build_label (0, 0, NULL_TREE, current_block);
  742. if (a)
  743. {
  744. if (current_continue_label)
  745. TREE_CHAIN (current_continue_label) = continue_label_stack;
  746. continue_label_stack = current_continue_label;
  747. current_continue_label = build_label (0, 0, NULL_TREE, current_block);
  748. }
  749. }
  750. static void
  751. popbreak(a)
  752. int a;
  753. {
  754. current_break_label = break_label_stack;
  755. if (current_break_label)
  756. break_label_stack = TREE_CHAIN (break_label_stack);
  757. if (a)
  758. {
  759. current_continue_label = continue_label_stack;
  760. if (current_continue_label)
  761. continue_label_stack = TREE_CHAIN (continue_label_stack);
  762. }
  763. if (current_break_label)
  764. TREE_CHAIN (current_break_label) = NULL;
  765. if (current_continue_label)
  766. TREE_CHAIN (current_continue_label) = NULL;
  767. }
  768. /* Return something to represent absolute declarators containing a *.
  769. TARGET is the absolute declarator that the * contains.
  770. TYPEMODS is a list of modifiers such as const or volatile
  771. to apply to the pointer type, represented as identifiers.
  772. We return an INDIRECT_REF whose "contents" are TARGET
  773. and whose type is the modifier list. */
  774. static tree
  775. make_pointer_declarator (typemods, target)
  776. tree typemods, target;
  777. {
  778. register tree t = build1 (INDIRECT_REF, target);
  779. TREE_TYPE (t) = typemods;
  780. return t;
  781. }
  782. /* Given a chain of STRING_CST nodes,
  783. concatenate them into one STRING_CST
  784. and then return an ADDR_EXPR for it. */
  785. static tree
  786. combine_strings (strings)
  787. tree strings;
  788. {
  789. register tree value, t;
  790. if (TREE_CHAIN (strings))
  791. {
  792. /* More than one in the chain, so concatenate. */
  793. register char *p, *q;
  794. register int length = 1;
  795. /* Don't include the \0 at the end of each substring,
  796. except for the last one. */
  797. for (t = strings; t; t = TREE_CHAIN (t))
  798. length += TREE_STRING_LENGTH (t) - 1;
  799. p = (char *) oballoc (length);
  800. q = p;
  801. for (t = strings; t; t = TREE_CHAIN (t))
  802. {
  803. bcopy (TREE_STRING_POINTER (t), q, TREE_STRING_LENGTH (t) - 1);
  804. q += TREE_STRING_LENGTH (t) - 1;
  805. }
  806. *q = 0;
  807. value = make_node (STRING_CST);
  808. TREE_TYPE (value) = TREE_TYPE (strings);
  809. TREE_STRING_POINTER (value) = p;
  810. TREE_STRING_LENGTH (value) = length;
  811. TREE_LITERAL (value) = 1;
  812. }
  813. else
  814. value = strings;
  815. value = build1 (ADDR_EXPR, value);
  816. TREE_TYPE (value) = string_type_node;
  817. TREE_LITERAL (value) = 1;
  818. return value;
  819. }
  820. int lineno; /* current line number in file being read */
  821. FILE *finput; /* input file.
  822. Normally a pipe from the preprocessor. */
  823. /* lexical analyzer */
  824. static int maxtoken; /* Current length of token buffer */
  825. static char *token_buffer; /* Pointer to token buffer */
  826. /* frw[i] is index in rw of the first word whose length is i. */
  827. #define MAXRESERVED 9
  828. static char frw[10] =
  829. { 0, 0, 0, 2, 5, 13, 19, 27, 29, 33 };
  830. static char *rw[] =
  831. { "if", "do", "int", "for", "asm",
  832. "case", "char", "auto", "goto", "else", "long", "void", "enum",
  833. "float", "short", "union", "break", "while", "const",
  834. "double", "static", "extern", "struct", "return", "sizeof", "switch", "signed",
  835. "typedef", "default",
  836. "unsigned", "continue", "register", "volatile" };
  837. static short rtoken[] =
  838. { IF, DO, TYPESPEC, FOR, ASM,
  839. CASE, TYPESPEC, SCSPEC, GOTO, ELSE, TYPESPEC, TYPESPEC, ENUM,
  840. TYPESPEC, TYPESPEC, UNION, BREAK, WHILE, TYPEMOD,
  841. TYPESPEC, SCSPEC, SCSPEC, STRUCT, RETURN, SIZEOF, SWITCH, TYPESPEC,
  842. SCSPEC, DEFAULT,
  843. TYPESPEC, CONTINUE, SCSPEC, TYPEMOD };
  844. /* This table corresponds to rw and rtoken.
  845. Its element is an index in ridpointers */
  846. #define NORID (enum rid) 0
  847. static enum rid rid[] =
  848. { NORID, NORID, RID_INT, NORID, NORID,
  849. NORID, RID_CHAR, RID_AUTO, NORID, NORID, RID_LONG, RID_VOID, NORID,
  850. RID_FLOAT, RID_SHORT, NORID, NORID, NORID, RID_CONST,
  851. RID_DOUBLE, RID_STATIC, RID_EXTERN, NORID, NORID, NORID, NORID, RID_SIGNED,
  852. RID_TYPEDEF, NORID,
  853. RID_UNSIGNED, NORID, RID_REGISTER, RID_VOLATILE };
  854. /* The elements of `ridpointers' are identifier nodes
  855. for the reserved type names and storage classes. */
  856. tree ridpointers[(int) RID_MAX];
  857. static tree line_identifier; /* The identifier node named "line" */
  858. void check_newline();
  859. void
  860. init_lex()
  861. {
  862. extern char *malloc();
  863. /* Start it at 0, because check_newline is called atthe very beginning
  864. and will increment it to 1. */
  865. lineno = 0;
  866. current_function_decl = NULL;
  867. current_switch_stmt = NULL;
  868. current_block = NULL;
  869. current_break_label = NULL;
  870. current_continue_label = NULL;
  871. break_label_stack = NULL;
  872. continue_label_stack = NULL;
  873. line_identifier = get_identifier("line");
  874. maxtoken = 40;
  875. token_buffer = malloc((unsigned)(maxtoken+1));
  876. ridpointers[(int) RID_INT] = get_identifier("int");
  877. ridpointers[(int) RID_CHAR] = get_identifier("char");
  878. ridpointers[(int) RID_VOID] = get_identifier("void");
  879. ridpointers[(int) RID_FLOAT] = get_identifier("float");
  880. ridpointers[(int) RID_DOUBLE] = get_identifier("double");
  881. ridpointers[(int) RID_SHORT] = get_identifier("short");
  882. ridpointers[(int) RID_LONG] = get_identifier("long");
  883. ridpointers[(int) RID_UNSIGNED] = get_identifier("unsigned");
  884. ridpointers[(int) RID_SIGNED] = get_identifier("signed");
  885. ridpointers[(int) RID_CONST] = get_identifier("const");
  886. ridpointers[(int) RID_VOLATILE] = get_identifier("volatile");
  887. ridpointers[(int) RID_AUTO] = get_identifier("auto");
  888. ridpointers[(int) RID_STATIC] = get_identifier("static");
  889. ridpointers[(int) RID_EXTERN] = get_identifier("extern");
  890. ridpointers[(int) RID_TYPEDEF] = get_identifier("typedef");
  891. ridpointers[(int) RID_REGISTER] = get_identifier("register");
  892. }
  893. static int
  894. skip_white_space()
  895. {
  896. register int c;
  897. register int inside;
  898. c = getc(finput);
  899. for (;;)
  900. {
  901. switch (c)
  902. {
  903. case '/':
  904. c = getc(finput);
  905. if (c != '*')
  906. {
  907. ungetc(c, finput);
  908. return '/';
  909. }
  910. c = getc(finput);
  911. inside = 1;
  912. while (inside)
  913. {
  914. if (c == '*')
  915. {
  916. while (c == '*')
  917. c = getc(finput);
  918. if (c == '/')
  919. {
  920. inside = 0;
  921. c = getc(finput);
  922. }
  923. }
  924. else if (c == '\n')
  925. {
  926. lineno++;
  927. c = getc(finput);
  928. }
  929. else if (c == EOF)
  930. yyerror("unterminated comment");
  931. else
  932. c = getc(finput);
  933. }
  934. break;
  935. case '\n':
  936. check_newline();
  937. case ' ':
  938. case '\t':
  939. case '\f':
  940. case '\r':
  941. case '\b':
  942. c = getc(finput);
  943. break;
  944. case '\\':
  945. c = getc(finput);
  946. if (c == '\n')
  947. lineno++;
  948. else
  949. yyerror("stray '\\' in program");
  950. c = getc(finput);
  951. break;
  952. default:
  953. return (c);
  954. }
  955. }
  956. }
  957. /* make the token buffer longer, preserving the data in it.
  958. p should point to just beyond the last valid character in the old buffer
  959. and the value points to the corresponding place in the new one. */
  960. static char *
  961. extend_token_buffer(p)
  962. char *p;
  963. {
  964. register char *newbuf;
  965. register char *value;
  966. int newlength = maxtoken * 2 + 10;
  967. register char *p2, *p1;
  968. extern char *malloc();
  969. newbuf = malloc((unsigned)(newlength+1));
  970. p2 = newbuf;
  971. p1 = newbuf + newlength + 1;
  972. while (p1 != p2) *p2++ = 0;
  973. value = newbuf;
  974. p2 = token_buffer;
  975. while (p2 != p)
  976. *value++ = *p2++;
  977. token_buffer = newbuf;
  978. maxtoken = newlength;
  979. return (value);
  980. }
  981. /* At the beginning of a line,
  982. increment the line number
  983. and handle a #line directive immediately following */
  984. void
  985. check_newline ()
  986. {
  987. register int c;
  988. register int token;
  989. while (1)
  990. {
  991. c = getc (finput);
  992. lineno++;
  993. if (c != '#')
  994. {
  995. /* If no #, unread the character,
  996. except don't bother if it is whitespace. */
  997. if (c == ' ' || c == '\t')
  998. return;
  999. ungetc (c, finput);
  1000. return;
  1001. }
  1002. /* Skip whitespace after the #. */
  1003. while (1)
  1004. {
  1005. c = getc (finput);
  1006. if (! (c == ' ' || c == '\t'))
  1007. break;
  1008. }
  1009. /* If the # is the only nonwhite char on the line,
  1010. just ignore it. Check the new newline. */
  1011. if (c == '\n')
  1012. continue;
  1013. /* Something follows the #; read a token. */
  1014. ungetc (c, finput);
  1015. token = yylex ();
  1016. if (token == CONSTANT
  1017. && TREE_CODE (yylval.ttype) == INTEGER_CST)
  1018. {
  1019. /* subtract one, because it is the following line that
  1020. gets the specified number */
  1021. int l = TREE_INT_CST_LOW (yylval.ttype) - 1;
  1022. token = yylex ();
  1023. if (token != STRING || TREE_CODE (yylval.ttype) != STRING_CST)
  1024. yyerror ("invalid #line");
  1025. input_filename
  1026. = (char *) permalloc (TREE_STRING_LENGTH (yylval.ttype) + 1);
  1027. strcpy (input_filename, TREE_STRING_POINTER (yylval.ttype));
  1028. lineno = l;
  1029. }
  1030. else
  1031. yyerror ("undefined or invalid # directive");
  1032. /* skip the rest of this line. */
  1033. while ((c = getc (finput)) != '\n');
  1034. }
  1035. }
  1036. #define isalnum(char) ((char >= 'a' && char <= 'z') || (char >= 'A' && char <= 'Z') || (char >= '0' && char <= '9'))
  1037. #define isdigit(char) (char >= '0' && char <= '9')
  1038. #define ENDFILE -1 /* token that represents end-of-file */
  1039. static int
  1040. readescape ()
  1041. {
  1042. register int c = getc (finput);
  1043. register int count, code;
  1044. switch (c)
  1045. {
  1046. case 'x':
  1047. code = 0;
  1048. count = 0;
  1049. while (1)
  1050. {
  1051. c = getc (finput);
  1052. if (!(c >= 'a' && c <= 'f')
  1053. && !(c >= 'A' && c <= 'F')
  1054. && !(c >= '0' && c <= '9'))
  1055. {
  1056. ungetc (c, finput);
  1057. break;
  1058. }
  1059. if (c >= 'a' && c <= 'z')
  1060. c -= 'a' - 'A';
  1061. code *= 16;
  1062. if (c >= 'a' && c <= 'f')
  1063. code += c - 'a' + 10;
  1064. if (c >= 'A' && c <= 'F')
  1065. code += c - 'A' + 10;
  1066. if (c >= '0' && c <= '9')
  1067. code += c - '0';
  1068. count++;
  1069. if (count == 3)
  1070. break;
  1071. }
  1072. if (count == 0)
  1073. yyerror ("\\x used with no following hex digits");
  1074. return code;
  1075. case '0': case '1': case '2': case '3': case '4':
  1076. case '5': case '6': case '7':
  1077. code = 0;
  1078. count = 0;
  1079. while ((c <= '7') && (c >= '0') && (count++ < 3))
  1080. {
  1081. code = (code * 8) + (c - '0');
  1082. c = getc (finput);
  1083. }
  1084. ungetc (c, finput);
  1085. return code;
  1086. case '\\': case '\'': case '"':
  1087. return c;
  1088. case '\n':
  1089. lineno++;
  1090. return -1;
  1091. case 'n':
  1092. return TARGET_NEWLINE;
  1093. case 't':
  1094. return TARGET_TAB;
  1095. case 'r':
  1096. return TARGET_CR;
  1097. case 'f':
  1098. return TARGET_FF;
  1099. case 'b':
  1100. return TARGET_BS;
  1101. case 'a':
  1102. return TARGET_BELL;
  1103. case 'v':
  1104. return TARGET_VT;
  1105. }
  1106. return c;
  1107. }
  1108. static int
  1109. yylex()
  1110. {
  1111. register int c;
  1112. register char *p;
  1113. register int value;
  1114. c = skip_white_space();
  1115. yylloc.first_line = lineno;
  1116. switch (c)
  1117. {
  1118. case EOF:
  1119. value = ENDFILE; break;
  1120. case 'A': case 'B': case 'C': case 'D': case 'E':
  1121. case 'F': case 'G': case 'H': case 'I': case 'J':
  1122. case 'K': case 'L': case 'M': case 'N': case 'O':
  1123. case 'P': case 'Q': case 'R': case 'S': case 'T':
  1124. case 'U': case 'V': case 'W': case 'X': case 'Y':
  1125. case 'Z':
  1126. case 'a': case 'b': case 'c': case 'd': case 'e':
  1127. case 'f': case 'g': case 'h': case 'i': case 'j':
  1128. case 'k': case 'l': case 'm': case 'n': case 'o':
  1129. case 'p': case 'q': case 'r': case 's': case 't':
  1130. case 'u': case 'v': case 'w': case 'x': case 'y':
  1131. case 'z':
  1132. case '_':
  1133. p = token_buffer;
  1134. while (isalnum(c) || (c == '_'))
  1135. {
  1136. if (p >= token_buffer + maxtoken)
  1137. p = extend_token_buffer(p);
  1138. *p++ = c;
  1139. c = getc(finput);
  1140. }
  1141. *p = 0;
  1142. ungetc(c, finput);
  1143. value = IDENTIFIER;
  1144. yylval.itype = 0;
  1145. if (p - token_buffer <= MAXRESERVED)
  1146. {
  1147. register int lim = frw [p - token_buffer + 1];
  1148. register int i;
  1149. for (i = frw[p - token_buffer]; i < lim; i++)
  1150. if (rw[i][0] == token_buffer[0] && !strcmp(rw[i], token_buffer))
  1151. {
  1152. if (rid[i])
  1153. yylval.ttype = ridpointers[(int) rid[i]];
  1154. value = (int) rtoken[i];
  1155. break;
  1156. }
  1157. }
  1158. if (value == IDENTIFIER)
  1159. {
  1160. yylval.ttype = get_identifier(token_buffer);
  1161. lastiddecl = lookup_name (yylval.ttype);
  1162. if (lastiddecl != 0 && TREE_CODE (lastiddecl) == TYPE_DECL)
  1163. value = TYPENAME;
  1164. }
  1165. break;
  1166. case '0': case '1': case '2': case '3': case '4':
  1167. case '5': case '6': case '7': case '8': case '9':
  1168. case '.':
  1169. {
  1170. int base = 10;
  1171. int count = 0;
  1172. /* for multi-precision arithmetic, we store only 8 live bits in each short,
  1173. giving us 64 bits of reliable precision */
  1174. short shorts[8];
  1175. char *floatflag = NULL; /* set nonzero if we learn this is a floating constant */
  1176. /* in fact, it points to the first fractional digit. */
  1177. for (count = 0; count < 8; count++)
  1178. shorts[count] = 0;
  1179. p = token_buffer;
  1180. *p++ = c;
  1181. if (c == '0')
  1182. {
  1183. *p++ = (c = getc(finput));
  1184. if ((c == 'x') || (c == 'X'))
  1185. {
  1186. base = 16;
  1187. *p++ = (c = getc(finput));
  1188. }
  1189. else
  1190. {
  1191. base = 8;
  1192. }
  1193. }
  1194. while (c == '.'
  1195. || (isalnum (c) && (c != 'l') && (c != 'L')
  1196. && (c != 'u') && (c != 'U')))
  1197. {
  1198. if (c == '.')
  1199. {
  1200. floatflag = p - 1;
  1201. p[-1] = c = getc(finput); /* omit the decimal point from
  1202. the token buffer. */
  1203. /* Accept '.' as the start of a floating-point number
  1204. only when it is followed by a digit.
  1205. Otherwise, unread the following non-digit
  1206. and use the '.' as a structural token. */
  1207. if (floatflag == token_buffer && !isdigit (c))
  1208. {
  1209. if (c == '.')
  1210. {
  1211. c = getc (finput);
  1212. if (c == '.')
  1213. return ELLIPSIS;
  1214. yyerror ("syntax error");
  1215. }
  1216. ungetc (c, finput);
  1217. return '.';
  1218. }
  1219. }
  1220. else
  1221. {
  1222. if (isdigit(c))
  1223. {
  1224. c = c - '0';
  1225. }
  1226. else if (base <= 10)
  1227. {
  1228. if ((c&~040) == 'E')
  1229. {
  1230. if (floatflag == 0)
  1231. floatflag = p - 1;
  1232. break; /* start of exponent */
  1233. }
  1234. yyerror("nondigits in number and not hexadecimal");
  1235. c = 0;
  1236. }
  1237. else if (c >= 'a')
  1238. {
  1239. c = c - 'a' + 10;
  1240. }
  1241. else
  1242. {
  1243. c = c - 'A' + 10;
  1244. }
  1245. if (c >= base)
  1246. yyerror("numeric constant contains digits beyond the radix");
  1247. for (count = 0; count < 8; count++)
  1248. {
  1249. (shorts[count] *= base);
  1250. if (count)
  1251. {
  1252. shorts[count] += (shorts[count-1] >> 8);
  1253. shorts[count-1] &= (1<<8)-1;
  1254. }
  1255. else shorts[0] += c;
  1256. }
  1257. *p++ = (c = getc(finput));
  1258. }
  1259. }
  1260. /* Remove terminating char from the token buffer and delimit the string */
  1261. *--p = 0;
  1262. if (floatflag)
  1263. {
  1264. register ex = -(p - floatflag); /* exponent is minus # digits after decimal pt */
  1265. tree type = double_type_node;
  1266. /* read explicit exponent if any, and add into ex. */
  1267. if ((c == 'e') || (c == 'E'))
  1268. {
  1269. register int exval = 0;
  1270. register int exsign = 1;
  1271. c = getc(finput);
  1272. if ((c == '+') || (c == '-'))
  1273. {
  1274. if (c == '-') exsign = -1;
  1275. c = getc(finput);
  1276. }
  1277. while (isdigit(c))
  1278. {
  1279. exval *= 10;
  1280. exval += c - '0';
  1281. c = getc(finput);
  1282. }
  1283. ex += exsign*exval;
  1284. }
  1285. while (1)
  1286. {
  1287. if (c == 'f' || c == 'F')
  1288. type = float_type_node;
  1289. else if (c == 'l' || c == 'L')
  1290. type = long_double_type_node;
  1291. else break;
  1292. c = getc (finput);
  1293. }
  1294. ungetc(c, finput);
  1295. yylval.ttype = build_real_from_string (token_buffer, ex);
  1296. TREE_TYPE (yylval.ttype) = type;
  1297. }
  1298. else
  1299. {
  1300. tree type;
  1301. int spec_unsigned = 0;
  1302. int spec_long = 0;
  1303. while (1)
  1304. {
  1305. if (c == 'u' || c == 'U')
  1306. {
  1307. spec_unsigned = 1;
  1308. c = getc (finput);
  1309. }
  1310. else if (c == 'l' || c == 'L')
  1311. {
  1312. spec_long = 1;
  1313. c = getc (finput);
  1314. }
  1315. else break;
  1316. }
  1317. ungetc (c, finput);
  1318. /* This is simplified by the fact that our constant
  1319. is always positive. */
  1320. yylval.ttype
  1321. = build_int_2 ((shorts[3]<<24) + (shorts[2]<<16) + (shorts[1]<<8) + shorts[0],
  1322. (shorts[7]<<24) + (shorts[6]<<16) + (shorts[5]<<8) + shorts[4]);
  1323. if (!spec_long && !spec_unsigned
  1324. && int_fits_type_p (yylval.ttype, integer_type_node))
  1325. type = integer_type_node;
  1326. else if (!spec_long && base != 10
  1327. && int_fits_type_p (yylval.ttype, unsigned_type_node))
  1328. type = unsigned_type_node;
  1329. else if (!spec_unsigned
  1330. && int_fits_type_p (yylval.ttype, long_integer_type_node))
  1331. type = long_integer_type_node;
  1332. else
  1333. type = long_unsigned_type_node;
  1334. TREE_TYPE (yylval.ttype) = type;
  1335. }
  1336. value = CONSTANT; break;
  1337. }
  1338. case '\'':
  1339. c = getc(finput);
  1340. {
  1341. register int code = 0;
  1342. tryagain:
  1343. if (c == '\\')
  1344. {
  1345. c = readescape ();
  1346. if (c < 0)
  1347. goto tryagain;
  1348. }
  1349. code = c;
  1350. c = getc (finput);
  1351. if (c != '\'')
  1352. yyerror("malformatted character constant");
  1353. if (char_type_node == unsigned_char_type_node
  1354. || (c >> (BITS_PER_UNIT - 1)) == 0)
  1355. yylval.ttype = build_int_2 (code, 0);
  1356. else
  1357. yylval.ttype = build_int_2 (code | (1 << BITS_PER_UNIT), -1);
  1358. TREE_TYPE (yylval.ttype) = char_type_node;
  1359. value = CONSTANT; break;
  1360. }
  1361. case '"':
  1362. {
  1363. c = getc(finput);
  1364. p = token_buffer;
  1365. while (c != '"')
  1366. {
  1367. if (c == '\\')
  1368. {
  1369. c = readescape ();
  1370. if (c < 0)
  1371. goto skipnewline;
  1372. }
  1373. else if (c == '\n')
  1374. {
  1375. lineno++;
  1376. }
  1377. if (p == token_buffer + maxtoken)
  1378. p = extend_token_buffer(p);
  1379. *p++ = c;
  1380. skipnewline:
  1381. c = getc (finput);
  1382. }
  1383. *p++ = 0;
  1384. yylval.ttype = build_string (p - token_buffer, token_buffer);
  1385. TREE_TYPE (yylval.ttype) = char_array_type_node;
  1386. value = STRING; break;
  1387. }
  1388. case '+':
  1389. case '-':
  1390. case '&':
  1391. case '|':
  1392. case '<':
  1393. case '>':
  1394. case '*':
  1395. case '/':
  1396. case '%':
  1397. case '^':
  1398. case '!':
  1399. case '=':
  1400. {
  1401. register int c1;
  1402. combine:
  1403. switch (c)
  1404. {
  1405. case '+':
  1406. yylval.code = PLUS_EXPR; break;
  1407. case '-':
  1408. yylval.code = MINUS_EXPR; break;
  1409. case '&':
  1410. yylval.code = BIT_AND_EXPR; break;
  1411. case '|':
  1412. yylval.code = BIT_IOR_EXPR; break;
  1413. case '*':
  1414. yylval.code = MULT_EXPR; break;
  1415. case '/':
  1416. yylval.code = TRUNC_DIV_EXPR; break;
  1417. case '%':
  1418. yylval.code = TRUNC_MOD_EXPR; break;
  1419. case '^':
  1420. yylval.code = BIT_XOR_EXPR; break;
  1421. case LSHIFT:
  1422. yylval.code = LSHIFT_EXPR; break;
  1423. case RSHIFT:
  1424. yylval.code = RSHIFT_EXPR; break;
  1425. case '<':
  1426. yylval.code = LT_EXPR; break;
  1427. case '>':
  1428. yylval.code = GT_EXPR; break;
  1429. }
  1430. c1 = getc(finput);
  1431. if (c1 == '=')
  1432. {
  1433. switch (c)
  1434. {
  1435. case '<':
  1436. value = ARITHCOMPARE; yylval.code = LE_EXPR; goto done;
  1437. case '>':
  1438. value = ARITHCOMPARE; yylval.code = GE_EXPR; goto done;
  1439. case '!':
  1440. value = EQCOMPARE; yylval.code = NE_EXPR; goto done;
  1441. case '=':
  1442. value = EQCOMPARE; yylval.code = EQ_EXPR; goto done;
  1443. }
  1444. value = ASSIGN; goto done;
  1445. }
  1446. else if (c == c1)
  1447. switch (c)
  1448. {
  1449. case '+':
  1450. value = PLUSPLUS; goto done;
  1451. case '-':
  1452. value = MINUSMINUS; goto done;
  1453. case '&':
  1454. value = ANDAND; goto done;
  1455. case '|':
  1456. value = OROR; goto done;
  1457. case '<':
  1458. c = LSHIFT;
  1459. goto combine;
  1460. case '>':
  1461. c = RSHIFT;
  1462. goto combine;
  1463. }
  1464. else if ((c == '-') && (c1 == '>'))
  1465. { value = POINTSAT; goto done; }
  1466. ungetc (c1, finput);
  1467. if ((c == '<') || (c == '>'))
  1468. value = ARITHCOMPARE;
  1469. else value = c;
  1470. goto done;
  1471. }
  1472. default:
  1473. value = c;
  1474. }
  1475. done:
  1476. yylloc.last_line = lineno;
  1477. return (value);
  1478. }