permit multiline comments and strings in macros
[bpt/coccinelle.git] / parsing_c / parser_c.mly
CommitLineData
34e49164 1%{
0708f913 2(* Yoann Padioleau
ae4735db 3 *
b1b2de81 4 * Copyright (C) 2002, 2006, 2007, 2008, 2009 Yoann Padioleau
34e49164
C
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License (GPL)
8 * version 2 as published by the Free Software Foundation.
ae4735db 9 *
34e49164
C
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * file license.txt for more details.
14 *)
15open Common
16
17open Ast_c
18
19module LP = Lexer_parser
20open Lexer_parser (* for the fields *)
21
22open Semantic_c (* Semantic exn *)
1b9ae606 23module T = Token_c
34e49164
C
24
25(*****************************************************************************)
26(* Wrappers *)
27(*****************************************************************************)
ae4735db
C
28let warning s v =
29 if !Flag_parsing_c.verbose_parsing
34e49164
C
30 then Common.warning ("PARSING: " ^ s) v
31 else v
32
ae4735db 33let pr2, pr2_once = Common.mk_pr2_wrappers Flag_parsing_c.verbose_parsing
34e49164
C
34
35(*****************************************************************************)
36(* Parse helpers functions *)
37(*****************************************************************************)
38
39(*-------------------------------------------------------------------------- *)
40(* Type related *)
41(*-------------------------------------------------------------------------- *)
42
43type shortLong = Short | Long | LongLong
44
ae4735db 45type decl = {
34e49164
C
46 storageD: storagebis wrap;
47 typeD: ((sign option) * (shortLong option) * (typeCbis option)) wrap;
48 qualifD: typeQualifierbis wrap;
49 inlineD: bool wrap;
50 (* note: have a full_info: parse_info list; to remember ordering
51 * between storage, qualifier, type ? well this info is already in
52 * the Ast_c.info, just have to sort them to get good order *)
ae4735db 53}
34e49164
C
54
55let nullDecl = {
56 storageD = NoSto, [];
57 typeD = (None, None, None), [];
58 qualifD = nullQualif;
59 inlineD = false, [];
60}
61let fake_pi = Common.fake_parse_info
62
ae4735db 63let addStorageD = function
34e49164 64 | ((x,ii), ({storageD = (NoSto,[])} as v)) -> { v with storageD = (x, [ii]) }
ae4735db 65 | ((x,ii), ({storageD = (y, ii2)} as v)) ->
b1b2de81 66 if x =*= y then warning "duplicate storage classes" v
34e49164
C
67 else raise (Semantic ("multiple storage classes", fake_pi))
68
ae4735db 69let addInlineD = function
34e49164
C
70 | ((true,ii), ({inlineD = (false,[])} as v)) -> { v with inlineD=(true,[ii])}
71 | ((true,ii), ({inlineD = (true, ii2)} as v)) -> warning "duplicate inline" v
abad11c5 72 | _ -> raise (Impossible 86)
34e49164
C
73
74
ae4735db
C
75let addTypeD = function
76 | ((Left3 Signed,ii) ,({typeD = ((Some Signed, b,c),ii2)} as v)) ->
34e49164 77 warning "duplicate 'signed'" v
ae4735db 78 | ((Left3 UnSigned,ii) ,({typeD = ((Some UnSigned,b,c),ii2)} as v)) ->
34e49164 79 warning "duplicate 'unsigned'" v
ae4735db 80 | ((Left3 _,ii), ({typeD = ((Some _,b,c),ii2)} as _v)) ->
34e49164 81 raise (Semantic ("both signed and unsigned specified", fake_pi))
ae4735db 82 | ((Left3 x,ii), ({typeD = ((None,b,c),ii2)} as v)) ->
34e49164
C
83 {v with typeD = (Some x,b,c),ii ++ ii2}
84
ae4735db 85 | ((Middle3 Short,ii), ({typeD = ((a,Some Short,c),ii2)} as v)) ->
34e49164
C
86 warning "duplicate 'short'" v
87
ae4735db 88
34e49164 89 (* gccext: long long allowed *)
ae4735db 90 | ((Middle3 Long,ii), ({typeD = ((a,Some Long ,c),ii2)} as v)) ->
34e49164 91 { v with typeD = (a, Some LongLong, c),ii++ii2 }
ae4735db 92 | ((Middle3 Long,ii), ({typeD = ((a,Some LongLong ,c),ii2)} as v)) ->
34e49164
C
93 warning "triplicate 'long'" v
94
485bce71 95
ae4735db 96 | ((Middle3 _,ii), ({typeD = ((a,Some _,c),ii2)} as _v)) ->
34e49164 97 raise (Semantic ("both long and short specified", fake_pi))
ae4735db 98 | ((Middle3 x,ii), ({typeD = ((a,None,c),ii2)} as v)) ->
34e49164
C
99 {v with typeD = (a, Some x,c),ii++ii2}
100
97111a47
C
101 | ((Right3 t,ii), ({typeD = ((a,b,Some x),ii2)} as _v)) ->
102 raise (Semantic ((Printf.sprintf "two or more data types: t %s ii %s\ntypeD %s ii2 %s\n" (Dumper.dump t) (Dumper.dump ii) (Dumper.dump x) (Dumper.dump ii2)), fake_pi))
ae4735db 103 | ((Right3 t,ii), ({typeD = ((a,b,None),ii2)} as v)) ->
34e49164
C
104 {v with typeD = (a,b, Some t),ii++ii2}
105
106
107let addQualif = function
108 | ({const=true}, ({const=true} as x)) -> warning "duplicate 'const'" x
109 | ({volatile=true},({volatile=true} as x))-> warning "duplicate 'volatile'" x
110 | ({const=true}, v) -> {v with const=true}
111 | ({volatile=true}, v) -> {v with volatile=true}
ae4735db 112 | _ ->
91eba41f 113 internal_error "there is no noconst or novolatile keyword"
34e49164
C
114
115let addQualifD ((qu,ii), ({qualifD = (v,ii2)} as x)) =
116 { x with qualifD = (addQualif (qu, v),ii::ii2) }
117
118
119(*-------------------------------------------------------------------------- *)
120(* Declaration/Function related *)
121(*-------------------------------------------------------------------------- *)
122
123
124(* stdC: type section, basic integer types (and ritchie)
ae4735db 125 * To understand the code, just look at the result (right part of the PM)
34e49164
C
126 * and go back.
127 *)
128let (fixDeclSpecForDecl: decl -> (fullType * (storage wrap))) = function
ae4735db
C
129 {storageD = (st,iist);
130 qualifD = (qu,iiq);
131 typeD = (ty,iit);
34e49164 132 inlineD = (inline,iinl);
ae4735db
C
133 } ->
134 let ty',iit' =
135 (match ty with
136 | (None,None,None) ->
137 (* generate fake_info, otherwise type_annotater can crash in
91eba41f
C
138 * offset.
139 *)
140 warning "type defaults to 'int'" (defaultInt, [fakeInfo fake_pi])
34e49164 141 | (None, None, Some t) -> (t, iit)
ae4735db
C
142
143 | (Some sign, None, (None| Some (BaseType (IntType (Si (_,CInt)))))) ->
34e49164 144 BaseType(IntType (Si (sign, CInt))), iit
ae4735db 145 | ((None|Some Signed),Some x,(None|Some(BaseType(IntType (Si (_,CInt)))))) ->
34e49164 146 BaseType(IntType (Si (Signed, [Short,CShort; Long, CLong; LongLong, CLongLong] +> List.assoc x))), iit
ae4735db 147 | (Some UnSigned, Some x, (None| Some (BaseType (IntType (Si (_,CInt))))))->
34e49164 148 BaseType(IntType (Si (UnSigned, [Short,CShort; Long, CLong; LongLong, CLongLong] +> List.assoc x))), iit
708f4980
C
149 | (Some sign, None, (Some (BaseType (IntType CChar)))) ->
150 BaseType(IntType (Si (sign, CChar2))), iit
151 | (None, Some Long,(Some(BaseType(FloatType CDouble)))) ->
152 BaseType (FloatType (CLongDouble)), iit
34e49164 153
ae4735db 154 | (Some _,_, Some _) ->
34e49164
C
155 (*mine*)
156 raise (Semantic ("signed, unsigned valid only for char and int", fake_pi))
ae4735db 157 | (_,Some _,(Some(BaseType(FloatType (CFloat|CLongDouble))))) ->
34e49164
C
158 raise (Semantic ("long or short specified with floatint type", fake_pi))
159 | (_,Some Short,(Some(BaseType(FloatType CDouble)))) ->
160 raise (Semantic ("the only valid combination is long double", fake_pi))
ae4735db
C
161
162 | (_, Some _, Some _) ->
34e49164 163 (* mine *)
ae4735db 164 raise (Semantic ("long, short valid only for int or float", fake_pi))
34e49164
C
165
166 (* if do short uint i, then gcc say parse error, strange ? it is
167 * not a parse error, it is just that we dont allow with typedef
168 * either short/long or signed/unsigned. In fact, with
169 * parse_typedef_fix2 (with et() and dt()) now I say too parse
170 * error so this code is executed only when do short struct
171 * {....} and never with a typedef cos now we parse short uint i
172 * as short ident ident => parse error (cos after first short i
173 * pass in dt() mode) *)
708f4980
C
174
175 )
176 in
177 ((qu, iiq),
178 (ty', iit'))
34e49164 179 ,((st, inline),iist++iinl)
34e49164 180
ae4735db
C
181
182let fixDeclSpecForParam = function ({storageD = (st,iist)} as r) ->
34e49164
C
183 let ((qu,ty) as v,_st) = fixDeclSpecForDecl r in
184 match st with
185 | (Sto Register) -> (v, true), iist
186 | NoSto -> (v, false), iist
ae4735db
C
187 | _ ->
188 raise
189 (Semantic ("storage class specified for parameter of function",
34e49164
C
190 fake_pi))
191
ae4735db 192let fixDeclSpecForMacro = function ({storageD = (st,iist)} as r) ->
708f4980
C
193 let ((qu,ty) as v,_st) = fixDeclSpecForDecl r in
194 match st with
195 | NoSto -> v
ae4735db
C
196 | _ ->
197 raise
198 (Semantic ("storage class specified for macro type decl",
708f4980
C
199 fake_pi))
200
201
34e49164
C
202let fixDeclSpecForFuncDef x =
203 let (returnType,storage) = fixDeclSpecForDecl x in
204 (match fst (unwrap storage) with
ae4735db 205 | StoTypedef ->
34e49164 206 raise (Semantic ("function definition declared 'typedef'", fake_pi))
0708f913 207 | _ -> (returnType, storage)
34e49164 208 )
ae4735db 209
34e49164
C
210
211(* parameter: (this is the context where we give parameter only when
212 * in func DEFINITION not in funct DECLARATION) We must have a name.
213 * This function ensure that we give only parameterTypeDecl with well
214 * formed Classic constructor todo?: do we accept other declaration
215 * in ? so I must add them to the compound of the deffunc. I dont
216 * have to handle typedef pb here cos C forbid to do VF f { ... }
217 * with VF a typedef of func cos here we dont see the name of the
218 * argument (in the typedef)
219 *)
220let (fixOldCDecl: fullType -> fullType) = fun ty ->
708f4980 221 match Ast_c.unwrap_typeC ty with
ae4735db 222 | FunctionType (fullt, (params, (b, iib))) ->
34e49164
C
223
224 (* stdC: If the prototype declaration declares a parameter for a
225 * function that you are defining (it is part of a function
226 * definition), then you must write a name within the declarator.
227 * Otherwise, you can omit the name. *)
228 (match params with
ae4735db 229 | [{p_namei = None; p_type = ty2},_] ->
708f4980 230 (match Ast_c.unwrap_typeC ty2 with
ae4735db 231 | BaseType Void ->
708f4980 232 ty
ae4735db 233 | _ ->
97111a47 234 pr2_once ("SEMANTIC:parameter name omitted, but I continue");
708f4980
C
235 ty
236 )
ae4735db
C
237
238 | params ->
b1b2de81
C
239 (params +> List.iter (fun (param,_) ->
240 match param with
ae4735db 241 | {p_namei = None} ->
34e49164 242 (* if majuscule, then certainly macro-parameter *)
97111a47 243 pr2_once ("SEMANTIC:parameter name omitted, but I continue");
b1b2de81
C
244 | _ -> ()
245 ));
708f4980
C
246 ty
247 )
ae4735db 248
34e49164
C
249 (* todo? can we declare prototype in the decl or structdef,
250 ... => length <> but good kan meme *)
ae4735db 251 | _ ->
34e49164 252 (* gcc say parse error but dont see why *)
ae4735db 253 raise (Semantic ("seems this is not a function", fake_pi))
34e49164
C
254
255
ae4735db 256let fixFunc (typ, compound, old_style_opt) =
91eba41f
C
257 let (cp,iicp) = compound in
258
708f4980
C
259 let (name, ty, (st,iist), attrs) = typ in
260
261 let (qu, tybis) = ty in
262
263 match Ast_c.unwrap_typeC ty with
ae4735db 264 | FunctionType (fullt, (params,abool)) ->
708f4980
C
265 let iifunc = Ast_c.get_ii_typeC_take_care tybis in
266
34e49164 267 let iistart = Ast_c.fakeInfo () in
708f4980
C
268 assert (qu =*= nullQualif);
269
34e49164 270 (match params with
ae4735db 271 | [{p_namei= None; p_type = ty2}, _] ->
708f4980
C
272 (match Ast_c.unwrap_typeC ty2 with
273 | BaseType Void -> ()
ae4735db 274 | _ ->
708f4980
C
275 (* failwith "internal errror: fixOldCDecl not good" *)
276 ()
277 )
ae4735db
C
278 | params ->
279 params +> List.iter (function
b1b2de81 280 | ({p_namei = Some s}, _) -> ()
34e49164
C
281 | _ -> ()
282 (* failwith "internal errror: fixOldCDecl not good" *)
0708f913
C
283 )
284 );
ae4735db 285 (* bugfix: cf tests_c/function_pointer4.c.
0708f913 286 * Apparemment en C on peut syntaxiquement ecrire ca:
ae4735db 287 *
0708f913
C
288 * void a(int)(int x);
289 * mais apres gcc gueule au niveau semantique avec:
290 * xxx.c:1: error: 'a' declared as function returning a function
ae4735db
C
291 * Je ne faisais pas cette verif. Sur du code comme
292 * void METH(foo)(int x) { ...} , le parser croit (a tort) que foo
293 * est un typedef, et donc c'est parsé comme l'exemple precedent,
0708f913
C
294 * ce qui ensuite confuse l'unparser qui n'est pas habitué
295 * a avoir dans le returnType un FunctionType et qui donc
296 * pr_elem les ii dans le mauvais sens ce qui genere au final
ae4735db 297 * une exception. Hence this fix to at least detect the error
0708f913
C
298 * at parsing time (not unparsing time).
299 *)
ae4735db
C
300 (match Ast_c.unwrap_typeC fullt with
301 | FunctionType _ ->
b1b2de81
C
302 let s = Ast_c.str_of_name name in
303 let iis = Ast_c.info_of_name name in
0708f913
C
304 pr2 (spf "WEIRD: %s declared as function returning a function." s);
305 pr2 (spf "This is probably because of a macro. Extend standard.h");
306 raise (Semantic (spf "error: %s " s, Ast_c.parse_info_of_info iis))
307 | _ -> ()
308 );
309
34e49164 310 (* it must be nullQualif,cos parser construct only this*)
b1b2de81 311 {f_name = name;
708f4980 312 f_type = (fullt, (params, abool));
485bce71
C
313 f_storage = st;
314 f_body = cp;
315 f_attr = attrs;
91eba41f 316 f_old_c_style = old_style_opt;
ae4735db
C
317 },
318 (iifunc++iicp++[iistart]++iist)
319 | _ ->
320 raise
321 (Semantic
34e49164
C
322 ("you are trying to do a function definition but you dont give " ^
323 "any parameter", fake_pi))
324
325
326(*-------------------------------------------------------------------------- *)
327(* parse_typedef_fix2 *)
328(*-------------------------------------------------------------------------- *)
329
ae4735db
C
330let dt s () =
331 if !Flag_parsing_c.debug_etdt then pr2 ("<" ^ s);
34e49164
C
332 LP.disable_typedef ()
333
ae4735db
C
334let et s () =
335 if !Flag_parsing_c.debug_etdt then pr2 (">" ^ s);
34e49164
C
336 LP.enable_typedef ()
337
338
ae4735db 339let fix_add_params_ident x =
708f4980
C
340 let (s, ty, st, _attrs) = x in
341 match Ast_c.unwrap_typeC ty with
342 | FunctionType (fullt, (params, bool)) ->
34e49164
C
343
344 (match params with
ae4735db 345 | [{p_namei=None; p_type=ty2}, _] ->
708f4980
C
346 (match Ast_c.unwrap_typeC ty2 with
347 | BaseType Void -> ()
ae4735db 348 | _ ->
708f4980
C
349 (* failwith "internal errror: fixOldCDecl not good" *)
350 ()
351 )
ae4735db
C
352 | params ->
353 params +> List.iter (function
354 | ({p_namei= Some name}, _) ->
b1b2de81 355 LP.add_ident (Ast_c.str_of_name s)
ae4735db 356 | _ ->
b1b2de81
C
357 ()
358 (* failwith "internal errror: fixOldCDecl not good" *)
359 )
ae4735db 360 )
34e49164
C
361 | _ -> ()
362
0708f913
C
363
364
34e49164
C
365(*-------------------------------------------------------------------------- *)
366(* shortcuts *)
367(*-------------------------------------------------------------------------- *)
368
708f4980 369let mk_e e ii = Ast_c.mk_e e ii
b1b2de81
C
370
371let mk_string_wrap (s,info) = (s, [info])
ae4735db 372
34e49164
C
373%}
374
375/*(*****************************************************************************)*/
485bce71
C
376/*(* Tokens *)*/
377/*(*************************************************************************)*/
34e49164
C
378
379/*
ae4735db 380(*
34e49164
C
381 * Some tokens are not even used in this file because they are filtered
382 * in some intermediate phase. But they still must be declared because
383 * ocamllex may generate them, or some intermediate phase may also
384 * generate them (like some functions in parsing_hacks.ml)
385 *)
386*/
387
388%token <Ast_c.info> TUnknown /*(* unrecognized token *)*/
389
390/*(* coupling: Token_helpers.is_real_comment *)*/
485bce71 391%token <Ast_c.info> TCommentSpace TCommentNewline TComment
34e49164 392
485bce71 393/*(*-----------------------------------------*)*/
34e49164 394/*(* the normal tokens *)*/
485bce71 395/*(*-----------------------------------------*)*/
34e49164 396
708f4980 397%token <(string * (Ast_c.sign * Ast_c.base)) * Ast_c.info> TInt
34e49164
C
398%token <(string * Ast_c.floatType) * Ast_c.info> TFloat
399%token <(string * Ast_c.isWchar) * Ast_c.info> TChar
400%token <(string * Ast_c.isWchar) * Ast_c.info> TString
401
ae4735db 402%token <string * Ast_c.info> TIdent
97111a47 403%token <string * Ast_c.info> TKRParam
f59c9fb7 404%token <string * Ast_c.info> Tconstructorname /* parsing_hack for c++ */
485bce71
C
405/*(* appears mostly after some fix_xxx in parsing_hack *)*/
406%token <string * Ast_c.info> TypedefIdent
34e49164
C
407
408
409/*
ae4735db 410(* Some tokens like TOPar and TCPar are used as synchronisation stuff,
34e49164 411 * in parsing_hack.ml. So if define special tokens like TOParDefine and
485bce71 412 * TCParEOL, then take care to also modify in Token_helpers.
34e49164
C
413 *)
414*/
ae4735db
C
415
416%token <Ast_c.info> TOPar TCPar TOBrace TCBrace TOCro TCCro
417%token <Ast_c.info> TDot TComma TPtrOp
34e49164 418%token <Ast_c.info> TInc TDec
ae4735db 419%token <Ast_c.assignOp * Ast_c.info> TAssign
34e49164
C
420%token <Ast_c.info> TEq
421%token <Ast_c.info> TWhy TTilde TBang
422%token <Ast_c.info> TEllipsis
423%token <Ast_c.info> TDotDot
424
425%token <Ast_c.info> TPtVirg
ae4735db 426%token <Ast_c.info>
34e49164 427 TOrLog TAndLog TOr TXor TAnd TEqEq TNotEq TInf TSup TInfEq TSupEq
ae4735db 428 TShl TShr
1b9ae606 429 TPlus TMinus TMul TDiv TMod TMin TMax
34e49164
C
430
431%token <Ast_c.info>
432 Tchar Tshort Tint Tdouble Tfloat Tlong Tunsigned Tsigned Tvoid
1eddfd50 433 Tsize_t Tssize_t Tptrdiff_t
ae4735db
C
434 Tauto Tregister Textern Tstatic
435 Ttypedef
34e49164 436 Tconst Tvolatile
ae4735db 437 Tstruct Tunion Tenum
34e49164
C
438 Tbreak Telse Tswitch Tcase Tcontinue Tfor Tdo Tif Twhile Treturn
439 Tgoto Tdefault
1b9ae606 440 Tsizeof Tnew Tdelete TOParCplusplusInit Tnamespace
34e49164 441
485bce71
C
442/*(* C99 *)*/
443%token <Ast_c.info>
444 Trestrict
445
446/*(*-----------------------------------------*)*/
34e49164 447/*(* gccext: extra tokens *)*/
485bce71 448/*(*-----------------------------------------*)*/
34e49164
C
449%token <Ast_c.info> Tasm
450%token <Ast_c.info> Tattribute
978fd7e5 451%token <Ast_c.info> TattributeNoarg
34e49164
C
452%token <Ast_c.info> Tinline
453%token <Ast_c.info> Ttypeof
454
485bce71
C
455/*(*-----------------------------------------*)*/
456/*(* cppext: extra tokens *)*/
457/*(*-----------------------------------------*)*/
458/*(* coupling with Token_helpers.is_cpp_token *)*/
459
460
461/*(*---------------*)*/
462/*(* define *)*/
463/*(*---------------*)*/
464
465%token <Ast_c.info> TDefine
466%token <(string * Ast_c.info)> TDefParamVariadic
467
468/*(* disappear after fix_tokens_define *)*/
ae4735db 469%token <Ast_c.info> TCppEscapedNewline
485bce71 470
b1b2de81
C
471%token <Ast_c.info> TCppConcatOp
472
485bce71 473/*(* appear after fix_tokens_define *)*/
ae4735db 474%token <Ast_c.info> TOParDefine
485bce71
C
475%token <Ast_c.info> TOBraceDefineInit
476
477%token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/
478%token <Ast_c.info> TDefEOL /*(* same *)*/
479
480
481/*(*---------------*)*/
482/*(* include *)*/
483/*(*---------------*)*/
484
485
486/*(* used only in lexer_c, then transformed in comment or splitted in tokens *)*/
487%token <(string * string * bool ref * Ast_c.info)> TInclude
488
489/*(* tokens coming from above, generated in parse_c from TInclude, etc *)*/
490%token <(Ast_c.info * bool ref)> TIncludeStart
491%token <(string * Ast_c.info)> TIncludeFilename
492
493
494/*(*---------------*)*/
495/*(* ifdef *)*/
496/*(*---------------*)*/
497
498/*(* coupling: Token_helpers.is_cpp_instruction *)*/
ae4735db 499%token <((int * int) option ref * Ast_c.info)>
485bce71 500 TIfdef TIfdefelse TIfdefelif TEndif
ae4735db 501%token <(bool * (int * int) option ref * Ast_c.info)>
485bce71
C
502 TIfdefBool TIfdefMisc TIfdefVersion
503
504/*(*---------------*)*/
505/*(* other *)*/
506/*(*---------------*)*/
507
3a314143 508%token <Ast_c.info> TUndef
485bce71
C
509
510%token <Ast_c.info> TCppDirectiveOther
511
512/*(*---------------*)*/
513/*(* macro use *)*/
514/*(*---------------*)*/
515
516/*(* appear after fix_tokens_cpp, cf also parsing_hacks#hint *)*/
517
518%token <(string * Ast_c.info)> TMacroAttr
519%token <(string * Ast_c.info)> TMacroStmt
b1b2de81 520%token <(string * Ast_c.info)> TMacroIdentBuilder
485bce71 521/*(* no need value for the moment *)*/
ae4735db 522%token <(string * Ast_c.info)> TMacroString
485bce71 523%token <(string * Ast_c.info)> TMacroDecl
ae4735db 524%token <Ast_c.info> TMacroDeclConst
708f4980 525
485bce71 526%token <(string * Ast_c.info)> TMacroIterator
ae4735db
C
527/*(*
528%token <(string * Ast_c.info)> TMacroTop
708f4980
C
529%token <(string * Ast_c.info)> TMacroStructDecl
530*)*/
485bce71
C
531
532%token <(string * Ast_c.info)> TMacroAttrStorage
533
534
535/*(*---------------*)*/
536/*(* other *)*/
537/*(*---------------*)*/
538
0708f913
C
539
540/*(* should disappear after parsing_hack *)*/
541%token <Ast_c.info> TCommentSkipTagStart TCommentSkipTagEnd
542
543
485bce71 544/*(* appear after parsing_hack *)*/
ae4735db 545%token <Ast_c.info> TCParEOL
485bce71
C
546
547%token <Ast_c.info> TAction
548
549
0708f913 550/*(* TCommentMisc still useful ? obsolete ? *)*/
485bce71 551%token <Ast_c.info> TCommentMisc
0708f913 552%token <(Token_c.cppcommentkind * Ast_c.info)> TCommentCpp
485bce71 553
34e49164 554
485bce71 555/*(*-----------------------------------------*)*/
34e49164
C
556%token <Ast_c.info> EOF
557
485bce71
C
558/*(*-----------------------------------------*)*/
559
560/*(* must be at the top so that it has the lowest priority *)*/
561%nonassoc SHIFTHERE
34e49164 562
34e49164
C
563%nonassoc Telse
564
565%left TOrLog
566%left TAndLog
567%left TOr
568%left TXor
ae4735db 569%left TAnd
34e49164 570%left TEqEq TNotEq
ae4735db 571%left TInf TSup TInfEq TSupEq
34e49164
C
572%left TShl TShr
573%left TPlus TMinus
1b9ae606 574%left TMul TDiv TMod TMin TMax
34e49164 575
485bce71
C
576/*(*************************************************************************)*/
577/*(* Rules type declaration *)*/
578/*(*************************************************************************)*/
579
34e49164
C
580%start main celem statement expr type_name
581%type <Ast_c.program> main
582%type <Ast_c.toplevel> celem
583
584%type <Ast_c.statement> statement
585%type <Ast_c.expression> expr
586%type <Ast_c.fullType> type_name
587
588%%
589/*(*************************************************************************)*/
590/*
591(* TOC:
485bce71 592 * toplevel (obsolete)
ae4735db 593 *
485bce71 594 * ident
34e49164
C
595 * expression
596 * statement
ae4735db
C
597 * types with
598 * - left part (type_spec, qualif),
485bce71
C
599 * - right part (declarator, abstract declarator)
600 * - aux part (parameters)
601 * declaration, storage, initializers
602 * struct
603 * enum
34e49164
C
604 * cpp directives
605 * celem (=~ main)
ae4735db 606 *
485bce71
C
607 * generic workarounds (obrace, cbrace for context setting)
608 * xxx_list, xxx_opt
34e49164
C
609 *)
610*/
611/*(*************************************************************************)*/
612
485bce71
C
613/*(*************************************************************************)*/
614/*(* toplevel *)*/
615/*(*************************************************************************)*/
34e49164
C
616/*(* no more used; now that use error recovery *)*/
617
f59c9fb7
C
618main:
619 translation_unit EOF { $1 }
34e49164 620
ae4735db 621translation_unit:
1b9ae606
C
622 |
623 { [] }
34e49164 624 | translation_unit external_declaration
485bce71 625 { !LP._lexer_hint.context_stack <- [LP.InTopLevel]; $1 ++ [$2] }
1b9ae606
C
626 | translation_unit Tnamespace TIdent TOBrace translation_unit TCBrace
627 { !LP._lexer_hint.context_stack <- [LP.InTopLevel];
628 $1 ++ [Namespace ($5, [$2; snd $3; $4; $6])] }
485bce71
C
629
630
631/*(*************************************************************************)*/
632/*(* ident *)*/
633/*(*************************************************************************)*/
634
ae4735db 635/*(* Why this ? Why not s/ident/TIdent ? cos there is multiple namespaces in C,
485bce71
C
636 * so a label can have the same name that a typedef, same for field and tags
637 * hence sometimes the use of ident instead of TIdent.
638 *)*/
ae4735db 639ident:
485bce71
C
640 | TIdent { $1 }
641 | TypedefIdent { $1 }
34e49164
C
642
643
485bce71
C
644identifier:
645 | TIdent { $1 }
34e49164 646
b1b2de81 647/*
ae4735db 648(* cppext: string concatenation of idents
b1b2de81
C
649 * also cppext: gccext: ##args for variadic macro
650 *)
651*/
708f4980 652identifier_cpp:
ae4735db 653 | TIdent
b1b2de81 654 { RegularName (mk_string_wrap $1) }
708f4980
C
655 | ident_extra_cpp { $1 }
656
657ident_cpp:
658 | TIdent
659 { RegularName (mk_string_wrap $1) }
ae4735db 660 | TypedefIdent
708f4980
C
661 { RegularName (mk_string_wrap $1) }
662 | ident_extra_cpp { $1 }
663
664ident_extra_cpp:
ae4735db
C
665 | TIdent TCppConcatOp identifier_cpp_list
666 {
b1b2de81
C
667 CppConcatenatedName (
668 match $3 with
abad11c5 669 | [] -> raise (Impossible 87)
ae4735db 670 | (x,concatnull)::xs ->
b1b2de81
C
671 assert(null concatnull);
672 (mk_string_wrap $1, [])::(x,[$2])::xs
673 )
674 }
ae4735db 675 | TCppConcatOp TIdent
b1b2de81
C
676 { CppVariadicName (fst $2, [$1; snd $2]) }
677 | TMacroIdentBuilder TOPar param_define_list TCPar
ae4735db 678 { CppIdentBuilder ((fst $1, [snd $1;$2;$4]), $3) }
b1b2de81
C
679
680identifier_cpp_list:
ae4735db 681 | TIdent { [mk_string_wrap $1, []] }
b1b2de81
C
682 | identifier_cpp_list TCppConcatOp TIdent { $1 ++ [mk_string_wrap $3, [$2]] }
683
34e49164
C
684/*(*************************************************************************)*/
685/*(* expr *)*/
686/*(*************************************************************************)*/
687
ae4735db 688expr:
34e49164
C
689 | assign_expr { $1 }
690 | expr TComma assign_expr { mk_e (Sequence ($1,$3)) [$2] }
691
ae4735db 692/*(* bugfix: in C grammar they put unary_expr, but in fact it must be
34e49164
C
693 * cast_expr, otherwise (int * ) xxx = &yy; is not allowed
694 *)*/
ae4735db 695assign_expr:
34e49164
C
696 | cond_expr { $1 }
697 | cast_expr TAssign assign_expr { mk_e(Assignment ($1,fst $2,$3)) [snd $2]}
698 | cast_expr TEq assign_expr { mk_e(Assignment ($1,SimpleAssign,$3)) [$2]}
699
ae4735db 700/*(* gccext: allow optional then part hence gcc_opt_expr
34e49164
C
701 * bugfix: in C grammar they put TDotDot cond_expr, but in fact it must be
702 * assign_expr, otherwise pnp ? x : x = 0x388 is not allowed
703 *)*/
ae4735db
C
704cond_expr:
705 | arith_expr
34e49164 706 { $1 }
ae4735db
C
707 | arith_expr TWhy gcc_opt_expr TDotDot assign_expr
708 { mk_e (CondExpr ($1,$3,$5)) [$2;$4] }
34e49164
C
709
710
ae4735db 711arith_expr:
34e49164
C
712 | cast_expr { $1 }
713 | arith_expr TMul arith_expr { mk_e(Binary ($1, Arith Mul, $3)) [$2] }
714 | arith_expr TDiv arith_expr { mk_e(Binary ($1, Arith Div, $3)) [$2] }
1b9ae606
C
715 | arith_expr TMin arith_expr { mk_e(Binary ($1, Arith Min, $3)) [$2] }
716 | arith_expr TMax arith_expr { mk_e(Binary ($1, Arith Max, $3)) [$2] }
34e49164
C
717 | arith_expr TMod arith_expr { mk_e(Binary ($1, Arith Mod, $3)) [$2] }
718 | arith_expr TPlus arith_expr { mk_e(Binary ($1, Arith Plus, $3)) [$2] }
719 | arith_expr TMinus arith_expr { mk_e(Binary ($1, Arith Minus, $3)) [$2] }
720 | arith_expr TShl arith_expr { mk_e(Binary ($1, Arith DecLeft, $3)) [$2] }
721 | arith_expr TShr arith_expr { mk_e(Binary ($1, Arith DecRight, $3)) [$2] }
722 | arith_expr TInf arith_expr { mk_e(Binary ($1, Logical Inf, $3)) [$2] }
723 | arith_expr TSup arith_expr { mk_e(Binary ($1, Logical Sup, $3)) [$2] }
724 | arith_expr TInfEq arith_expr { mk_e(Binary ($1, Logical InfEq, $3)) [$2] }
725 | arith_expr TSupEq arith_expr { mk_e(Binary ($1, Logical SupEq, $3)) [$2] }
726 | arith_expr TEqEq arith_expr { mk_e(Binary ($1, Logical Eq, $3)) [$2] }
727 | arith_expr TNotEq arith_expr { mk_e(Binary ($1, Logical NotEq, $3)) [$2] }
728 | arith_expr TAnd arith_expr { mk_e(Binary ($1, Arith And, $3)) [$2] }
729 | arith_expr TOr arith_expr { mk_e(Binary ($1, Arith Or, $3)) [$2] }
730 | arith_expr TXor arith_expr { mk_e(Binary ($1, Arith Xor, $3)) [$2] }
731 | arith_expr TAndLog arith_expr { mk_e(Binary ($1, Logical AndLog, $3)) [$2] }
732 | arith_expr TOrLog arith_expr { mk_e(Binary ($1, Logical OrLog, $3)) [$2] }
733
ae4735db 734cast_expr:
34e49164
C
735 | unary_expr { $1 }
736 | topar2 type_name tcpar2 cast_expr { mk_e(Cast ($2, $4)) [$1;$3] }
737
ae4735db 738unary_expr:
34e49164
C
739 | postfix_expr { $1 }
740 | TInc unary_expr { mk_e(Infix ($2, Inc)) [$1] }
741 | TDec unary_expr { mk_e(Infix ($2, Dec)) [$1] }
742 | unary_op cast_expr { mk_e(Unary ($2, fst $1)) [snd $1] }
743 | Tsizeof unary_expr { mk_e(SizeOfExpr ($2)) [$1] }
744 | Tsizeof topar2 type_name tcpar2 { mk_e(SizeOfType ($3)) [$1;$2;$4] }
1b9ae606
C
745 | Tnew new_argument { mk_e(New (None, $2)) [$1] }
746 | Tnew TOPar argument_list_ne TCPar new_argument { mk_e(New (Some $3, $5)) [$1; $2; $4] }
4dfbc1c2 747 | Tdelete cast_expr { mk_e(Delete $2) [$1] }
f59c9fb7
C
748
749new_argument:
4dfbc1c2
C
750 | TIdent TOPar argument_list_ne TCPar
751 { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
752 Left (mk_e(FunCall (fn, $3)) [$2;$4]) }
753 | TIdent TOPar TCPar
754 { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
755 Left(mk_e(FunCall (fn, [])) [$2;$3]) }
756 | TypedefIdent TOPar argument_list_ne TCPar
757 { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
758 Left (mk_e(FunCall (fn, $3)) [$2;$4]) }
759 | TypedefIdent TOPar TCPar
760 { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
761 Left (mk_e(FunCall (fn, [])) [$2;$3]) }
762 | type_spec
763 { let ty = addTypeD ($1,nullDecl) in
764 let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam ty in
f59c9fb7
C
765 Right (ArgType { p_namei = None; p_type = returnType;
766 p_register = hasreg, iihasreg;
767 } )
768 }
4dfbc1c2
C
769 | new_argument TOCro expr TCCro
770 {
771 match $1 with
772 Left(e) -> Left(mk_e(ArrayAccess (e, $3)) [$2;$4])
773 | Right(ArgType(ty)) -> (* lots of hacks to make the right type *)
774 let fty = mk_ty (Array (Some $3, ty.Ast_c.p_type)) [$2;$4] in
775 let pty = { ty with p_type = fty } in
776 Right(ArgType pty)
abad11c5 777 | _ -> raise (Impossible 88)
4dfbc1c2 778 }
34e49164 779
ae4735db 780unary_op:
34e49164
C
781 | TAnd { GetRef, $1 }
782 | TMul { DeRef, $1 }
783 | TPlus { UnPlus, $1 }
784 | TMinus { UnMinus, $1 }
785 | TTilde { Tilde, $1 }
786 | TBang { Not, $1 }
787 /*(* gccext: have that a lot in old kernel to get address of local label.
788 * cf gcc manual "local labels as values".
789 *)*/
790 | TAndLog { GetRefLabel, $1 }
791
ae4735db 792postfix_expr:
34e49164 793 | primary_expr { $1 }
ae4735db 794 | postfix_expr TOCro expr TCCro
34e49164 795 { mk_e(ArrayAccess ($1, $3)) [$2;$4] }
ae4735db 796 | postfix_expr TOPar argument_list_ne TCPar
34e49164
C
797 { mk_e(FunCall ($1, $3)) [$2;$4] }
798 | postfix_expr TOPar TCPar { mk_e(FunCall ($1, [])) [$2;$3] }
b1b2de81
C
799 | postfix_expr TDot ident_cpp { mk_e(RecordAccess ($1,$3)) [$2] }
800 | postfix_expr TPtrOp ident_cpp { mk_e(RecordPtAccess ($1,$3)) [$2] }
34e49164
C
801 | postfix_expr TInc { mk_e(Postfix ($1, Inc)) [$2] }
802 | postfix_expr TDec { mk_e(Postfix ($1, Dec)) [$2] }
803
804 /*(* gccext: also called compound literals *)*/
0708f913 805 | topar2 type_name tcpar2 TOBrace TCBrace
7fe62b65 806 { mk_e(Constructor ($2, (InitList [], [$4;$5]))) [$1;$3] }
34e49164 807 | topar2 type_name tcpar2 TOBrace initialize_list gcc_comma_opt TCBrace
7fe62b65 808 { mk_e(Constructor ($2, (InitList (List.rev $5),[$4;$7]++$6))) [$1;$3] }
34e49164 809
4dfbc1c2 810
0708f913 811primary_expr:
708f4980
C
812 | identifier_cpp { mk_e(Ident ($1)) [] }
813 | TInt
814 { let (str,(sign,base)) = fst $1 in
815 mk_e(Constant (Int (str,Si(sign,base)))) [snd $1] }
34e49164
C
816 | TFloat { mk_e(Constant (Float (fst $1))) [snd $1] }
817 | TString { mk_e(Constant (String (fst $1))) [snd $1] }
818 | TChar { mk_e(Constant (Char (fst $1))) [snd $1] }
819 | TOPar expr TCPar { mk_e(ParenExpr ($2)) [$1;$3] } /*(* forunparser: *)*/
820
485bce71 821 /*(* gccext: cppext: TODO better ast ? *)*/
0708f913
C
822 | TMacroString { mk_e(Constant (MultiString [fst $1])) [snd $1] }
823 | string_elem string_list
824 { mk_e(Constant (MultiString ["TODO: MultiString"])) ($1 ++ $2) }
34e49164
C
825
826 /*(* gccext: allow statement as expressions via ({ statement }) *)*/
0708f913 827 | TOPar compound TCPar { mk_e(StatementExpr ($2)) [$1;$3] }
34e49164
C
828
829
830
485bce71
C
831/*(*----------------------------*)*/
832/*(* cppext: *)*/
833/*(*----------------------------*)*/
34e49164
C
834
835/*(* cppext: *)*/
485bce71 836/*(* to avoid conflicts have to introduce a _not_empty (ne) version *)*/
0708f913 837argument_ne:
34e49164
C
838 | assign_expr { Left $1 }
839 | parameter_decl { Right (ArgType $1) }
840 | action_higherordermacro_ne { Right (ArgAction $1) }
841
485bce71 842
ae4735db 843argument:
34e49164
C
844 | assign_expr { Left $1 }
845 | parameter_decl { Right (ArgType $1) }
485bce71 846 /*(* had conflicts before, but julia fixed them *)*/
34e49164
C
847 | action_higherordermacro { Right (ArgAction $1) }
848
ae4735db
C
849action_higherordermacro_ne:
850 | taction_list_ne
34e49164
C
851 { if null $1
852 then ActMisc [Ast_c.fakeInfo()]
853 else ActMisc $1
854 }
855
485bce71 856
ae4735db
C
857action_higherordermacro:
858 | taction_list
34e49164
C
859 { if null $1
860 then ActMisc [Ast_c.fakeInfo()]
861 else ActMisc $1
862 }
863
864
865/*(*----------------------------*)*/
866/*(* workarounds *)*/
867/*(*----------------------------*)*/
868
34e49164
C
869/*(* would like evalInt $1 but require too much info *)*/
870const_expr: cond_expr { $1 }
871
872
873topar2: TOPar { et "topar2" (); $1 }
ae4735db 874tcpar2: TCPar { et "tcpar2" (); $1 (*TODO? et ? sure ? c pas dt plutot ? *) }
34e49164
C
875
876
877
878/*(*************************************************************************)*/
879/*(* statement *)*/
880/*(*************************************************************************)*/
881
708f4980
C
882statement: statement2 { mk_st (fst $1) (snd $1) }
883
ae4735db 884statement2:
34e49164
C
885 | labeled { Labeled (fst $1), snd $1 }
886 | compound { Compound (fst $1), snd $1 }
887 | expr_statement { ExprStatement(fst $1), snd $1 }
888 | selection { Selection (fst $1), snd $1 ++ [fakeInfo()] }
889 | iteration { Iteration (fst $1), snd $1 ++ [fakeInfo()] }
890 | jump TPtVirg { Jump (fst $1), snd $1 ++ [$2] }
891
892 /*(* gccext: *)*/
893 | Tasm TOPar asmbody TCPar TPtVirg { Asm $3, [$1;$2;$4;$5] }
894 | Tasm Tvolatile TOPar asmbody TCPar TPtVirg { Asm $4, [$1;$2;$3;$5;$6] }
895
896 /*(* cppext: *)*/
485bce71 897 | TMacroStmt { MacroStmt, [snd $1] }
34e49164
C
898
899
900
901
ae4735db
C
902/*(* note that case 1: case 2: i++; would be correctly parsed, but with
903 * a Case (1, (Case (2, i++))) :(
34e49164 904 *)*/
ae4735db 905labeled:
993936c0
C
906 | ident_cpp TDotDot sw_stat_or_decl { Label ($1, $3), [$2] }
907 | Tcase const_expr TDotDot sw_stat_or_decl { Case ($2, $4), [$1; $3] }
908 | Tcase const_expr TEllipsis const_expr TDotDot sw_stat_or_decl
34e49164 909 { CaseRange ($2, $4, $6), [$1;$3;$5] } /*(* gccext: allow range *)*/
993936c0
C
910 | Tdefault TDotDot sw_stat_or_decl { Default $3, [$1; $2] }
911
912sw_stat_or_decl:
913 | decl { mk_st (Decl ($1 Ast_c.LocalDecl)) Ast_c.noii }
914 | statement { $1 }
915
34e49164 916
ae4735db 917end_labeled:
34e49164 918 /*(* gccext: allow toto: }
485bce71
C
919 * was generating each 30 shift/Reduce conflicts,
920 * mais ca va, ca fait ce qu'il faut.
ae4735db 921 * update: julia fixed the problem by introducing end_labeled
485bce71 922 * and modifying below stat_or_decl_list
34e49164 923 *)*/
ae4735db 924 | ident_cpp TDotDot
708f4980 925 { Label ($1, (mk_st (ExprStatement None) Ast_c.noii)), [$2] }
ae4735db 926 | Tcase const_expr TDotDot
708f4980 927 { Case ($2, (mk_st (ExprStatement None) Ast_c.noii)), [$1;$3] }
ae4735db 928 | Tdefault TDotDot
708f4980 929 { Default (mk_st (ExprStatement None) Ast_c.noii), [$1; $2] }
34e49164
C
930
931
932
933
934
935compound: tobrace compound2 tcbrace { $2, [$1; $3] }
936
34e49164
C
937
938/*
939(* cppext: because of cpp, some stuff looks like declaration but are in
940 * fact statement but too hard to figure out, and if parse them as
941 * expression, then we force to have first decls and then exprs, then
942 * will have a parse error. So easier to let mix decl/statement.
943 * Moreover it helps to not make such a difference between decl and
944 * statement for further coccinelle phases to factorize code.
945*)*/
ae4735db 946compound2:
34e49164
C
947 | { ([]) }
948 | stat_or_decl_list { $1 }
949
34e49164 950
ae4735db
C
951stat_or_decl_list:
952 | stat_or_decl { [$1] }
485bce71 953 /*(* gccext: to avoid conflicts, cf end_labeled above *)*/
708f4980 954 | end_labeled { [StmtElem (mk_st (Labeled (fst $1)) (snd $1))] }
485bce71
C
955 /*(* old: conflicts | stat_or_decl_list stat_or_decl { $1 ++ [$2] } *)*/
956 | stat_or_decl stat_or_decl_list { $1 :: $2 }
957
ae4735db 958stat_or_decl:
708f4980 959 | decl { StmtElem (mk_st (Decl ($1 Ast_c.LocalDecl)) Ast_c.noii) }
485bce71 960 | statement { StmtElem $1 }
34e49164
C
961
962 /*(* gccext: *)*/
708f4980 963 | function_definition { StmtElem (mk_st (NestedFunc $1) Ast_c.noii) }
34e49164 964
485bce71 965 /* (* cppext: *)*/
ae4735db 966 | cpp_directive
485bce71 967 { CppDirectiveStmt $1 }
ae4735db 968 | cpp_ifdef_directive/*(* stat_or_decl_list ...*)*/
485bce71 969 { IfdefStmt $1 }
34e49164
C
970
971
ae4735db 972expr_statement:
34e49164
C
973 | TPtVirg { None, [$1] }
974 | expr TPtVirg { Some $1, [$2] }
975
ae4735db 976selection:
485bce71 977 | Tif TOPar expr TCPar statement %prec SHIFTHERE
708f4980 978 { If ($3, $5, (mk_st (ExprStatement None) Ast_c.noii)), [$1;$2;$4] }
ae4735db 979 | Tif TOPar expr TCPar statement Telse statement
34e49164 980 { If ($3, $5, $7), [$1;$2;$4;$6] }
ae4735db 981 | Tswitch TOPar expr TCPar statement
34e49164
C
982 { Switch ($3,$5), [$1;$2;$4] }
983
ae4735db
C
984iteration:
985 | Twhile TOPar expr TCPar statement
34e49164 986 { While ($3,$5), [$1;$2;$4] }
ae4735db 987 | Tdo statement Twhile TOPar expr TCPar TPtVirg
34e49164
C
988 { DoWhile ($2,$5), [$1;$3;$4;$6;$7] }
989 | Tfor TOPar expr_statement expr_statement TCPar statement
755320b0 990 { For (ForExp $3,$4,(None, []),$6), [$1;$2;$5]}
34e49164 991 | Tfor TOPar expr_statement expr_statement expr TCPar statement
755320b0 992 { For (ForExp $3,$4,(Some $5, []),$7), [$1;$2;$6] }
485bce71 993 /*(* c++ext: for(int i = 0; i < n; i++)*)*/
755320b0
C
994 | Tfor TOPar decl expr_statement TCPar statement
995 { For (ForDecl ($3 Ast_c.LocalDecl),$4,(None, []),$6), [$1;$2;$5]}
996 | Tfor TOPar decl expr_statement expr TCPar statement
997 { For (ForDecl ($3 Ast_c.LocalDecl),$4,(Some $5, []),$7), [$1;$2;$6] }
34e49164
C
998 /*(* cppext: *)*/
999 | TMacroIterator TOPar argument_list_ne TCPar statement
1000 { MacroIteration (fst $1, $3, $5), [snd $1;$2;$4] }
1001 | TMacroIterator TOPar TCPar statement
1002 { MacroIteration (fst $1, [], $4), [snd $1;$2;$3] }
1003
1004/*(* the ';' in the caller grammar rule will be appended to the infos *)*/
ae4735db
C
1005jump:
1006 | Tgoto ident_cpp { Goto ($2), [$1] }
34e49164
C
1007 | Tcontinue { Continue, [$1] }
1008 | Tbreak { Break, [$1] }
ae4735db 1009 | Treturn { Return, [$1] }
34e49164
C
1010 | Treturn expr { ReturnExpr $2, [$1] }
1011 | Tgoto TMul expr { GotoComputed $3, [$1;$2] }
1012
1013
1014
1015/*(*----------------------------*)*/
1016/*(* gccext: *)*/
1017/*(*----------------------------*)*/
1018string_elem:
1019 | TString { [snd $1] }
1020 /*(* cppext: ex= printk (KERN_INFO "xxx" UTS_RELEASE) *)*/
485bce71 1021 | TMacroString { [snd $1] }
34e49164
C
1022
1023
ae4735db 1024asmbody:
34e49164
C
1025 | string_list colon_asm_list { $1, $2 }
1026 | string_list { $1, [] } /*(* in old kernel *)*/
1027
1028
1029colon_asm: TDotDot colon_option_list { Colon $2, [$1] }
1030
ae4735db 1031colon_option:
34e49164 1032 | TString { ColonMisc, [snd $1] }
ae4735db 1033 | TString TOPar asm_expr TCPar { ColonExpr $3, [snd $1; $2;$4] }
34e49164
C
1034 /*(* cppext: certainly a macro *)*/
1035 | TOCro identifier TCCro TString TOPar asm_expr TCPar
1036 { ColonExpr $6, [$1;snd $2;$3;snd $4; $5; $7 ] }
1037 | identifier { ColonMisc, [snd $1] }
1038 | /*(* empty *)*/ { ColonMisc, [] }
1039
1040asm_expr: assign_expr { $1 }
1041
34e49164 1042/*(*************************************************************************)*/
485bce71 1043/*(* types *)*/
34e49164 1044/*(*************************************************************************)*/
ae4735db 1045
34e49164 1046
485bce71
C
1047/*(*-----------------------------------------------------------------------*)*/
1048/*(* Type spec, left part of a type *)*/
1049/*(*-----------------------------------------------------------------------*)*/
ae4735db 1050type_spec2:
34e49164
C
1051 | Tvoid { Right3 (BaseType Void), [$1] }
1052 | Tchar { Right3 (BaseType (IntType CChar)), [$1]}
1053 | Tint { Right3 (BaseType (IntType (Si (Signed,CInt)))), [$1]}
1054 | Tfloat { Right3 (BaseType (FloatType CFloat)), [$1]}
1055 | Tdouble { Right3 (BaseType (FloatType CDouble)), [$1] }
1eddfd50
C
1056 | Tsize_t { Right3 (BaseType SizeType), [$1] }
1057 | Tssize_t { Right3 (BaseType SSizeType), [$1] }
1058 | Tptrdiff_t { Right3 (BaseType PtrDiffType), [$1] }
34e49164
C
1059 | Tshort { Middle3 Short, [$1]}
1060 | Tlong { Middle3 Long, [$1]}
1061 | Tsigned { Left3 Signed, [$1]}
1062 | Tunsigned { Left3 UnSigned, [$1]}
1063 | struct_or_union_spec { Right3 (fst $1), snd $1 }
1064 | enum_spec { Right3 (fst $1), snd $1 }
1065
1066 /*
ae4735db
C
1067 (* parse_typedef_fix1: cant put: TIdent {} cos it make the grammar
1068 * ambiguous, generates lots of conflicts => we must
34e49164 1069 * use some tricks: we make the lexer and parser cooperate, cf lexerParser.ml.
ae4735db
C
1070 *
1071 * parse_typedef_fix2: this is not enough, and you must use
34e49164 1072 * parse_typedef_fix2 to fully manage typedef problems in grammar.
ae4735db 1073 *
34e49164 1074 * parse_typedef_fix3:
ae4735db 1075 *
34e49164
C
1076 * parse_typedef_fix4: try also to do now some consistency checking in
1077 * Parse_c
ae4735db
C
1078 *)*/
1079 | TypedefIdent
b1b2de81
C
1080 { let name = RegularName (mk_string_wrap $1) in
1081 Right3 (TypeName (name, Ast_c.noTypedefDef())),[] }
34e49164
C
1082
1083 | Ttypeof TOPar assign_expr TCPar { Right3 (TypeOfExpr ($3)), [$1;$2;$4] }
1084 | Ttypeof TOPar type_name TCPar { Right3 (TypeOfType ($3)), [$1;$2;$4] }
1085
34e49164
C
1086/*(*----------------------------*)*/
1087/*(* workarounds *)*/
1088/*(*----------------------------*)*/
1089
34e49164
C
1090type_spec: type_spec2 { dt "type" (); $1 }
1091
485bce71
C
1092/*(*-----------------------------------------------------------------------*)*/
1093/*(* Qualifiers *)*/
1094/*(*-----------------------------------------------------------------------*)*/
34e49164 1095
ae4735db 1096type_qualif:
485bce71
C
1097 | Tconst { {const=true ; volatile=false}, $1 }
1098 | Tvolatile { {const=false ; volatile=true}, $1 }
1099 /*(* C99 *)*/
1100 | Trestrict { (* TODO *) {const=false ; volatile=false}, $1 }
34e49164
C
1101
1102
1103/*(*-----------------------------------------------------------------------*)*/
485bce71 1104/*(* gccext: attributes *)*/
34e49164 1105/*(*-----------------------------------------------------------------------*)*/
34e49164 1106
485bce71
C
1107attribute:
1108 | Tattribute TOPar /*stuff*/ TCPar { raise Todo }
1109 /*(* cppext: *)*/
1110 | TMacroAttr { Attribute (fst $1), [snd $1] }
34e49164 1111
485bce71
C
1112attribute_storage:
1113 | TMacroAttrStorage { $1 }
34e49164 1114
485bce71
C
1115type_qualif_attr:
1116 | type_qualif { $1 }
91eba41f
C
1117/*(*TODO !!!!! *)*/
1118 | TMacroAttr { {const=true ; volatile=false}, snd $1 }
34e49164 1119
485bce71
C
1120/*(*-----------------------------------------------------------------------*)*/
1121/*(* Declarator, right part of a type + second part of decl (the ident) *)*/
1122/*(*-----------------------------------------------------------------------*)*/
34e49164
C
1123
1124/*
ae4735db
C
1125(* declarator return a couple:
1126 * (name, partial type (a function to be applied to return type))
34e49164
C
1127 *
1128 * when int* f(int) we must return Func(Pointer int,int) and not
ae4735db 1129 * Pointer (Func(int,int)
34e49164
C
1130 *)*/
1131
ae4735db 1132declarator:
34e49164
C
1133 | pointer direct_d { (fst $2, fun x -> x +> $1 +> (snd $2) ) }
1134 | direct_d { $1 }
1135
1136/*(* so must do int * const p; if the pointer is constant, not the pointee *)*/
ae4735db 1137pointer:
f59c9fb7
C
1138 | tmul { fun x -> mk_ty (Pointer x) [$1] }
1139 | tmul pointer { fun x -> mk_ty (Pointer ($2 x)) [$1] }
1140 | tmul type_qualif_list
708f4980 1141 { fun x -> ($2.qualifD, mk_tybis (Pointer x) [$1])}
f59c9fb7 1142 | tmul type_qualif_list pointer
708f4980 1143 { fun x -> ($2.qualifD, mk_tybis (Pointer ($3 x)) [$1]) }
34e49164 1144
f59c9fb7
C
1145tmul:
1146 TMul { $1 }
1147 | TAnd
1148 { if !Flag.c_plus_plus
1149 then $1
1150 else
1151 let i = Ast_c.parse_info_of_info $1 in
1152 raise (Semantic("& not allowed in C types, try -c++ option", i)) }
1153
34e49164 1154
ae4735db 1155direct_d:
708f4980 1156 | identifier_cpp
34e49164 1157 { ($1, fun x -> x) }
ae4735db 1158 | TOPar declarator TCPar /*(* forunparser: old: $2 *)*/
708f4980 1159 { (fst $2, fun x -> mk_ty (ParenType ((snd $2) x)) [$1;$3]) }
ae4735db 1160 | direct_d tocro tccro
708f4980 1161 { (fst $1,fun x->(snd $1) (mk_ty (Array (None,x)) [$2;$3])) }
34e49164 1162 | direct_d tocro const_expr tccro
708f4980 1163 { (fst $1,fun x->(snd $1) (mk_ty (Array (Some $3,x)) [$2;$4])) }
34e49164
C
1164 | direct_d topar tcpar
1165 { (fst $1,
ae4735db 1166 fun x->(snd $1)
708f4980 1167 (mk_ty (FunctionType (x,(([],(false, []))))) [$2;$3]))
34e49164
C
1168 }
1169 | direct_d topar parameter_type_list tcpar
ae4735db
C
1170 { (fst $1,fun x->(snd $1)
1171 (mk_ty (FunctionType (x, $3)) [$2;$4]))
708f4980 1172 }
34e49164
C
1173
1174
485bce71
C
1175/*(*----------------------------*)*/
1176/*(* workarounds *)*/
1177/*(*----------------------------*)*/
1178
1179tocro: TOCro { et "tocro" ();$1 }
1180tccro: TCCro { dt "tccro" ();$1 }
1181
1182/*(*-----------------------------------------------------------------------*)*/
ae4735db 1183abstract_declarator:
485bce71
C
1184 | pointer { $1 }
1185 | direct_abstract_declarator { $1 }
1186 | pointer direct_abstract_declarator { fun x -> x +> $2 +> $1 }
1187
ae4735db 1188direct_abstract_declarator:
485bce71 1189 | TOPar abstract_declarator TCPar /*(* forunparser: old: $2 *)*/
708f4980 1190 { fun x -> mk_ty (ParenType ($2 x)) [$1;$3] }
485bce71 1191
ae4735db 1192 | TOCro TCCro
708f4980 1193 { fun x -> mk_ty (Array (None, x)) [$1;$2] }
ae4735db 1194 | TOCro const_expr TCCro
708f4980 1195 { fun x -> mk_ty (Array (Some $2, x)) [$1;$3] }
ae4735db 1196 | direct_abstract_declarator TOCro TCCro
708f4980 1197 { fun x -> $1 (mk_ty (Array (None, x)) [$2;$3]) }
485bce71 1198 | direct_abstract_declarator TOCro const_expr TCCro
708f4980 1199 { fun x -> $1 (mk_ty (Array (Some $3,x)) [$2;$4]) }
ae4735db 1200 | TOPar TCPar
708f4980 1201 { fun x -> mk_ty (FunctionType (x, ([], (false, [])))) [$1;$2] }
0708f913 1202 | topar parameter_type_list tcpar
708f4980 1203 { fun x -> mk_ty (FunctionType (x, $2)) [$1;$3] }
0708f913
C
1204/*(* subtle: here must also use topar, not TOPar, otherwise if have for
1205 * instance (xxx ( * )(xxx)) cast, then the second xxx may still be a Tident
ae4735db 1206 * but we want to reduce topar, to set the InParameter so that
0708f913
C
1207 * parsing_hack can get a chance to change the type of xxx into a typedef.
1208 * That's an example where parsing_hack and the lookahead of ocamlyacc does
ae4735db 1209 * not go very well together ... we got the info too late. We got
0708f913
C
1210 * a similar pb with xxx xxx; declaration, cf parsing_hack.ml and the
1211 * "disable typedef cos special case ..." message.
1212*)*/
1213 | direct_abstract_declarator topar tcpar
708f4980 1214 { fun x -> $1 (mk_ty (FunctionType (x, (([], (false, []))))) [$2;$3]) }
0708f913 1215 | direct_abstract_declarator topar parameter_type_list tcpar
708f4980 1216 { fun x -> $1 (mk_ty (FunctionType (x, $3)) [$2;$4]) }
485bce71
C
1217
1218/*(*-----------------------------------------------------------------------*)*/
1219/*(* Parameters (use decl_spec not type_spec just for 'register') *)*/
1220/*(*-----------------------------------------------------------------------*)*/
ae4735db 1221parameter_type_list:
34e49164
C
1222 | parameter_list { ($1, (false, []))}
1223 | parameter_list TComma TEllipsis { ($1, (true, [$2;$3])) }
1224
1225
ae4735db 1226parameter_decl2:
97111a47
C
1227 TKRParam {
1228 let name = RegularName (mk_string_wrap $1) in
1229 LP.add_ident (str_of_name name);
1230 { p_namei = Some name;
1231 p_type = mk_ty NoType [];
1232 p_register = (false, []);
1233 }
1234 }
34e49164 1235 | decl_spec declaratorp
b1b2de81
C
1236 { let ((returnType,hasreg),iihasreg) = fixDeclSpecForParam $1 in
1237 let (name, ftyp) = $2 in
1238 { p_namei = Some (name);
1239 p_type = ftyp returnType;
1240 p_register = (hasreg, iihasreg);
1241 }
34e49164 1242 }
485bce71 1243 | decl_spec abstract_declaratorp
ae4735db 1244 { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in
b1b2de81
C
1245 { p_namei = None;
1246 p_type = $2 returnType;
1247 p_register = hasreg, iihasreg;
ae4735db 1248 }
34e49164
C
1249 }
1250 | decl_spec
b1b2de81
C
1251 { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in
1252 { p_namei = None;
1253 p_type = returnType;
1254 p_register = hasreg, iihasreg;
1255 }
34e49164
C
1256 }
1257
1258
1259/*(*----------------------------*)*/
1260/*(* workarounds *)*/
1261/*(*----------------------------*)*/
1262
485bce71 1263parameter_decl: parameter_decl2 { et "param" (); $1 }
708f4980 1264 | attributes parameter_decl2 { et "param" (); $2 }
34e49164 1265
ae4735db 1266declaratorp:
b1b2de81 1267 | declarator { LP.add_ident (str_of_name (fst $1)); $1 }
485bce71 1268 /*(* gccext: *)*/
b1b2de81
C
1269 | attributes declarator { LP.add_ident (str_of_name (fst $2)); $2 }
1270 | declarator attributes { LP.add_ident (str_of_name (fst $1)); $1 }
34e49164 1271
485bce71
C
1272abstract_declaratorp:
1273 | abstract_declarator { $1 }
1274 /*(* gccext: *)*/
1275 | attributes abstract_declarator { $2 }
1276
1277/*(*-----------------------------------------------------------------------*)*/
1278/*(* helper type rules *)*/
1279/*(*-----------------------------------------------------------------------*)*/
1280
1281/*(* for struct and also typename *)*/
1282/*(* cant put decl_spec cos no storage is allowed for field struct *)*/
ae4735db 1283spec_qualif_list2:
485bce71
C
1284 | type_spec { addTypeD ($1, nullDecl) }
1285 | type_qualif { {nullDecl with qualifD = (fst $1,[snd $1])}}
1286 | type_spec spec_qualif_list { addTypeD ($1,$2) }
1287 | type_qualif spec_qualif_list { addQualifD ($1,$2) }
1288
1289spec_qualif_list: spec_qualif_list2 { dt "spec_qualif" (); $1 }
1290
1291
1292/*(* for pointers in direct_declarator and abstract_declarator *)*/
ae4735db 1293type_qualif_list:
485bce71
C
1294 | type_qualif_attr { {nullDecl with qualifD = (fst $1,[snd $1])} }
1295 | type_qualif_list type_qualif_attr { addQualifD ($2,$1) }
34e49164 1296
34e49164
C
1297
1298
485bce71 1299
ae4735db 1300
485bce71
C
1301
1302/*(*-----------------------------------------------------------------------*)*/
1303/*(* xxx_type_id *)*/
34e49164 1304/*(*-----------------------------------------------------------------------*)*/
485bce71 1305
ae4735db
C
1306type_name:
1307 | spec_qualif_list
34e49164 1308 { let (returnType, _) = fixDeclSpecForDecl $1 in returnType }
485bce71 1309 | spec_qualif_list abstract_declaratort
34e49164
C
1310 { let (returnType, _) = fixDeclSpecForDecl $1 in $2 returnType }
1311
1312
34e49164 1313
ae4735db 1314abstract_declaratort:
485bce71
C
1315 | abstract_declarator { $1 }
1316 /*(* gccext: *)*/
1317 | attributes abstract_declarator { $2 }
1318
1319
1320/*(*************************************************************************)*/
1321/*(* declaration and initializers *)*/
1322/*(*************************************************************************)*/
1323
ae4735db 1324decl2:
485bce71
C
1325 | decl_spec TPtVirg
1326 { function local ->
ae4735db 1327 let (returnType,storage) = fixDeclSpecForDecl $1 in
485bce71 1328 let iistart = Ast_c.fakeInfo () in
ae4735db 1329 DeclList ([{v_namei = None; v_type = returnType;
485bce71
C
1330 v_storage = unwrap storage; v_local = local;
1331 v_attr = Ast_c.noattr;
978fd7e5 1332 v_type_bis = ref None;
ae4735db 1333 },[]],
485bce71 1334 ($2::iistart::snd storage))
ae4735db
C
1335 }
1336 | decl_spec init_declarator_list TPtVirg
485bce71
C
1337 { function local ->
1338 let (returnType,storage) = fixDeclSpecForDecl $1 in
1339 let iistart = Ast_c.fakeInfo () in
1340 DeclList (
ae4735db 1341 ($2 +> List.map (fun ((((name,f),attrs), ini), iivirg) ->
b1b2de81 1342 let s = str_of_name name in
ae4735db 1343 if fst (unwrap storage) =*= StoTypedef
485bce71 1344 then LP.add_typedef s;
4dfbc1c2 1345 {v_namei = Some (name, ini);
485bce71
C
1346 v_type = f returnType;
1347 v_storage = unwrap storage;
1348 v_local = local;
1349 v_attr = attrs;
978fd7e5 1350 v_type_bis = ref None;
485bce71 1351 },
ae4735db 1352 iivirg
485bce71
C
1353 )
1354 ), ($3::iistart::snd storage))
ae4735db 1355 }
485bce71
C
1356 /*(* cppext: *)*/
1357
ae4735db 1358 | TMacroDecl TOPar argument_list TCPar TPtVirg
485bce71 1359 { function _ ->
5427db06 1360 MacroDecl ((fst $1, $3, true), [snd $1;$2;$4;$5;fakeInfo()]) }
ae4735db 1361 | Tstatic TMacroDecl TOPar argument_list TCPar TPtVirg
485bce71 1362 { function _ ->
5427db06 1363 MacroDecl ((fst $2, $4, true), [snd $2;$3;$5;$6;fakeInfo();$1]) }
ae4735db 1364 | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar TPtVirg
485bce71 1365 { function _ ->
5427db06 1366 MacroDecl ((fst $3, $5, true), [snd $3;$4;$6;$7;fakeInfo();$1;$2])}
485bce71
C
1367
1368
17ba0788
C
1369 | TMacroDecl TOPar argument_list TCPar teq initialize TPtVirg
1370 { function _ ->
1371 MacroDeclInit ((fst $1, $3, $6), [snd $1;$2;$4;$5;$7;fakeInfo()]) }
1372 | Tstatic TMacroDecl TOPar argument_list TCPar teq initialize TPtVirg
1373 { function _ ->
1374 MacroDeclInit ((fst $2, $4, $7),[snd $2;$3;$5;$6;$8;fakeInfo();$1]) }
1375 | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar
1376 teq initialize TPtVirg
1377 { function _ ->
1378 MacroDeclInit
1379 ((fst $3, $5, $8), [snd $3;$4;$6;$7;$9;fakeInfo();$1;$2])}
1380
1381
485bce71 1382/*(*-----------------------------------------------------------------------*)*/
ae4735db 1383decl_spec2:
485bce71
C
1384 | storage_class_spec { {nullDecl with storageD = (fst $1, [snd $1]) } }
1385 | type_spec { addTypeD ($1,nullDecl) }
1386 | type_qualif { {nullDecl with qualifD = (fst $1, [snd $1]) } }
1387 | Tinline { {nullDecl with inlineD = (true, [$1]) } }
1388 | storage_class_spec decl_spec2 { addStorageD ($1, $2) }
1389 | type_spec decl_spec2 { addTypeD ($1, $2) }
1390 | type_qualif decl_spec2 { addQualifD ($1, $2) }
1391 | Tinline decl_spec2 { addInlineD ((true, $1), $2) }
1392
1393/*(* can simplify by putting all in _opt ? must have at least one otherwise
ae4735db 1394 * decl_list is ambiguous ? (no cos have ';' between decl)
485bce71
C
1395 *)*/
1396
1397
ae4735db 1398storage_class_spec2:
485bce71
C
1399 | Tstatic { Sto Static, $1 }
1400 | Textern { Sto Extern, $1 }
1401 | Tauto { Sto Auto, $1 }
1402 | Tregister { Sto Register,$1 }
1403 | Ttypedef { StoTypedef, $1 }
1404
1405storage_class_spec:
1406 /*(* gccext: *)*/
1407 | storage_class_spec2 { $1 }
708f4980 1408 | storage_class_spec2 attribute_storage_list { $1 (* TODO *) }
485bce71
C
1409
1410
1411
1412/*(*----------------------------*)*/
1413/*(* workarounds *)*/
1414/*(*----------------------------*)*/
1415
1416decl: decl2 { et "decl" (); $1 }
1417decl_spec: decl_spec2 { dt "declspec" (); $1 }
1418
1419/*(*-----------------------------------------------------------------------*)*/
1420/*(* declarators (right part of type and variable) *)*/
1421/*(*-----------------------------------------------------------------------*)*/
ae4735db 1422init_declarator2:
4dfbc1c2
C
1423 | declaratori { ($1, NoInit) }
1424 | declaratori teq initialize { ($1, ValInit($2, $3)) }
1425 /* C++ only */
1426 | declaratori TOParCplusplusInit argument_list TCPar
1427 { ($1, ConstrInit($3,[$2;$4])) }
485bce71
C
1428
1429
1430/*(*----------------------------*)*/
1431/*(* workarounds *)*/
1432/*(*----------------------------*)*/
1433teq: TEq { et "teq" (); $1 }
1434
1435init_declarator: init_declarator2 { dt "init" (); $1 }
1436
1437
1438/*(*----------------------------*)*/
1439/*(* gccext: *)*/
1440/*(*----------------------------*)*/
1441
ae4735db 1442declaratori:
b1b2de81 1443 | declarator { LP.add_ident (str_of_name (fst $1)); $1, Ast_c.noattr }
485bce71 1444 /*(* gccext: *)*/
b1b2de81 1445 | declarator gcc_asm_decl { LP.add_ident (str_of_name (fst $1)); $1, Ast_c.noattr }
485bce71 1446 /*(* gccext: *)*/
b1b2de81
C
1447 | attributes declarator { LP.add_ident (str_of_name (fst $2)); $2, $1 }
1448 | declarator attributes { LP.add_ident (str_of_name (fst $1)); $1, Ast_c.noattr (* TODO *) }
485bce71
C
1449
1450
1451
ae4735db 1452gcc_asm_decl:
485bce71
C
1453 | Tasm TOPar asmbody TCPar { }
1454 | Tasm Tvolatile TOPar asmbody TCPar { }
1455
34e49164 1456
34e49164 1457/*(*-----------------------------------------------------------------------*)*/
ae4735db
C
1458initialize:
1459 | assign_expr
34e49164 1460 { InitExpr $1, [] }
485bce71 1461 | tobrace_ini initialize_list gcc_comma_opt_struct tcbrace_ini
34e49164 1462 { InitList (List.rev $2), [$1;$4]++$3 }
485bce71 1463 | tobrace_ini tcbrace_ini
34e49164
C
1464 { InitList [], [$1;$2] } /*(* gccext: *)*/
1465
1466
1467/*
ae4735db 1468(* opti: This time we use the weird order of non-terminal which requires in
0708f913 1469 * the "caller" to do a List.rev cos quite critical. With this weird order it
34e49164
C
1470 * allows yacc to use a constant stack space instead of exploding if we would
1471 * do a 'initialize2 Tcomma initialize_list'.
1472 *)
1473*/
ae4735db 1474initialize_list:
34e49164
C
1475 | initialize2 { [$1, []] }
1476 | initialize_list TComma initialize2 { ($3, [$2])::$1 }
1477
1478
1479/*(* gccext: condexpr and no assign_expr cos can have ambiguity with comma *)*/
ae4735db
C
1480initialize2:
1481 | cond_expr
1482 { InitExpr $1, [] }
485bce71 1483 | tobrace_ini initialize_list gcc_comma_opt_struct tcbrace_ini
34e49164 1484 { InitList (List.rev $2), [$1;$4]++$3 }
485bce71 1485 | tobrace_ini tcbrace_ini
34e49164
C
1486 { InitList [], [$1;$2] }
1487
1488 /*(* gccext: labeled elements, a.k.a designators *)*/
ae4735db 1489 | designator_list TEq initialize2
34e49164
C
1490 { InitDesignators ($1, $3), [$2] }
1491
1492 /*(* gccext: old format *)*/
1493 | ident TDotDot initialize2
1494 { InitFieldOld (fst $1, $3), [snd $1; $2] } /*(* in old kernel *)*/
ae4735db 1495/* conflict
34e49164
C
1496 | TOCro const_expr TCCro initialize2
1497 { InitIndexOld ($2, $4), [$1;$3] }
485bce71
C
1498*/
1499
1500
34e49164 1501
113803cf 1502/*(* they can be nested, can have a .x[3].y *)*/
ae4735db
C
1503designator:
1504 | TDot ident
1505 { DesignatorField (fst $2), [$1;snd $2] }
1506 | TOCro const_expr TCCro
34e49164 1507 { DesignatorIndex ($2), [$1;$3] }
ae4735db 1508 | TOCro const_expr TEllipsis const_expr TCCro
34e49164
C
1509 { DesignatorRange ($2, $4), [$1;$3;$5] }
1510
1511
1512/*(*----------------------------*)*/
1513/*(* workarounds *)*/
1514/*(*----------------------------*)*/
1515
ae4735db
C
1516gcc_comma_opt_struct:
1517 | TComma { [$1] }
34e49164
C
1518 | /*(* empty *)*/ { [Ast_c.fakeInfo() +> Ast_c.rewrap_str ","] }
1519
1520
34e49164
C
1521
1522
1523
1524
1525
1526
485bce71
C
1527/*(*************************************************************************)*/
1528/*(* struct *)*/
1529/*(*************************************************************************)*/
1530
ae4735db 1531s_or_u_spec2:
34e49164
C
1532 | struct_or_union ident tobrace_struct struct_decl_list_gcc tcbrace_struct
1533 { StructUnion (fst $1, Some (fst $2), $4), [snd $1;snd $2;$3;$5] }
1534 | struct_or_union tobrace_struct struct_decl_list_gcc tcbrace_struct
1535 { StructUnion (fst $1, None, $3), [snd $1;$2;$4] }
ae4735db 1536 | struct_or_union ident
34e49164
C
1537 { StructUnionName (fst $1, fst $2), [snd $1;snd $2] }
1538
ae4735db 1539struct_or_union2:
34e49164
C
1540 | Tstruct { Struct, $1 }
1541 | Tunion { Union, $1 }
485bce71
C
1542 /*(* gccext: *)*/
1543 | Tstruct attributes { Struct, $1 (* TODO *) }
1544 | Tunion attributes { Union, $1 (* TODO *) }
34e49164
C
1545
1546
1547
ae4735db 1548struct_decl2:
708f4980
C
1549 | field_declaration { DeclarationField $1 }
1550 | TPtVirg { EmptyField $1 }
1551
1552 /*(* no conflict ? no need for a TMacroStruct ? apparently not as at struct
1553 * the rule are slightly different.
1554 *)*/
1555 | identifier TOPar argument_list TCPar TPtVirg
1556 { MacroDeclField ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) }
485bce71
C
1557
1558 /*(* cppext: *)*/
ae4735db 1559 | cpp_directive
708f4980 1560 { CppDirectiveStruct $1 }
ae4735db 1561 | cpp_ifdef_directive/*(* struct_decl_list ... *)*/
708f4980 1562 { IfdefStruct $1 }
485bce71
C
1563
1564
1565field_declaration:
ae4735db
C
1566 | spec_qualif_list struct_declarator_list TPtVirg
1567 {
34e49164 1568 let (returnType,storage) = fixDeclSpecForDecl $1 in
ae4735db 1569 if fst (unwrap storage) <> NoSto
34e49164 1570 then internal_error "parsing dont allow this";
ae4735db
C
1571
1572 FieldDeclList ($2 +> (List.map (fun (f, iivirg) ->
34e49164 1573 f returnType, iivirg))
485bce71 1574 ,[$3])
34e49164 1575 (* dont need to check if typedef or func initialised cos
ae4735db 1576 * grammar dont allow typedef nor initialiser in struct
34e49164
C
1577 *)
1578 }
1579
abad11c5 1580 | spec_qualif_list TPtVirg
ae4735db 1581 {
34e49164
C
1582 (* gccext: allow empty elements if it is a structdef or enumdef *)
1583 let (returnType,storage) = fixDeclSpecForDecl $1 in
ae4735db 1584 if fst (unwrap storage) <> NoSto
34e49164 1585 then internal_error "parsing dont allow this";
ae4735db 1586
b1b2de81 1587 FieldDeclList ([(Simple (None, returnType)) , []], [$2])
34e49164 1588 }
485bce71
C
1589
1590
34e49164
C
1591
1592
1593
ae4735db
C
1594struct_declarator:
1595 | declaratorsd
b1b2de81 1596 { (fun x -> Simple (Some (fst $1), (snd $1) x)) }
ae4735db 1597 | dotdot const_expr2
b1b2de81 1598 { (fun x -> BitField (None, x, $1, $2)) }
ae4735db 1599 | declaratorsd dotdot const_expr2
b1b2de81 1600 { (fun x -> BitField (Some (fst $1), ((snd $1) x), $2, $3)) }
34e49164
C
1601
1602
1603/*(*----------------------------*)*/
1604/*(* workarounds *)*/
1605/*(*----------------------------*)*/
ae4735db 1606declaratorsd:
485bce71
C
1607 | declarator { (*also ? LP.add_ident (fst (fst $1)); *) $1 }
1608 /*(* gccext: *)*/
1609 | attributes declarator { $2 }
1610 | declarator attributes { $1 }
34e49164 1611
34e49164
C
1612
1613
1614
1615struct_or_union_spec: s_or_u_spec2 { dt "su" (); $1 }
1616struct_or_union: struct_or_union2 { et "su" (); $1 }
1617struct_decl: struct_decl2 { et "struct" (); $1 }
1618
1619dotdot: TDotDot { et "dotdot" (); $1 }
1620const_expr2: const_expr { dt "const_expr2" (); $1 }
1621
ae4735db
C
1622struct_decl_list_gcc:
1623 | struct_decl_list { $1 }
34e49164
C
1624 | /*(* empty *)*/ { [] } /*(* gccext: allow empty struct *)*/
1625
1626
485bce71
C
1627/*(*************************************************************************)*/
1628/*(* enum *)*/
1629/*(*************************************************************************)*/
ae4735db 1630enum_spec:
c491d8ee 1631 | Tenum tobrace_enum enumerator_list gcc_comma_opt_struct tcbrace_enum
34e49164 1632 { Enum (None, $3), [$1;$2;$5] ++ $4 }
c491d8ee 1633 | Tenum ident tobrace_enum enumerator_list gcc_comma_opt_struct tcbrace_enum
34e49164 1634 { Enum (Some (fst $2), $4), [$1; snd $2; $3;$6] ++ $5 }
ae4735db 1635 | Tenum ident
34e49164
C
1636 { EnumName (fst $2), [$1; snd $2] }
1637
ae4735db 1638enumerator:
b1b2de81
C
1639 | idente { $1, None }
1640 | idente TEq const_expr { $1, Some ($2, $3) }
34e49164
C
1641
1642
1643/*(*----------------------------*)*/
1644/*(* workarounds *)*/
1645/*(*----------------------------*)*/
1646
b1b2de81 1647idente: ident_cpp { LP.add_ident (str_of_name $1); $1 }
34e49164 1648
34e49164
C
1649
1650
1651/*(*************************************************************************)*/
485bce71 1652/*(* function *)*/
34e49164 1653/*(*************************************************************************)*/
485bce71 1654function_definition: function_def { fixFunc $1 }
34e49164 1655
ae4735db 1656decl_list:
91eba41f
C
1657 | decl { [$1 Ast_c.LocalDecl] }
1658 | decl_list decl { $1 ++ [$2 Ast_c.LocalDecl] }
34e49164 1659
9f8e26f4 1660/* hack : to drop when a better solution is found */
ae4735db 1661cpp_directive_list:
9f8e26f4
C
1662 | cpp_directive { }
1663 | cpp_directive_list cpp_directive { }
1664
ae4735db 1665function_def:
91eba41f 1666 | start_fun compound { LP.del_scope(); ($1, $2, None) }
9f8e26f4 1667 | start_fun cpp_directive_list compound { LP.del_scope(); ($1, $3, None) }
ae4735db 1668 | start_fun decl_list compound {
485bce71 1669 (* TODO: undo the typedef added ? *)
ae4735db 1670 LP.del_scope();
91eba41f 1671 ($1, $3, Some $2)
485bce71
C
1672 }
1673
ae4735db
C
1674start_fun: start_fun2
1675 { LP.new_scope();
1676 fix_add_params_ident $1;
485bce71 1677 (* toreput? !LP._lexer_hint.toplevel <- false; *)
ae4735db 1678 $1
485bce71
C
1679 }
1680
ae4735db 1681start_fun2: decl_spec declaratorfd
485bce71
C
1682 { let (returnType,storage) = fixDeclSpecForFuncDef $1 in
1683 let (id, attrs) = $2 in
ae4735db 1684 (fst id, fixOldCDecl ((snd id) returnType) , storage, attrs)
485bce71 1685 }
f59c9fb7
C
1686 | ctor_dtor { $1 }
1687
1688ctor_dtor:
1689 | Tconstructorname topar tcpar {
1690 let id = RegularName (mk_string_wrap $1) in
1691 let ret = mk_ty NoType [] in
1692 let ty = mk_ty (FunctionType (ret, (([], (false, []))))) [$2;$3] in
1693 let storage = ((NoSto,false),[]) in
1694 let attrs = [] in
1695 (id, ty, storage, attrs) }
1696 | Tconstructorname topar parameter_type_list tcpar {
1697 let id = RegularName (mk_string_wrap $1) in
1698 let ret = mk_ty NoType [] in
1699 let ty = mk_ty (FunctionType (ret, $3)) [$2;$4] in
1700 let storage = ((NoSto,false),[]) in
1701 let attrs = [] in
1702 (id, ty, storage, attrs) }
485bce71
C
1703
1704/*(*----------------------------*)*/
1705/*(* workarounds *)*/
1706/*(*----------------------------*)*/
1707
5636bb2c
C
1708/* It would be very nice if we could make declarator aware that this is
1709coming from a function definition. Then on the ( and ) cases, it could
1710set the state to something other than InParameter. Then the case
1711(TIdent (s, i1)::(TComma _|TCPar _)::_ , (TComma _ |TOPar _)::_ )
1712in parsing_hacks.ml would not have to consider K&R variable declarations
1713as typedefs. Unfortunately, doing something about this problem seems to
1714introduce conflicts in the parser. */
1715
ae4735db 1716declaratorfd:
485bce71
C
1717 | declarator { et "declaratorfd" (); $1, Ast_c.noattr }
1718 /*(* gccext: *)*/
1719 | attributes declarator { et "declaratorfd" (); $2, $1 }
1720 | declarator attributes { et "declaratorfd" (); $1, Ast_c.noattr }
1721
1722
1723
1724/*(*************************************************************************)*/
1725/*(* cpp directives *)*/
1726/*(*************************************************************************)*/
1727
ae4735db
C
1728cpp_directive:
1729 | TIncludeStart TIncludeFilename
1730 {
485bce71
C
1731 let (i1, in_ifdef) = $1 in
1732 let (s, i2) = $2 in
1733
1734 (* redo some lexing work :( *)
ae4735db 1735 let inc_file =
485bce71 1736 match () with
ae4735db 1737 | _ when s =~ "^\"\\(.*\\)\"$" ->
485bce71 1738 Local (Common.split "/" (matched1 s))
ae4735db 1739 | _ when s =~ "^\\<\\(.*\\)\\>$" ->
485bce71 1740 NonLocal (Common.split "/" (matched1 s))
ae4735db
C
1741 | _ ->
1742 Weird s
485bce71
C
1743 in
1744 Include { i_include = (inc_file, [i1;i2]);
1745 i_rel_pos = Ast_c.noRelPos();
1746 i_is_in_ifdef = !in_ifdef;
1747 i_content = Ast_c.noi_content;
1748 }
1749 }
1750
ae4735db 1751 | TDefine TIdentDefine define_val TDefEOL
485bce71
C
1752 { Define ((fst $2, [$1; snd $2;$4]), (DefineVar, $3)) }
1753
1754 /*
1755 (* The TOParDefine is introduced to avoid ambiguity with previous rules.
1756 * A TOParDefine is a TOPar that was just next to the ident.
1757 *)*/
1758 | TDefine TIdentDefine TOParDefine param_define_list TCPar define_val TDefEOL
ae4735db 1759 { Define
3a314143 1760 ((fst $2, [$1; snd $2; $7]),
ae4735db 1761 (DefineFunc ($4, [$3;$5]), $6))
485bce71
C
1762 }
1763
3a314143
C
1764 | TUndef TIdentDefine TDefEOL
1765 { Define((fst $2, [$1; snd $2; $3]), (Undef,DefineEmpty)) }
485bce71
C
1766 | TCppDirectiveOther { PragmaAndCo ([$1]) }
1767
b1b2de81
C
1768
1769
1770
1771
ae4735db 1772/*(* perhaps better to use assign_expr ? but in that case need
485bce71
C
1773 * do a assign_expr_of_string in parse_c
1774 *)*/
ae4735db 1775define_val:
485bce71
C
1776 | expr { DefineExpr $1 }
1777 | statement { DefineStmt $1 }
708f4980
C
1778 | decl { DefineStmt (mk_st (Decl ($1 Ast_c.NotLocalDecl)) Ast_c.noii) }
1779
ae4735db 1780/*(*old:
708f4980 1781 * | TypedefIdent { DefineType (nQ,(TypeName(fst $1,noTypedefDef()),[snd $1]))}
ae4735db 1782 * get conflicts:
708f4980
C
1783 * | spec_qualif_list TMul
1784 * { let (returnType, _) = fixDeclSpecForDecl $1 in DefineType returnType }
1785 *)
1786*/
ae4735db
C
1787 | decl_spec
1788 { let returnType = fixDeclSpecForMacro $1 in
708f4980
C
1789 DefineType returnType
1790 }
ae4735db
C
1791 | decl_spec abstract_declarator
1792 { let returnType = fixDeclSpecForMacro $1 in
708f4980
C
1793 let typ = $2 returnType in
1794 DefineType typ
1795 }
1796
abad11c5 1797/*(* can be in conflict with decl_spec, maybe change fixDeclSpecForMacro
708f4980
C
1798 * to also allow storage ?
1799 | storage_class_spec { DefineTodo }
1800 | Tinline { DefineTodo }
abad11c5 1801*)*/
708f4980 1802
abad11c5
C
1803 | stat_or_decl stat_or_decl_list
1804 { DefineMulti
1805 (List.map
1806 (function
1807 StmtElem e -> e
1808 | _ -> failwith "unexpected statement for DefineMulti")
1809 ($1 :: $2)) }
1810/*(*
708f4980
C
1811 | statement statement { DefineTodo }
1812 | decl function_definition { DefineTodo }
abad11c5 1813*)*/
708f4980
C
1814
1815
1816
485bce71 1817
485bce71
C
1818 | function_definition { DefineFunction $1 }
1819
ae4735db 1820 | TOBraceDefineInit initialize_list gcc_comma_opt_struct TCBrace comma_opt
485bce71
C
1821 { DefineInit (InitList (List.rev $2), [$1;$4]++$3++$5) }
1822
1823 /*(* note: had a conflict before when were putting TInt instead of expr *)*/
ae4735db 1824 | Tdo statement Twhile TOPar expr TCPar
485bce71 1825 {
ae4735db
C
1826 (* TOREPUT
1827 if fst $5 <> "0"
0708f913 1828 then pr2 "WEIRD: in macro and have not a while(0)";
485bce71
C
1829 *)
1830 DefineDoWhileZero (($2,$5), [$1;$3;$4;$6])
1831 }
1832
485bce71
C
1833 | Tasm TOPar asmbody TCPar { DefineTodo }
1834 | Tasm Tvolatile TOPar asmbody TCPar { DefineTodo }
1835
485bce71
C
1836 /*(* aliases macro *)*/
1837 | TMacroAttr { DefineTodo }
485bce71
C
1838
1839 | /*(* empty *)*/ { DefineEmpty }
1840
1841
b1b2de81
C
1842
1843
485bce71 1844param_define:
ae4735db
C
1845 | TIdent { mk_string_wrap $1 }
1846 | TypedefIdent { mk_string_wrap $1 }
1847 | TDefParamVariadic { mk_string_wrap $1 }
485bce71
C
1848 | TEllipsis { "...", [$1] }
1849 /*(* they reuse keywords :( *)*/
1850 | Tregister { "register", [$1] }
1851
1852
1853
1854
ae4735db
C
1855cpp_ifdef_directive:
1856 | TIfdef
1857 { let (tag,ii) = $1 in
485bce71 1858 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1859 | TIfdefelse
1860 { let (tag,ii) = $1 in
485bce71 1861 IfdefDirective ((IfdefElse, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1862 | TIfdefelif
1863 { let (tag,ii) = $1 in
485bce71 1864 IfdefDirective ((IfdefElseif, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1865 | TEndif
1866 { let (tag,ii) = $1 in
485bce71
C
1867 IfdefDirective ((IfdefEndif, IfdefTag (Common.some !tag)), [ii]) }
1868
ae4735db
C
1869 | TIfdefBool
1870 { let (_b, tag,ii) = $1 in
485bce71 1871 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1872 | TIfdefMisc
1873 { let (_b, tag,ii) = $1 in
485bce71 1874 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1875 | TIfdefVersion
1876 { let (_b, tag,ii) = $1 in
485bce71
C
1877 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
1878
1879
1880/*(* cppext: *)*/
ae4735db 1881cpp_other:
485bce71
C
1882 /*(* no conflict ? no need for a TMacroTop ? apparently not as at toplevel
1883 * the rule are slightly different, they cant be statement and so expr
1884 * at the top, only decl or function definition.
1885 *)*/
1886 | identifier TOPar argument_list TCPar TPtVirg
ae4735db 1887 {
5427db06 1888 Declaration(MacroDecl((fst $1, $3, true), [snd $1;$2;$4;$5;fakeInfo()]))
708f4980
C
1889 (* old: MacroTop (fst $1, $3, [snd $1;$2;$4;$5]) *)
1890 }
485bce71
C
1891
1892 /*(* TCParEOL to fix the end-of-stream bug of ocamlyacc *)*/
1893 | identifier TOPar argument_list TCParEOL
5427db06 1894 { Declaration (MacroDecl ((fst $1, $3, false), [snd $1;$2;$4;fakeInfo()])) }
485bce71
C
1895
1896 /*(* ex: EXPORT_NO_SYMBOLS; *)*/
1897 | identifier TPtVirg { EmptyDef [snd $1;$2] }
1898
1899
1900
1901/*(*************************************************************************)*/
1902/*(* celem *)*/
1903/*(*************************************************************************)*/
1904
ae4735db 1905external_declaration:
485bce71
C
1906 | function_definition { Definition $1 }
1907 | decl { Declaration ($1 Ast_c.NotLocalDecl) }
1908
1909
ae4735db 1910celem:
1b9ae606
C
1911 | Tnamespace TIdent TOBrace translation_unit TCBrace
1912 { !LP._lexer_hint.context_stack <- [LP.InTopLevel];
1913 Namespace ($4, [$1; snd $2; $3; $5]) }
1914
1915 | external_declaration { $1 }
485bce71
C
1916
1917 /*(* cppext: *)*/
ae4735db 1918 | cpp_directive
485bce71 1919 { CppTop $1 }
ae4735db 1920 | cpp_other
485bce71
C
1921 { $1 }
1922 | cpp_ifdef_directive /* (*external_declaration_list ...*)*/
1923 { IfdefTop $1 }
1924
1925 /*(* can have asm declaration at toplevel *)*/
ae4735db 1926 | Tasm TOPar asmbody TCPar TPtVirg { EmptyDef [$1;$2;$4;$5] }
485bce71
C
1927
1928 /*
1929 (* in ~/kernels/src/linux-2.5.2/drivers/isdn/hisax/isdnl3.c sometimes
ae4735db 1930 * the function ends with }; instead of just }
485bce71
C
1931 * can also remove this rule and report "parse error" pb to morton
1932 *)*/
ae4735db
C
1933 | TPtVirg { EmptyDef [$1] }
1934
485bce71 1935
ae4735db 1936 | EOF { FinalDef $1 }
485bce71
C
1937
1938
1939
1940
1941/*(*************************************************************************)*/
1942/*(* some generic workarounds *)*/
1943/*(*************************************************************************)*/
1944
1945tobrace: TOBrace { LP.push_context LP.InFunction; LP.new_scope (); $1 }
1946tcbrace: TCBrace { LP.pop_context(); LP.del_scope (); $1 }
1947
1948tobrace_enum: TOBrace { LP.push_context LP.InEnum; $1 }
1949tcbrace_enum: TCBrace { LP.pop_context (); $1 }
1950
1951tobrace_ini: TOBrace { LP.push_context LP.InInitializer; $1 }
1952tcbrace_ini: TCBrace { LP.pop_context (); $1 }
1953
1954tobrace_struct: TOBrace { LP.push_context LP.InStruct; $1}
1955tcbrace_struct: TCBrace { LP.pop_context (); $1 }
1956
1957
1958
1959
ae4735db
C
1960topar: TOPar
1961 { LP.new_scope ();et "topar" ();
485bce71 1962 LP.push_context LP.InParameter;
ae4735db 1963 $1
485bce71 1964 }
ae4735db
C
1965tcpar: TCPar
1966 { LP.del_scope ();dt "tcpar" ();
1967 LP.pop_context ();
1968 $1
485bce71
C
1969 }
1970
1971
1972
1973
1974/*(*************************************************************************)*/
1975/*(* xxx_list, xxx_opt *)*/
1976/*(*************************************************************************)*/
1977
1978
1979/*(* old:
ae4735db 1980compound2:
485bce71
C
1981 | { ([],[]) }
1982 | statement_list { ([], $1) }
1983 | decl_list { ($1, []) }
1984 | decl_list statement_list { ($1,$2) }
1985
1986statement_list: stat_or_decl_list { $1 }
1987*)*/
1988
1989
1990/*(*
ae4735db 1991decl_list:
485bce71
C
1992 | decl { [$1] }
1993 | decl_list decl { $1 ++ [$2] }
1994
ae4735db 1995statement_list:
485bce71
C
1996 | statement { [$1] }
1997 | statement_list statement { $1 ++ [$2] }
1998*)*/
34e49164 1999
34e49164
C
2000
2001
2002
2003
ae4735db 2004string_list:
34e49164 2005 | string_elem { $1 }
ae4735db 2006 | string_list string_elem { $1 ++ $2 }
34e49164 2007
ae4735db 2008colon_asm_list:
34e49164
C
2009 | colon_asm { [$1] }
2010 | colon_asm_list colon_asm { $1 ++ [$2] }
2011
ae4735db
C
2012colon_option_list:
2013 | colon_option { [$1, []] }
34e49164
C
2014 | colon_option_list TComma colon_option { $1 ++ [$3, [$2]] }
2015
2016
ae4735db 2017argument_list_ne:
34e49164
C
2018 | argument_ne { [$1, []] }
2019 | argument_list_ne TComma argument { $1 ++ [$3, [$2]] }
2020
ae4735db 2021argument_list:
34e49164
C
2022 | argument { [$1, []] }
2023 | argument_list TComma argument { $1 ++ [$3, [$2]] }
2024
2025/*(*
2026expression_list:
2027 | assign_expr { [$1, []] }
2028 | expression_list TComma assign_expr { $1 ++ [$3, [$2]] }
2029*)*/
2030
2031
ae4735db 2032struct_decl_list:
34e49164
C
2033 | struct_decl { [$1] }
2034 | struct_decl_list struct_decl { $1 ++ [$2] }
2035
2036
ae4735db 2037struct_declarator_list:
34e49164
C
2038 | struct_declarator { [$1, []] }
2039 | struct_declarator_list TComma struct_declarator { $1 ++ [$3, [$2]] }
2040
2041
ae4735db 2042enumerator_list:
34e49164
C
2043 | enumerator { [$1, []] }
2044 | enumerator_list TComma enumerator { $1 ++ [$3, [$2]] }
2045
2046
ae4735db 2047init_declarator_list:
34e49164
C
2048 | init_declarator { [$1, []] }
2049 | init_declarator_list TComma init_declarator { $1 ++ [$3, [$2]] }
2050
2051
ae4735db 2052parameter_list:
34e49164
C
2053 | parameter_decl { [$1, []] }
2054 | parameter_list TComma parameter_decl { $1 ++ [$3, [$2]] }
2055
ae4735db 2056taction_list_ne:
34e49164
C
2057 | TAction { [$1] }
2058 | TAction taction_list_ne { $1 :: $2 }
2059
ae4735db
C
2060taction_list:
2061/*old: was generating conflict, hence now taction_list_ne
485bce71
C
2062 | (* empty *) { [] }
2063 | TAction { [$1] }
2064 | taction_list TAction { $1 ++ [$2] }
2065*/
34e49164
C
2066 | { [] }
2067 | TAction taction_list { $1 :: $2 }
2068
ae4735db 2069param_define_list:
34e49164
C
2070 | /*(* empty *)*/ { [] }
2071 | param_define { [$1, []] }
2072 | param_define_list TComma param_define { $1 ++ [$3, [$2]] }
2073
ae4735db 2074designator_list:
34e49164
C
2075 | designator { [$1] }
2076 | designator_list designator { $1 ++ [$2] }
2077
485bce71
C
2078attribute_list:
2079 | attribute { [$1] }
2080 | attribute_list attribute { $1 ++ [$2] }
2081
2082attribute_storage_list:
2083 | attribute_storage { [$1] }
2084 | attribute_storage_list attribute_storage { $1 ++ [$2] }
2085
2086
2087attributes: attribute_list { $1 }
2088
485bce71 2089
34e49164
C
2090
2091/*(* gccext: which allow a trailing ',' in enum, as in perl *)*/
ae4735db
C
2092gcc_comma_opt:
2093 | TComma { [$1] }
34e49164
C
2094 | /*(* empty *)*/ { [] }
2095
ae4735db
C
2096comma_opt:
2097 | TComma { [$1] }
485bce71
C
2098 | /*(* empty *)*/ { [] }
2099
34e49164
C
2100/*(*
2101gcc_opt_virg:
2102 | TPtVirg { }
2103 | { }
2104*)*/
2105
ae4735db 2106gcc_opt_expr:
34e49164
C
2107 | expr { Some $1 }
2108 | /*(* empty *)*/ { None }
2109
2110/*(*
2111opt_ptvirg:
2112 | TPtVirg { [$1] }
2113 | { [] }
2114*)*/
2115
2116