Coccinelle release 0.2.5-rc7.
[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 *)
23
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
72 | _ -> raise Impossible
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
ae4735db 101 | ((Right3 t,ii), ({typeD = ((a,b,Some _),ii2)} as _v)) ->
34e49164 102 raise (Semantic ("two or more data types", 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 | _ ->
708f4980
C
234 pr2 ("SEMANTIC:parameter name omitted, but I continue");
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 *)
ae4735db 243 pr2 ("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
f59c9fb7 403%token <string * Ast_c.info> Tconstructorname /* parsing_hack for c++ */
485bce71
C
404/*(* appears mostly after some fix_xxx in parsing_hack *)*/
405%token <string * Ast_c.info> TypedefIdent
34e49164
C
406
407
408/*
ae4735db 409(* Some tokens like TOPar and TCPar are used as synchronisation stuff,
34e49164 410 * in parsing_hack.ml. So if define special tokens like TOParDefine and
485bce71 411 * TCParEOL, then take care to also modify in Token_helpers.
34e49164
C
412 *)
413*/
ae4735db
C
414
415%token <Ast_c.info> TOPar TCPar TOBrace TCBrace TOCro TCCro
416%token <Ast_c.info> TDot TComma TPtrOp
34e49164 417%token <Ast_c.info> TInc TDec
ae4735db 418%token <Ast_c.assignOp * Ast_c.info> TAssign
34e49164
C
419%token <Ast_c.info> TEq
420%token <Ast_c.info> TWhy TTilde TBang
421%token <Ast_c.info> TEllipsis
422%token <Ast_c.info> TDotDot
423
424%token <Ast_c.info> TPtVirg
ae4735db 425%token <Ast_c.info>
34e49164 426 TOrLog TAndLog TOr TXor TAnd TEqEq TNotEq TInf TSup TInfEq TSupEq
ae4735db
C
427 TShl TShr
428 TPlus TMinus TMul TDiv TMod
34e49164
C
429
430%token <Ast_c.info>
431 Tchar Tshort Tint Tdouble Tfloat Tlong Tunsigned Tsigned Tvoid
1eddfd50 432 Tsize_t Tssize_t Tptrdiff_t
ae4735db
C
433 Tauto Tregister Textern Tstatic
434 Ttypedef
34e49164 435 Tconst Tvolatile
ae4735db 436 Tstruct Tunion Tenum
34e49164
C
437 Tbreak Telse Tswitch Tcase Tcontinue Tfor Tdo Tif Twhile Treturn
438 Tgoto Tdefault
4dfbc1c2 439 Tsizeof Tnew Tdelete TOParCplusplusInit
34e49164 440
485bce71
C
441/*(* C99 *)*/
442%token <Ast_c.info>
443 Trestrict
444
445/*(*-----------------------------------------*)*/
34e49164 446/*(* gccext: extra tokens *)*/
485bce71 447/*(*-----------------------------------------*)*/
34e49164
C
448%token <Ast_c.info> Tasm
449%token <Ast_c.info> Tattribute
978fd7e5 450%token <Ast_c.info> TattributeNoarg
34e49164
C
451%token <Ast_c.info> Tinline
452%token <Ast_c.info> Ttypeof
453
485bce71
C
454/*(*-----------------------------------------*)*/
455/*(* cppext: extra tokens *)*/
456/*(*-----------------------------------------*)*/
457/*(* coupling with Token_helpers.is_cpp_token *)*/
458
459
460/*(*---------------*)*/
461/*(* define *)*/
462/*(*---------------*)*/
463
464%token <Ast_c.info> TDefine
465%token <(string * Ast_c.info)> TDefParamVariadic
466
467/*(* disappear after fix_tokens_define *)*/
ae4735db 468%token <Ast_c.info> TCppEscapedNewline
485bce71 469
b1b2de81
C
470%token <Ast_c.info> TCppConcatOp
471
485bce71 472/*(* appear after fix_tokens_define *)*/
ae4735db 473%token <Ast_c.info> TOParDefine
485bce71
C
474%token <Ast_c.info> TOBraceDefineInit
475
476%token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/
477%token <Ast_c.info> TDefEOL /*(* same *)*/
478
479
480/*(*---------------*)*/
481/*(* include *)*/
482/*(*---------------*)*/
483
484
485/*(* used only in lexer_c, then transformed in comment or splitted in tokens *)*/
486%token <(string * string * bool ref * Ast_c.info)> TInclude
487
488/*(* tokens coming from above, generated in parse_c from TInclude, etc *)*/
489%token <(Ast_c.info * bool ref)> TIncludeStart
490%token <(string * Ast_c.info)> TIncludeFilename
491
492
493/*(*---------------*)*/
494/*(* ifdef *)*/
495/*(*---------------*)*/
496
497/*(* coupling: Token_helpers.is_cpp_instruction *)*/
ae4735db 498%token <((int * int) option ref * Ast_c.info)>
485bce71 499 TIfdef TIfdefelse TIfdefelif TEndif
ae4735db 500%token <(bool * (int * int) option ref * Ast_c.info)>
485bce71
C
501 TIfdefBool TIfdefMisc TIfdefVersion
502
503/*(*---------------*)*/
504/*(* other *)*/
505/*(*---------------*)*/
506
3a314143 507%token <Ast_c.info> TUndef
485bce71
C
508
509%token <Ast_c.info> TCppDirectiveOther
510
511/*(*---------------*)*/
512/*(* macro use *)*/
513/*(*---------------*)*/
514
515/*(* appear after fix_tokens_cpp, cf also parsing_hacks#hint *)*/
516
517%token <(string * Ast_c.info)> TMacroAttr
518%token <(string * Ast_c.info)> TMacroStmt
b1b2de81 519%token <(string * Ast_c.info)> TMacroIdentBuilder
485bce71 520/*(* no need value for the moment *)*/
ae4735db 521%token <(string * Ast_c.info)> TMacroString
485bce71 522%token <(string * Ast_c.info)> TMacroDecl
ae4735db 523%token <Ast_c.info> TMacroDeclConst
708f4980 524
485bce71 525%token <(string * Ast_c.info)> TMacroIterator
ae4735db
C
526/*(*
527%token <(string * Ast_c.info)> TMacroTop
708f4980
C
528%token <(string * Ast_c.info)> TMacroStructDecl
529*)*/
485bce71
C
530
531%token <(string * Ast_c.info)> TMacroAttrStorage
532
533
534/*(*---------------*)*/
535/*(* other *)*/
536/*(*---------------*)*/
537
0708f913
C
538
539/*(* should disappear after parsing_hack *)*/
540%token <Ast_c.info> TCommentSkipTagStart TCommentSkipTagEnd
541
542
485bce71 543/*(* appear after parsing_hack *)*/
ae4735db 544%token <Ast_c.info> TCParEOL
485bce71
C
545
546%token <Ast_c.info> TAction
547
548
0708f913 549/*(* TCommentMisc still useful ? obsolete ? *)*/
485bce71 550%token <Ast_c.info> TCommentMisc
0708f913 551%token <(Token_c.cppcommentkind * Ast_c.info)> TCommentCpp
485bce71 552
34e49164 553
485bce71 554/*(*-----------------------------------------*)*/
34e49164
C
555%token <Ast_c.info> EOF
556
485bce71
C
557/*(*-----------------------------------------*)*/
558
559/*(* must be at the top so that it has the lowest priority *)*/
560%nonassoc SHIFTHERE
34e49164 561
34e49164
C
562%nonassoc Telse
563
564%left TOrLog
565%left TAndLog
566%left TOr
567%left TXor
ae4735db 568%left TAnd
34e49164 569%left TEqEq TNotEq
ae4735db 570%left TInf TSup TInfEq TSupEq
34e49164
C
571%left TShl TShr
572%left TPlus TMinus
ae4735db 573%left TMul TDiv TMod
34e49164 574
485bce71
C
575/*(*************************************************************************)*/
576/*(* Rules type declaration *)*/
577/*(*************************************************************************)*/
578
34e49164
C
579%start main celem statement expr type_name
580%type <Ast_c.program> main
581%type <Ast_c.toplevel> celem
582
583%type <Ast_c.statement> statement
584%type <Ast_c.expression> expr
585%type <Ast_c.fullType> type_name
586
587%%
588/*(*************************************************************************)*/
589/*
590(* TOC:
485bce71 591 * toplevel (obsolete)
ae4735db 592 *
485bce71 593 * ident
34e49164
C
594 * expression
595 * statement
ae4735db
C
596 * types with
597 * - left part (type_spec, qualif),
485bce71
C
598 * - right part (declarator, abstract declarator)
599 * - aux part (parameters)
600 * declaration, storage, initializers
601 * struct
602 * enum
34e49164
C
603 * cpp directives
604 * celem (=~ main)
ae4735db 605 *
485bce71
C
606 * generic workarounds (obrace, cbrace for context setting)
607 * xxx_list, xxx_opt
34e49164
C
608 *)
609*/
610/*(*************************************************************************)*/
611
485bce71
C
612/*(*************************************************************************)*/
613/*(* toplevel *)*/
614/*(*************************************************************************)*/
34e49164
C
615/*(* no more used; now that use error recovery *)*/
616
f59c9fb7
C
617main:
618 translation_unit EOF { $1 }
34e49164 619
ae4735db
C
620translation_unit:
621 | external_declaration
485bce71 622 { !LP._lexer_hint.context_stack <- [LP.InTopLevel]; [$1] }
34e49164 623 | translation_unit external_declaration
485bce71
C
624 { !LP._lexer_hint.context_stack <- [LP.InTopLevel]; $1 ++ [$2] }
625
626
627
628/*(*************************************************************************)*/
629/*(* ident *)*/
630/*(*************************************************************************)*/
631
ae4735db 632/*(* Why this ? Why not s/ident/TIdent ? cos there is multiple namespaces in C,
485bce71
C
633 * so a label can have the same name that a typedef, same for field and tags
634 * hence sometimes the use of ident instead of TIdent.
635 *)*/
ae4735db 636ident:
485bce71
C
637 | TIdent { $1 }
638 | TypedefIdent { $1 }
34e49164
C
639
640
485bce71
C
641identifier:
642 | TIdent { $1 }
34e49164 643
b1b2de81 644/*
ae4735db 645(* cppext: string concatenation of idents
b1b2de81
C
646 * also cppext: gccext: ##args for variadic macro
647 *)
648*/
708f4980 649identifier_cpp:
ae4735db 650 | TIdent
b1b2de81 651 { RegularName (mk_string_wrap $1) }
708f4980
C
652 | ident_extra_cpp { $1 }
653
654ident_cpp:
655 | TIdent
656 { RegularName (mk_string_wrap $1) }
ae4735db 657 | TypedefIdent
708f4980
C
658 { RegularName (mk_string_wrap $1) }
659 | ident_extra_cpp { $1 }
660
661ident_extra_cpp:
ae4735db
C
662 | TIdent TCppConcatOp identifier_cpp_list
663 {
b1b2de81
C
664 CppConcatenatedName (
665 match $3 with
666 | [] -> raise Impossible
ae4735db 667 | (x,concatnull)::xs ->
b1b2de81
C
668 assert(null concatnull);
669 (mk_string_wrap $1, [])::(x,[$2])::xs
670 )
671 }
ae4735db 672 | TCppConcatOp TIdent
b1b2de81
C
673 { CppVariadicName (fst $2, [$1; snd $2]) }
674 | TMacroIdentBuilder TOPar param_define_list TCPar
ae4735db 675 { CppIdentBuilder ((fst $1, [snd $1;$2;$4]), $3) }
b1b2de81
C
676
677identifier_cpp_list:
ae4735db 678 | TIdent { [mk_string_wrap $1, []] }
b1b2de81
C
679 | identifier_cpp_list TCppConcatOp TIdent { $1 ++ [mk_string_wrap $3, [$2]] }
680
34e49164
C
681/*(*************************************************************************)*/
682/*(* expr *)*/
683/*(*************************************************************************)*/
684
ae4735db 685expr:
34e49164
C
686 | assign_expr { $1 }
687 | expr TComma assign_expr { mk_e (Sequence ($1,$3)) [$2] }
688
ae4735db 689/*(* bugfix: in C grammar they put unary_expr, but in fact it must be
34e49164
C
690 * cast_expr, otherwise (int * ) xxx = &yy; is not allowed
691 *)*/
ae4735db 692assign_expr:
34e49164
C
693 | cond_expr { $1 }
694 | cast_expr TAssign assign_expr { mk_e(Assignment ($1,fst $2,$3)) [snd $2]}
695 | cast_expr TEq assign_expr { mk_e(Assignment ($1,SimpleAssign,$3)) [$2]}
696
ae4735db 697/*(* gccext: allow optional then part hence gcc_opt_expr
34e49164
C
698 * bugfix: in C grammar they put TDotDot cond_expr, but in fact it must be
699 * assign_expr, otherwise pnp ? x : x = 0x388 is not allowed
700 *)*/
ae4735db
C
701cond_expr:
702 | arith_expr
34e49164 703 { $1 }
ae4735db
C
704 | arith_expr TWhy gcc_opt_expr TDotDot assign_expr
705 { mk_e (CondExpr ($1,$3,$5)) [$2;$4] }
34e49164
C
706
707
ae4735db 708arith_expr:
34e49164
C
709 | cast_expr { $1 }
710 | arith_expr TMul arith_expr { mk_e(Binary ($1, Arith Mul, $3)) [$2] }
711 | arith_expr TDiv arith_expr { mk_e(Binary ($1, Arith Div, $3)) [$2] }
712 | arith_expr TMod arith_expr { mk_e(Binary ($1, Arith Mod, $3)) [$2] }
713 | arith_expr TPlus arith_expr { mk_e(Binary ($1, Arith Plus, $3)) [$2] }
714 | arith_expr TMinus arith_expr { mk_e(Binary ($1, Arith Minus, $3)) [$2] }
715 | arith_expr TShl arith_expr { mk_e(Binary ($1, Arith DecLeft, $3)) [$2] }
716 | arith_expr TShr arith_expr { mk_e(Binary ($1, Arith DecRight, $3)) [$2] }
717 | arith_expr TInf arith_expr { mk_e(Binary ($1, Logical Inf, $3)) [$2] }
718 | arith_expr TSup arith_expr { mk_e(Binary ($1, Logical Sup, $3)) [$2] }
719 | arith_expr TInfEq arith_expr { mk_e(Binary ($1, Logical InfEq, $3)) [$2] }
720 | arith_expr TSupEq arith_expr { mk_e(Binary ($1, Logical SupEq, $3)) [$2] }
721 | arith_expr TEqEq arith_expr { mk_e(Binary ($1, Logical Eq, $3)) [$2] }
722 | arith_expr TNotEq arith_expr { mk_e(Binary ($1, Logical NotEq, $3)) [$2] }
723 | arith_expr TAnd arith_expr { mk_e(Binary ($1, Arith And, $3)) [$2] }
724 | arith_expr TOr arith_expr { mk_e(Binary ($1, Arith Or, $3)) [$2] }
725 | arith_expr TXor arith_expr { mk_e(Binary ($1, Arith Xor, $3)) [$2] }
726 | arith_expr TAndLog arith_expr { mk_e(Binary ($1, Logical AndLog, $3)) [$2] }
727 | arith_expr TOrLog arith_expr { mk_e(Binary ($1, Logical OrLog, $3)) [$2] }
728
ae4735db 729cast_expr:
34e49164
C
730 | unary_expr { $1 }
731 | topar2 type_name tcpar2 cast_expr { mk_e(Cast ($2, $4)) [$1;$3] }
732
ae4735db 733unary_expr:
34e49164
C
734 | postfix_expr { $1 }
735 | TInc unary_expr { mk_e(Infix ($2, Inc)) [$1] }
736 | TDec unary_expr { mk_e(Infix ($2, Dec)) [$1] }
737 | unary_op cast_expr { mk_e(Unary ($2, fst $1)) [snd $1] }
738 | Tsizeof unary_expr { mk_e(SizeOfExpr ($2)) [$1] }
739 | Tsizeof topar2 type_name tcpar2 { mk_e(SizeOfType ($3)) [$1;$2;$4] }
f59c9fb7 740 | Tnew new_argument { mk_e(New $2) [$1] }
4dfbc1c2 741 | Tdelete cast_expr { mk_e(Delete $2) [$1] }
f59c9fb7
C
742
743new_argument:
4dfbc1c2
C
744 | TIdent TOPar argument_list_ne TCPar
745 { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
746 Left (mk_e(FunCall (fn, $3)) [$2;$4]) }
747 | TIdent TOPar TCPar
748 { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
749 Left(mk_e(FunCall (fn, [])) [$2;$3]) }
750 | TypedefIdent 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 | TypedefIdent TOPar TCPar
754 { let fn = mk_e(Ident (RegularName (mk_string_wrap $1))) [] in
755 Left (mk_e(FunCall (fn, [])) [$2;$3]) }
756 | type_spec
757 { let ty = addTypeD ($1,nullDecl) in
758 let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam ty in
f59c9fb7
C
759 Right (ArgType { p_namei = None; p_type = returnType;
760 p_register = hasreg, iihasreg;
761 } )
762 }
4dfbc1c2
C
763 | new_argument TOCro expr TCCro
764 {
765 match $1 with
766 Left(e) -> Left(mk_e(ArrayAccess (e, $3)) [$2;$4])
767 | Right(ArgType(ty)) -> (* lots of hacks to make the right type *)
768 let fty = mk_ty (Array (Some $3, ty.Ast_c.p_type)) [$2;$4] in
769 let pty = { ty with p_type = fty } in
770 Right(ArgType pty)
771 | _ -> raise Impossible
772 }
34e49164 773
ae4735db 774unary_op:
34e49164
C
775 | TAnd { GetRef, $1 }
776 | TMul { DeRef, $1 }
777 | TPlus { UnPlus, $1 }
778 | TMinus { UnMinus, $1 }
779 | TTilde { Tilde, $1 }
780 | TBang { Not, $1 }
781 /*(* gccext: have that a lot in old kernel to get address of local label.
782 * cf gcc manual "local labels as values".
783 *)*/
784 | TAndLog { GetRefLabel, $1 }
785
ae4735db 786postfix_expr:
34e49164 787 | primary_expr { $1 }
ae4735db 788 | postfix_expr TOCro expr TCCro
34e49164 789 { mk_e(ArrayAccess ($1, $3)) [$2;$4] }
ae4735db 790 | postfix_expr TOPar argument_list_ne TCPar
34e49164
C
791 { mk_e(FunCall ($1, $3)) [$2;$4] }
792 | postfix_expr TOPar TCPar { mk_e(FunCall ($1, [])) [$2;$3] }
b1b2de81
C
793 | postfix_expr TDot ident_cpp { mk_e(RecordAccess ($1,$3)) [$2] }
794 | postfix_expr TPtrOp ident_cpp { mk_e(RecordPtAccess ($1,$3)) [$2] }
34e49164
C
795 | postfix_expr TInc { mk_e(Postfix ($1, Inc)) [$2] }
796 | postfix_expr TDec { mk_e(Postfix ($1, Dec)) [$2] }
797
798 /*(* gccext: also called compound literals *)*/
0708f913 799 | topar2 type_name tcpar2 TOBrace TCBrace
34e49164
C
800 { mk_e(Constructor ($2, [])) [$1;$3;$4;$5] }
801 | topar2 type_name tcpar2 TOBrace initialize_list gcc_comma_opt TCBrace
802 { mk_e(Constructor ($2, List.rev $5)) ([$1;$3;$4;$7] ++ $6) }
803
4dfbc1c2 804
0708f913 805primary_expr:
708f4980
C
806 | identifier_cpp { mk_e(Ident ($1)) [] }
807 | TInt
808 { let (str,(sign,base)) = fst $1 in
809 mk_e(Constant (Int (str,Si(sign,base)))) [snd $1] }
34e49164
C
810 | TFloat { mk_e(Constant (Float (fst $1))) [snd $1] }
811 | TString { mk_e(Constant (String (fst $1))) [snd $1] }
812 | TChar { mk_e(Constant (Char (fst $1))) [snd $1] }
813 | TOPar expr TCPar { mk_e(ParenExpr ($2)) [$1;$3] } /*(* forunparser: *)*/
814
485bce71 815 /*(* gccext: cppext: TODO better ast ? *)*/
0708f913
C
816 | TMacroString { mk_e(Constant (MultiString [fst $1])) [snd $1] }
817 | string_elem string_list
818 { mk_e(Constant (MultiString ["TODO: MultiString"])) ($1 ++ $2) }
34e49164
C
819
820 /*(* gccext: allow statement as expressions via ({ statement }) *)*/
0708f913 821 | TOPar compound TCPar { mk_e(StatementExpr ($2)) [$1;$3] }
34e49164
C
822
823
824
485bce71
C
825/*(*----------------------------*)*/
826/*(* cppext: *)*/
827/*(*----------------------------*)*/
34e49164
C
828
829/*(* cppext: *)*/
485bce71 830/*(* to avoid conflicts have to introduce a _not_empty (ne) version *)*/
0708f913 831argument_ne:
34e49164
C
832 | assign_expr { Left $1 }
833 | parameter_decl { Right (ArgType $1) }
834 | action_higherordermacro_ne { Right (ArgAction $1) }
835
485bce71 836
ae4735db 837argument:
34e49164
C
838 | assign_expr { Left $1 }
839 | parameter_decl { Right (ArgType $1) }
485bce71 840 /*(* had conflicts before, but julia fixed them *)*/
34e49164
C
841 | action_higherordermacro { Right (ArgAction $1) }
842
ae4735db
C
843action_higherordermacro_ne:
844 | taction_list_ne
34e49164
C
845 { if null $1
846 then ActMisc [Ast_c.fakeInfo()]
847 else ActMisc $1
848 }
849
485bce71 850
ae4735db
C
851action_higherordermacro:
852 | taction_list
34e49164
C
853 { if null $1
854 then ActMisc [Ast_c.fakeInfo()]
855 else ActMisc $1
856 }
857
858
859/*(*----------------------------*)*/
860/*(* workarounds *)*/
861/*(*----------------------------*)*/
862
34e49164
C
863/*(* would like evalInt $1 but require too much info *)*/
864const_expr: cond_expr { $1 }
865
866
867topar2: TOPar { et "topar2" (); $1 }
ae4735db 868tcpar2: TCPar { et "tcpar2" (); $1 (*TODO? et ? sure ? c pas dt plutot ? *) }
34e49164
C
869
870
871
872/*(*************************************************************************)*/
873/*(* statement *)*/
874/*(*************************************************************************)*/
875
708f4980
C
876statement: statement2 { mk_st (fst $1) (snd $1) }
877
ae4735db 878statement2:
34e49164
C
879 | labeled { Labeled (fst $1), snd $1 }
880 | compound { Compound (fst $1), snd $1 }
881 | expr_statement { ExprStatement(fst $1), snd $1 }
882 | selection { Selection (fst $1), snd $1 ++ [fakeInfo()] }
883 | iteration { Iteration (fst $1), snd $1 ++ [fakeInfo()] }
884 | jump TPtVirg { Jump (fst $1), snd $1 ++ [$2] }
885
886 /*(* gccext: *)*/
887 | Tasm TOPar asmbody TCPar TPtVirg { Asm $3, [$1;$2;$4;$5] }
888 | Tasm Tvolatile TOPar asmbody TCPar TPtVirg { Asm $4, [$1;$2;$3;$5;$6] }
889
890 /*(* cppext: *)*/
485bce71 891 | TMacroStmt { MacroStmt, [snd $1] }
34e49164
C
892
893
894
895
ae4735db
C
896/*(* note that case 1: case 2: i++; would be correctly parsed, but with
897 * a Case (1, (Case (2, i++))) :(
34e49164 898 *)*/
ae4735db 899labeled:
b1b2de81 900 | ident_cpp TDotDot statement { Label ($1, $3), [$2] }
34e49164 901 | Tcase const_expr TDotDot statement { Case ($2, $4), [$1; $3] }
ae4735db 902 | Tcase const_expr TEllipsis const_expr TDotDot statement
34e49164 903 { CaseRange ($2, $4, $6), [$1;$3;$5] } /*(* gccext: allow range *)*/
ae4735db 904 | Tdefault TDotDot statement { Default $3, [$1; $2] }
34e49164 905
ae4735db 906end_labeled:
34e49164 907 /*(* gccext: allow toto: }
485bce71
C
908 * was generating each 30 shift/Reduce conflicts,
909 * mais ca va, ca fait ce qu'il faut.
ae4735db 910 * update: julia fixed the problem by introducing end_labeled
485bce71 911 * and modifying below stat_or_decl_list
34e49164 912 *)*/
ae4735db 913 | ident_cpp TDotDot
708f4980 914 { Label ($1, (mk_st (ExprStatement None) Ast_c.noii)), [$2] }
ae4735db 915 | Tcase const_expr TDotDot
708f4980 916 { Case ($2, (mk_st (ExprStatement None) Ast_c.noii)), [$1;$3] }
ae4735db 917 | Tdefault TDotDot
708f4980 918 { Default (mk_st (ExprStatement None) Ast_c.noii), [$1; $2] }
34e49164
C
919
920
921
922
923
924compound: tobrace compound2 tcbrace { $2, [$1; $3] }
925
34e49164
C
926
927/*
928(* cppext: because of cpp, some stuff looks like declaration but are in
929 * fact statement but too hard to figure out, and if parse them as
930 * expression, then we force to have first decls and then exprs, then
931 * will have a parse error. So easier to let mix decl/statement.
932 * Moreover it helps to not make such a difference between decl and
933 * statement for further coccinelle phases to factorize code.
934*)*/
ae4735db 935compound2:
34e49164
C
936 | { ([]) }
937 | stat_or_decl_list { $1 }
938
34e49164 939
ae4735db
C
940stat_or_decl_list:
941 | stat_or_decl { [$1] }
485bce71 942 /*(* gccext: to avoid conflicts, cf end_labeled above *)*/
708f4980 943 | end_labeled { [StmtElem (mk_st (Labeled (fst $1)) (snd $1))] }
485bce71
C
944 /*(* old: conflicts | stat_or_decl_list stat_or_decl { $1 ++ [$2] } *)*/
945 | stat_or_decl stat_or_decl_list { $1 :: $2 }
946
ae4735db 947stat_or_decl:
708f4980 948 | decl { StmtElem (mk_st (Decl ($1 Ast_c.LocalDecl)) Ast_c.noii) }
485bce71 949 | statement { StmtElem $1 }
34e49164
C
950
951 /*(* gccext: *)*/
708f4980 952 | function_definition { StmtElem (mk_st (NestedFunc $1) Ast_c.noii) }
34e49164 953
485bce71 954 /* (* cppext: *)*/
ae4735db 955 | cpp_directive
485bce71 956 { CppDirectiveStmt $1 }
ae4735db 957 | cpp_ifdef_directive/*(* stat_or_decl_list ...*)*/
485bce71 958 { IfdefStmt $1 }
34e49164
C
959
960
ae4735db 961expr_statement:
34e49164
C
962 | TPtVirg { None, [$1] }
963 | expr TPtVirg { Some $1, [$2] }
964
ae4735db 965selection:
485bce71 966 | Tif TOPar expr TCPar statement %prec SHIFTHERE
708f4980 967 { If ($3, $5, (mk_st (ExprStatement None) Ast_c.noii)), [$1;$2;$4] }
ae4735db 968 | Tif TOPar expr TCPar statement Telse statement
34e49164 969 { If ($3, $5, $7), [$1;$2;$4;$6] }
ae4735db 970 | Tswitch TOPar expr TCPar statement
34e49164
C
971 { Switch ($3,$5), [$1;$2;$4] }
972
ae4735db
C
973iteration:
974 | Twhile TOPar expr TCPar statement
34e49164 975 { While ($3,$5), [$1;$2;$4] }
ae4735db 976 | Tdo statement Twhile TOPar expr TCPar TPtVirg
34e49164
C
977 { DoWhile ($2,$5), [$1;$3;$4;$6;$7] }
978 | Tfor TOPar expr_statement expr_statement TCPar statement
979 { For ($3,$4,(None, []),$6), [$1;$2;$5]}
980 | Tfor TOPar expr_statement expr_statement expr TCPar statement
981 { For ($3,$4,(Some $5, []),$7), [$1;$2;$6] }
485bce71
C
982 /*(* c++ext: for(int i = 0; i < n; i++)*)*/
983 | Tfor TOPar decl expr_statement expr_opt TCPar statement
ae4735db 984 {
485bce71 985 (* pr2 "DECL in for"; *)
b1b2de81 986 MacroIteration ("toto", [], $7),[$1;$2;$6] (* TODOfake ast, TODO need decl2 ? *)
34e49164 987 }
34e49164
C
988 /*(* cppext: *)*/
989 | TMacroIterator TOPar argument_list_ne TCPar statement
990 { MacroIteration (fst $1, $3, $5), [snd $1;$2;$4] }
991 | TMacroIterator TOPar TCPar statement
992 { MacroIteration (fst $1, [], $4), [snd $1;$2;$3] }
993
994/*(* the ';' in the caller grammar rule will be appended to the infos *)*/
ae4735db
C
995jump:
996 | Tgoto ident_cpp { Goto ($2), [$1] }
34e49164
C
997 | Tcontinue { Continue, [$1] }
998 | Tbreak { Break, [$1] }
ae4735db 999 | Treturn { Return, [$1] }
34e49164
C
1000 | Treturn expr { ReturnExpr $2, [$1] }
1001 | Tgoto TMul expr { GotoComputed $3, [$1;$2] }
1002
1003
1004
1005/*(*----------------------------*)*/
1006/*(* gccext: *)*/
1007/*(*----------------------------*)*/
1008string_elem:
1009 | TString { [snd $1] }
1010 /*(* cppext: ex= printk (KERN_INFO "xxx" UTS_RELEASE) *)*/
485bce71 1011 | TMacroString { [snd $1] }
34e49164
C
1012
1013
ae4735db 1014asmbody:
34e49164
C
1015 | string_list colon_asm_list { $1, $2 }
1016 | string_list { $1, [] } /*(* in old kernel *)*/
1017
1018
1019colon_asm: TDotDot colon_option_list { Colon $2, [$1] }
1020
ae4735db 1021colon_option:
34e49164 1022 | TString { ColonMisc, [snd $1] }
ae4735db 1023 | TString TOPar asm_expr TCPar { ColonExpr $3, [snd $1; $2;$4] }
34e49164
C
1024 /*(* cppext: certainly a macro *)*/
1025 | TOCro identifier TCCro TString TOPar asm_expr TCPar
1026 { ColonExpr $6, [$1;snd $2;$3;snd $4; $5; $7 ] }
1027 | identifier { ColonMisc, [snd $1] }
1028 | /*(* empty *)*/ { ColonMisc, [] }
1029
1030asm_expr: assign_expr { $1 }
1031
34e49164 1032/*(*************************************************************************)*/
485bce71 1033/*(* types *)*/
34e49164 1034/*(*************************************************************************)*/
ae4735db 1035
34e49164 1036
485bce71
C
1037/*(*-----------------------------------------------------------------------*)*/
1038/*(* Type spec, left part of a type *)*/
1039/*(*-----------------------------------------------------------------------*)*/
ae4735db 1040type_spec2:
34e49164
C
1041 | Tvoid { Right3 (BaseType Void), [$1] }
1042 | Tchar { Right3 (BaseType (IntType CChar)), [$1]}
1043 | Tint { Right3 (BaseType (IntType (Si (Signed,CInt)))), [$1]}
1044 | Tfloat { Right3 (BaseType (FloatType CFloat)), [$1]}
1045 | Tdouble { Right3 (BaseType (FloatType CDouble)), [$1] }
1eddfd50
C
1046 | Tsize_t { Right3 (BaseType SizeType), [$1] }
1047 | Tssize_t { Right3 (BaseType SSizeType), [$1] }
1048 | Tptrdiff_t { Right3 (BaseType PtrDiffType), [$1] }
34e49164
C
1049 | Tshort { Middle3 Short, [$1]}
1050 | Tlong { Middle3 Long, [$1]}
1051 | Tsigned { Left3 Signed, [$1]}
1052 | Tunsigned { Left3 UnSigned, [$1]}
1053 | struct_or_union_spec { Right3 (fst $1), snd $1 }
1054 | enum_spec { Right3 (fst $1), snd $1 }
1055
1056 /*
ae4735db
C
1057 (* parse_typedef_fix1: cant put: TIdent {} cos it make the grammar
1058 * ambiguous, generates lots of conflicts => we must
34e49164 1059 * use some tricks: we make the lexer and parser cooperate, cf lexerParser.ml.
ae4735db
C
1060 *
1061 * parse_typedef_fix2: this is not enough, and you must use
34e49164 1062 * parse_typedef_fix2 to fully manage typedef problems in grammar.
ae4735db 1063 *
34e49164 1064 * parse_typedef_fix3:
ae4735db 1065 *
34e49164
C
1066 * parse_typedef_fix4: try also to do now some consistency checking in
1067 * Parse_c
ae4735db
C
1068 *)*/
1069 | TypedefIdent
b1b2de81
C
1070 { let name = RegularName (mk_string_wrap $1) in
1071 Right3 (TypeName (name, Ast_c.noTypedefDef())),[] }
34e49164
C
1072
1073 | Ttypeof TOPar assign_expr TCPar { Right3 (TypeOfExpr ($3)), [$1;$2;$4] }
1074 | Ttypeof TOPar type_name TCPar { Right3 (TypeOfType ($3)), [$1;$2;$4] }
1075
34e49164
C
1076/*(*----------------------------*)*/
1077/*(* workarounds *)*/
1078/*(*----------------------------*)*/
1079
34e49164
C
1080type_spec: type_spec2 { dt "type" (); $1 }
1081
485bce71
C
1082/*(*-----------------------------------------------------------------------*)*/
1083/*(* Qualifiers *)*/
1084/*(*-----------------------------------------------------------------------*)*/
34e49164 1085
ae4735db 1086type_qualif:
485bce71
C
1087 | Tconst { {const=true ; volatile=false}, $1 }
1088 | Tvolatile { {const=false ; volatile=true}, $1 }
1089 /*(* C99 *)*/
1090 | Trestrict { (* TODO *) {const=false ; volatile=false}, $1 }
34e49164
C
1091
1092
1093/*(*-----------------------------------------------------------------------*)*/
485bce71 1094/*(* gccext: attributes *)*/
34e49164 1095/*(*-----------------------------------------------------------------------*)*/
34e49164 1096
485bce71
C
1097attribute:
1098 | Tattribute TOPar /*stuff*/ TCPar { raise Todo }
1099 /*(* cppext: *)*/
1100 | TMacroAttr { Attribute (fst $1), [snd $1] }
34e49164 1101
485bce71
C
1102attribute_storage:
1103 | TMacroAttrStorage { $1 }
34e49164 1104
485bce71
C
1105type_qualif_attr:
1106 | type_qualif { $1 }
91eba41f
C
1107/*(*TODO !!!!! *)*/
1108 | TMacroAttr { {const=true ; volatile=false}, snd $1 }
34e49164 1109
485bce71
C
1110/*(*-----------------------------------------------------------------------*)*/
1111/*(* Declarator, right part of a type + second part of decl (the ident) *)*/
1112/*(*-----------------------------------------------------------------------*)*/
34e49164
C
1113
1114/*
ae4735db
C
1115(* declarator return a couple:
1116 * (name, partial type (a function to be applied to return type))
34e49164
C
1117 *
1118 * when int* f(int) we must return Func(Pointer int,int) and not
ae4735db 1119 * Pointer (Func(int,int)
34e49164
C
1120 *)*/
1121
ae4735db 1122declarator:
34e49164
C
1123 | pointer direct_d { (fst $2, fun x -> x +> $1 +> (snd $2) ) }
1124 | direct_d { $1 }
1125
1126/*(* so must do int * const p; if the pointer is constant, not the pointee *)*/
ae4735db 1127pointer:
f59c9fb7
C
1128 | tmul { fun x -> mk_ty (Pointer x) [$1] }
1129 | tmul pointer { fun x -> mk_ty (Pointer ($2 x)) [$1] }
1130 | tmul type_qualif_list
708f4980 1131 { fun x -> ($2.qualifD, mk_tybis (Pointer x) [$1])}
f59c9fb7 1132 | tmul type_qualif_list pointer
708f4980 1133 { fun x -> ($2.qualifD, mk_tybis (Pointer ($3 x)) [$1]) }
34e49164 1134
f59c9fb7
C
1135tmul:
1136 TMul { $1 }
1137 | TAnd
1138 { if !Flag.c_plus_plus
1139 then $1
1140 else
1141 let i = Ast_c.parse_info_of_info $1 in
1142 raise (Semantic("& not allowed in C types, try -c++ option", i)) }
1143
34e49164 1144
ae4735db 1145direct_d:
708f4980 1146 | identifier_cpp
34e49164 1147 { ($1, fun x -> x) }
ae4735db 1148 | TOPar declarator TCPar /*(* forunparser: old: $2 *)*/
708f4980 1149 { (fst $2, fun x -> mk_ty (ParenType ((snd $2) x)) [$1;$3]) }
ae4735db 1150 | direct_d tocro tccro
708f4980 1151 { (fst $1,fun x->(snd $1) (mk_ty (Array (None,x)) [$2;$3])) }
34e49164 1152 | direct_d tocro const_expr tccro
708f4980 1153 { (fst $1,fun x->(snd $1) (mk_ty (Array (Some $3,x)) [$2;$4])) }
34e49164
C
1154 | direct_d topar tcpar
1155 { (fst $1,
ae4735db 1156 fun x->(snd $1)
708f4980 1157 (mk_ty (FunctionType (x,(([],(false, []))))) [$2;$3]))
34e49164
C
1158 }
1159 | direct_d topar parameter_type_list tcpar
ae4735db
C
1160 { (fst $1,fun x->(snd $1)
1161 (mk_ty (FunctionType (x, $3)) [$2;$4]))
708f4980 1162 }
34e49164
C
1163
1164
485bce71
C
1165/*(*----------------------------*)*/
1166/*(* workarounds *)*/
1167/*(*----------------------------*)*/
1168
1169tocro: TOCro { et "tocro" ();$1 }
1170tccro: TCCro { dt "tccro" ();$1 }
1171
1172/*(*-----------------------------------------------------------------------*)*/
ae4735db 1173abstract_declarator:
485bce71
C
1174 | pointer { $1 }
1175 | direct_abstract_declarator { $1 }
1176 | pointer direct_abstract_declarator { fun x -> x +> $2 +> $1 }
1177
ae4735db 1178direct_abstract_declarator:
485bce71 1179 | TOPar abstract_declarator TCPar /*(* forunparser: old: $2 *)*/
708f4980 1180 { fun x -> mk_ty (ParenType ($2 x)) [$1;$3] }
485bce71 1181
ae4735db 1182 | TOCro TCCro
708f4980 1183 { fun x -> mk_ty (Array (None, x)) [$1;$2] }
ae4735db 1184 | TOCro const_expr TCCro
708f4980 1185 { fun x -> mk_ty (Array (Some $2, x)) [$1;$3] }
ae4735db 1186 | direct_abstract_declarator TOCro TCCro
708f4980 1187 { fun x -> $1 (mk_ty (Array (None, x)) [$2;$3]) }
485bce71 1188 | direct_abstract_declarator TOCro const_expr TCCro
708f4980 1189 { fun x -> $1 (mk_ty (Array (Some $3,x)) [$2;$4]) }
ae4735db 1190 | TOPar TCPar
708f4980 1191 { fun x -> mk_ty (FunctionType (x, ([], (false, [])))) [$1;$2] }
0708f913 1192 | topar parameter_type_list tcpar
708f4980 1193 { fun x -> mk_ty (FunctionType (x, $2)) [$1;$3] }
0708f913
C
1194/*(* subtle: here must also use topar, not TOPar, otherwise if have for
1195 * instance (xxx ( * )(xxx)) cast, then the second xxx may still be a Tident
ae4735db 1196 * but we want to reduce topar, to set the InParameter so that
0708f913
C
1197 * parsing_hack can get a chance to change the type of xxx into a typedef.
1198 * That's an example where parsing_hack and the lookahead of ocamlyacc does
ae4735db 1199 * not go very well together ... we got the info too late. We got
0708f913
C
1200 * a similar pb with xxx xxx; declaration, cf parsing_hack.ml and the
1201 * "disable typedef cos special case ..." message.
1202*)*/
1203 | direct_abstract_declarator topar tcpar
708f4980 1204 { fun x -> $1 (mk_ty (FunctionType (x, (([], (false, []))))) [$2;$3]) }
0708f913 1205 | direct_abstract_declarator topar parameter_type_list tcpar
708f4980 1206 { fun x -> $1 (mk_ty (FunctionType (x, $3)) [$2;$4]) }
485bce71
C
1207
1208/*(*-----------------------------------------------------------------------*)*/
1209/*(* Parameters (use decl_spec not type_spec just for 'register') *)*/
1210/*(*-----------------------------------------------------------------------*)*/
ae4735db 1211parameter_type_list:
34e49164
C
1212 | parameter_list { ($1, (false, []))}
1213 | parameter_list TComma TEllipsis { ($1, (true, [$2;$3])) }
1214
1215
ae4735db 1216parameter_decl2:
34e49164 1217 | decl_spec declaratorp
b1b2de81
C
1218 { let ((returnType,hasreg),iihasreg) = fixDeclSpecForParam $1 in
1219 let (name, ftyp) = $2 in
1220 { p_namei = Some (name);
1221 p_type = ftyp returnType;
1222 p_register = (hasreg, iihasreg);
1223 }
34e49164 1224 }
485bce71 1225 | decl_spec abstract_declaratorp
ae4735db 1226 { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in
b1b2de81
C
1227 { p_namei = None;
1228 p_type = $2 returnType;
1229 p_register = hasreg, iihasreg;
ae4735db 1230 }
34e49164
C
1231 }
1232 | decl_spec
b1b2de81
C
1233 { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in
1234 { p_namei = None;
1235 p_type = returnType;
1236 p_register = hasreg, iihasreg;
1237 }
34e49164
C
1238 }
1239
1240
1241/*(*----------------------------*)*/
1242/*(* workarounds *)*/
1243/*(*----------------------------*)*/
1244
485bce71 1245parameter_decl: parameter_decl2 { et "param" (); $1 }
708f4980 1246 | attributes parameter_decl2 { et "param" (); $2 }
34e49164 1247
ae4735db 1248declaratorp:
b1b2de81 1249 | declarator { LP.add_ident (str_of_name (fst $1)); $1 }
485bce71 1250 /*(* gccext: *)*/
b1b2de81
C
1251 | attributes declarator { LP.add_ident (str_of_name (fst $2)); $2 }
1252 | declarator attributes { LP.add_ident (str_of_name (fst $1)); $1 }
34e49164 1253
485bce71
C
1254abstract_declaratorp:
1255 | abstract_declarator { $1 }
1256 /*(* gccext: *)*/
1257 | attributes abstract_declarator { $2 }
1258
1259/*(*-----------------------------------------------------------------------*)*/
1260/*(* helper type rules *)*/
1261/*(*-----------------------------------------------------------------------*)*/
1262
1263/*(* for struct and also typename *)*/
1264/*(* cant put decl_spec cos no storage is allowed for field struct *)*/
ae4735db 1265spec_qualif_list2:
485bce71
C
1266 | type_spec { addTypeD ($1, nullDecl) }
1267 | type_qualif { {nullDecl with qualifD = (fst $1,[snd $1])}}
1268 | type_spec spec_qualif_list { addTypeD ($1,$2) }
1269 | type_qualif spec_qualif_list { addQualifD ($1,$2) }
1270
1271spec_qualif_list: spec_qualif_list2 { dt "spec_qualif" (); $1 }
1272
1273
1274/*(* for pointers in direct_declarator and abstract_declarator *)*/
ae4735db 1275type_qualif_list:
485bce71
C
1276 | type_qualif_attr { {nullDecl with qualifD = (fst $1,[snd $1])} }
1277 | type_qualif_list type_qualif_attr { addQualifD ($2,$1) }
34e49164 1278
34e49164
C
1279
1280
485bce71 1281
ae4735db 1282
485bce71
C
1283
1284/*(*-----------------------------------------------------------------------*)*/
1285/*(* xxx_type_id *)*/
34e49164 1286/*(*-----------------------------------------------------------------------*)*/
485bce71 1287
ae4735db
C
1288type_name:
1289 | spec_qualif_list
34e49164 1290 { let (returnType, _) = fixDeclSpecForDecl $1 in returnType }
485bce71 1291 | spec_qualif_list abstract_declaratort
34e49164
C
1292 { let (returnType, _) = fixDeclSpecForDecl $1 in $2 returnType }
1293
1294
34e49164 1295
ae4735db 1296abstract_declaratort:
485bce71
C
1297 | abstract_declarator { $1 }
1298 /*(* gccext: *)*/
1299 | attributes abstract_declarator { $2 }
1300
1301
1302/*(*************************************************************************)*/
1303/*(* declaration and initializers *)*/
1304/*(*************************************************************************)*/
1305
ae4735db 1306decl2:
485bce71
C
1307 | decl_spec TPtVirg
1308 { function local ->
ae4735db 1309 let (returnType,storage) = fixDeclSpecForDecl $1 in
485bce71 1310 let iistart = Ast_c.fakeInfo () in
ae4735db 1311 DeclList ([{v_namei = None; v_type = returnType;
485bce71
C
1312 v_storage = unwrap storage; v_local = local;
1313 v_attr = Ast_c.noattr;
978fd7e5 1314 v_type_bis = ref None;
ae4735db 1315 },[]],
485bce71 1316 ($2::iistart::snd storage))
ae4735db
C
1317 }
1318 | decl_spec init_declarator_list TPtVirg
485bce71
C
1319 { function local ->
1320 let (returnType,storage) = fixDeclSpecForDecl $1 in
1321 let iistart = Ast_c.fakeInfo () in
1322 DeclList (
ae4735db 1323 ($2 +> List.map (fun ((((name,f),attrs), ini), iivirg) ->
b1b2de81 1324 let s = str_of_name name in
ae4735db 1325 if fst (unwrap storage) =*= StoTypedef
485bce71 1326 then LP.add_typedef s;
4dfbc1c2 1327 {v_namei = Some (name, ini);
485bce71
C
1328 v_type = f returnType;
1329 v_storage = unwrap storage;
1330 v_local = local;
1331 v_attr = attrs;
978fd7e5 1332 v_type_bis = ref None;
485bce71 1333 },
ae4735db 1334 iivirg
485bce71
C
1335 )
1336 ), ($3::iistart::snd storage))
ae4735db 1337 }
485bce71
C
1338 /*(* cppext: *)*/
1339
ae4735db 1340 | TMacroDecl TOPar argument_list TCPar TPtVirg
485bce71
C
1341 { function _ ->
1342 MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) }
ae4735db 1343 | Tstatic TMacroDecl TOPar argument_list TCPar TPtVirg
485bce71
C
1344 { function _ ->
1345 MacroDecl ((fst $2, $4), [snd $2;$3;$5;$6;fakeInfo();$1]) }
ae4735db 1346 | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar TPtVirg
485bce71
C
1347 { function _ ->
1348 MacroDecl ((fst $3, $5), [snd $3;$4;$6;$7;fakeInfo();$1;$2])}
1349
1350
1351/*(*-----------------------------------------------------------------------*)*/
ae4735db 1352decl_spec2:
485bce71
C
1353 | storage_class_spec { {nullDecl with storageD = (fst $1, [snd $1]) } }
1354 | type_spec { addTypeD ($1,nullDecl) }
1355 | type_qualif { {nullDecl with qualifD = (fst $1, [snd $1]) } }
1356 | Tinline { {nullDecl with inlineD = (true, [$1]) } }
1357 | storage_class_spec decl_spec2 { addStorageD ($1, $2) }
1358 | type_spec decl_spec2 { addTypeD ($1, $2) }
1359 | type_qualif decl_spec2 { addQualifD ($1, $2) }
1360 | Tinline decl_spec2 { addInlineD ((true, $1), $2) }
1361
1362/*(* can simplify by putting all in _opt ? must have at least one otherwise
ae4735db 1363 * decl_list is ambiguous ? (no cos have ';' between decl)
485bce71
C
1364 *)*/
1365
1366
ae4735db 1367storage_class_spec2:
485bce71
C
1368 | Tstatic { Sto Static, $1 }
1369 | Textern { Sto Extern, $1 }
1370 | Tauto { Sto Auto, $1 }
1371 | Tregister { Sto Register,$1 }
1372 | Ttypedef { StoTypedef, $1 }
1373
1374storage_class_spec:
1375 /*(* gccext: *)*/
1376 | storage_class_spec2 { $1 }
708f4980 1377 | storage_class_spec2 attribute_storage_list { $1 (* TODO *) }
485bce71
C
1378
1379
1380
1381/*(*----------------------------*)*/
1382/*(* workarounds *)*/
1383/*(*----------------------------*)*/
1384
1385decl: decl2 { et "decl" (); $1 }
1386decl_spec: decl_spec2 { dt "declspec" (); $1 }
1387
1388/*(*-----------------------------------------------------------------------*)*/
1389/*(* declarators (right part of type and variable) *)*/
1390/*(*-----------------------------------------------------------------------*)*/
ae4735db 1391init_declarator2:
4dfbc1c2
C
1392 | declaratori { ($1, NoInit) }
1393 | declaratori teq initialize { ($1, ValInit($2, $3)) }
1394 /* C++ only */
1395 | declaratori TOParCplusplusInit argument_list TCPar
1396 { ($1, ConstrInit($3,[$2;$4])) }
485bce71
C
1397
1398
1399/*(*----------------------------*)*/
1400/*(* workarounds *)*/
1401/*(*----------------------------*)*/
1402teq: TEq { et "teq" (); $1 }
1403
1404init_declarator: init_declarator2 { dt "init" (); $1 }
1405
1406
1407/*(*----------------------------*)*/
1408/*(* gccext: *)*/
1409/*(*----------------------------*)*/
1410
ae4735db 1411declaratori:
b1b2de81 1412 | declarator { LP.add_ident (str_of_name (fst $1)); $1, Ast_c.noattr }
485bce71 1413 /*(* gccext: *)*/
b1b2de81 1414 | declarator gcc_asm_decl { LP.add_ident (str_of_name (fst $1)); $1, Ast_c.noattr }
485bce71 1415 /*(* gccext: *)*/
b1b2de81
C
1416 | attributes declarator { LP.add_ident (str_of_name (fst $2)); $2, $1 }
1417 | declarator attributes { LP.add_ident (str_of_name (fst $1)); $1, Ast_c.noattr (* TODO *) }
485bce71
C
1418
1419
1420
ae4735db 1421gcc_asm_decl:
485bce71
C
1422 | Tasm TOPar asmbody TCPar { }
1423 | Tasm Tvolatile TOPar asmbody TCPar { }
1424
34e49164 1425
34e49164 1426/*(*-----------------------------------------------------------------------*)*/
ae4735db
C
1427initialize:
1428 | assign_expr
34e49164 1429 { InitExpr $1, [] }
485bce71 1430 | tobrace_ini initialize_list gcc_comma_opt_struct tcbrace_ini
34e49164 1431 { InitList (List.rev $2), [$1;$4]++$3 }
485bce71 1432 | tobrace_ini tcbrace_ini
34e49164
C
1433 { InitList [], [$1;$2] } /*(* gccext: *)*/
1434
1435
1436/*
ae4735db 1437(* opti: This time we use the weird order of non-terminal which requires in
0708f913 1438 * the "caller" to do a List.rev cos quite critical. With this weird order it
34e49164
C
1439 * allows yacc to use a constant stack space instead of exploding if we would
1440 * do a 'initialize2 Tcomma initialize_list'.
1441 *)
1442*/
ae4735db 1443initialize_list:
34e49164
C
1444 | initialize2 { [$1, []] }
1445 | initialize_list TComma initialize2 { ($3, [$2])::$1 }
1446
1447
1448/*(* gccext: condexpr and no assign_expr cos can have ambiguity with comma *)*/
ae4735db
C
1449initialize2:
1450 | cond_expr
1451 { InitExpr $1, [] }
485bce71 1452 | tobrace_ini initialize_list gcc_comma_opt_struct tcbrace_ini
34e49164 1453 { InitList (List.rev $2), [$1;$4]++$3 }
485bce71 1454 | tobrace_ini tcbrace_ini
34e49164
C
1455 { InitList [], [$1;$2] }
1456
1457 /*(* gccext: labeled elements, a.k.a designators *)*/
ae4735db 1458 | designator_list TEq initialize2
34e49164
C
1459 { InitDesignators ($1, $3), [$2] }
1460
1461 /*(* gccext: old format *)*/
1462 | ident TDotDot initialize2
1463 { InitFieldOld (fst $1, $3), [snd $1; $2] } /*(* in old kernel *)*/
ae4735db 1464/* conflict
34e49164
C
1465 | TOCro const_expr TCCro initialize2
1466 { InitIndexOld ($2, $4), [$1;$3] }
485bce71
C
1467*/
1468
1469
34e49164 1470
113803cf 1471/*(* they can be nested, can have a .x[3].y *)*/
ae4735db
C
1472designator:
1473 | TDot ident
1474 { DesignatorField (fst $2), [$1;snd $2] }
1475 | TOCro const_expr TCCro
34e49164 1476 { DesignatorIndex ($2), [$1;$3] }
ae4735db 1477 | TOCro const_expr TEllipsis const_expr TCCro
34e49164
C
1478 { DesignatorRange ($2, $4), [$1;$3;$5] }
1479
1480
1481/*(*----------------------------*)*/
1482/*(* workarounds *)*/
1483/*(*----------------------------*)*/
1484
ae4735db
C
1485gcc_comma_opt_struct:
1486 | TComma { [$1] }
34e49164
C
1487 | /*(* empty *)*/ { [Ast_c.fakeInfo() +> Ast_c.rewrap_str ","] }
1488
1489
34e49164
C
1490
1491
1492
1493
1494
1495
485bce71
C
1496/*(*************************************************************************)*/
1497/*(* struct *)*/
1498/*(*************************************************************************)*/
1499
ae4735db 1500s_or_u_spec2:
34e49164
C
1501 | struct_or_union ident tobrace_struct struct_decl_list_gcc tcbrace_struct
1502 { StructUnion (fst $1, Some (fst $2), $4), [snd $1;snd $2;$3;$5] }
1503 | struct_or_union tobrace_struct struct_decl_list_gcc tcbrace_struct
1504 { StructUnion (fst $1, None, $3), [snd $1;$2;$4] }
ae4735db 1505 | struct_or_union ident
34e49164
C
1506 { StructUnionName (fst $1, fst $2), [snd $1;snd $2] }
1507
ae4735db 1508struct_or_union2:
34e49164
C
1509 | Tstruct { Struct, $1 }
1510 | Tunion { Union, $1 }
485bce71
C
1511 /*(* gccext: *)*/
1512 | Tstruct attributes { Struct, $1 (* TODO *) }
1513 | Tunion attributes { Union, $1 (* TODO *) }
34e49164
C
1514
1515
1516
ae4735db 1517struct_decl2:
708f4980
C
1518 | field_declaration { DeclarationField $1 }
1519 | TPtVirg { EmptyField $1 }
1520
1521 /*(* no conflict ? no need for a TMacroStruct ? apparently not as at struct
1522 * the rule are slightly different.
1523 *)*/
1524 | identifier TOPar argument_list TCPar TPtVirg
1525 { MacroDeclField ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) }
485bce71
C
1526
1527 /*(* cppext: *)*/
ae4735db 1528 | cpp_directive
708f4980 1529 { CppDirectiveStruct $1 }
ae4735db 1530 | cpp_ifdef_directive/*(* struct_decl_list ... *)*/
708f4980 1531 { IfdefStruct $1 }
485bce71
C
1532
1533
1534field_declaration:
ae4735db
C
1535 | spec_qualif_list struct_declarator_list TPtVirg
1536 {
34e49164 1537 let (returnType,storage) = fixDeclSpecForDecl $1 in
ae4735db 1538 if fst (unwrap storage) <> NoSto
34e49164 1539 then internal_error "parsing dont allow this";
ae4735db
C
1540
1541 FieldDeclList ($2 +> (List.map (fun (f, iivirg) ->
34e49164 1542 f returnType, iivirg))
485bce71 1543 ,[$3])
34e49164 1544 (* dont need to check if typedef or func initialised cos
ae4735db 1545 * grammar dont allow typedef nor initialiser in struct
34e49164
C
1546 *)
1547 }
1548
ae4735db
C
1549 | spec_qualif_list TPtVirg
1550 {
34e49164
C
1551 (* gccext: allow empty elements if it is a structdef or enumdef *)
1552 let (returnType,storage) = fixDeclSpecForDecl $1 in
ae4735db 1553 if fst (unwrap storage) <> NoSto
34e49164 1554 then internal_error "parsing dont allow this";
ae4735db 1555
b1b2de81 1556 FieldDeclList ([(Simple (None, returnType)) , []], [$2])
34e49164 1557 }
485bce71
C
1558
1559
34e49164
C
1560
1561
1562
ae4735db
C
1563struct_declarator:
1564 | declaratorsd
b1b2de81 1565 { (fun x -> Simple (Some (fst $1), (snd $1) x)) }
ae4735db 1566 | dotdot const_expr2
b1b2de81 1567 { (fun x -> BitField (None, x, $1, $2)) }
ae4735db 1568 | declaratorsd dotdot const_expr2
b1b2de81 1569 { (fun x -> BitField (Some (fst $1), ((snd $1) x), $2, $3)) }
34e49164
C
1570
1571
1572/*(*----------------------------*)*/
1573/*(* workarounds *)*/
1574/*(*----------------------------*)*/
ae4735db 1575declaratorsd:
485bce71
C
1576 | declarator { (*also ? LP.add_ident (fst (fst $1)); *) $1 }
1577 /*(* gccext: *)*/
1578 | attributes declarator { $2 }
1579 | declarator attributes { $1 }
34e49164 1580
34e49164
C
1581
1582
1583
1584struct_or_union_spec: s_or_u_spec2 { dt "su" (); $1 }
1585struct_or_union: struct_or_union2 { et "su" (); $1 }
1586struct_decl: struct_decl2 { et "struct" (); $1 }
1587
1588dotdot: TDotDot { et "dotdot" (); $1 }
1589const_expr2: const_expr { dt "const_expr2" (); $1 }
1590
ae4735db
C
1591struct_decl_list_gcc:
1592 | struct_decl_list { $1 }
34e49164
C
1593 | /*(* empty *)*/ { [] } /*(* gccext: allow empty struct *)*/
1594
1595
485bce71
C
1596/*(*************************************************************************)*/
1597/*(* enum *)*/
1598/*(*************************************************************************)*/
ae4735db 1599enum_spec:
c491d8ee 1600 | Tenum tobrace_enum enumerator_list gcc_comma_opt_struct tcbrace_enum
34e49164 1601 { Enum (None, $3), [$1;$2;$5] ++ $4 }
c491d8ee 1602 | Tenum ident tobrace_enum enumerator_list gcc_comma_opt_struct tcbrace_enum
34e49164 1603 { Enum (Some (fst $2), $4), [$1; snd $2; $3;$6] ++ $5 }
ae4735db 1604 | Tenum ident
34e49164
C
1605 { EnumName (fst $2), [$1; snd $2] }
1606
ae4735db 1607enumerator:
b1b2de81
C
1608 | idente { $1, None }
1609 | idente TEq const_expr { $1, Some ($2, $3) }
34e49164
C
1610
1611
1612/*(*----------------------------*)*/
1613/*(* workarounds *)*/
1614/*(*----------------------------*)*/
1615
b1b2de81 1616idente: ident_cpp { LP.add_ident (str_of_name $1); $1 }
34e49164 1617
34e49164
C
1618
1619
1620/*(*************************************************************************)*/
485bce71 1621/*(* function *)*/
34e49164 1622/*(*************************************************************************)*/
485bce71 1623function_definition: function_def { fixFunc $1 }
34e49164 1624
ae4735db 1625decl_list:
91eba41f
C
1626 | decl { [$1 Ast_c.LocalDecl] }
1627 | decl_list decl { $1 ++ [$2 Ast_c.LocalDecl] }
34e49164 1628
9f8e26f4 1629/* hack : to drop when a better solution is found */
ae4735db 1630cpp_directive_list:
9f8e26f4
C
1631 | cpp_directive { }
1632 | cpp_directive_list cpp_directive { }
1633
ae4735db 1634function_def:
91eba41f 1635 | start_fun compound { LP.del_scope(); ($1, $2, None) }
9f8e26f4 1636 | start_fun cpp_directive_list compound { LP.del_scope(); ($1, $3, None) }
ae4735db 1637 | start_fun decl_list compound {
485bce71 1638 (* TODO: undo the typedef added ? *)
ae4735db 1639 LP.del_scope();
91eba41f 1640 ($1, $3, Some $2)
485bce71
C
1641 }
1642
ae4735db
C
1643start_fun: start_fun2
1644 { LP.new_scope();
1645 fix_add_params_ident $1;
485bce71 1646 (* toreput? !LP._lexer_hint.toplevel <- false; *)
ae4735db 1647 $1
485bce71
C
1648 }
1649
ae4735db 1650start_fun2: decl_spec declaratorfd
485bce71
C
1651 { let (returnType,storage) = fixDeclSpecForFuncDef $1 in
1652 let (id, attrs) = $2 in
ae4735db 1653 (fst id, fixOldCDecl ((snd id) returnType) , storage, attrs)
485bce71 1654 }
f59c9fb7
C
1655 | ctor_dtor { $1 }
1656
1657ctor_dtor:
1658 | Tconstructorname topar tcpar {
1659 let id = RegularName (mk_string_wrap $1) in
1660 let ret = mk_ty NoType [] in
1661 let ty = mk_ty (FunctionType (ret, (([], (false, []))))) [$2;$3] in
1662 let storage = ((NoSto,false),[]) in
1663 let attrs = [] in
1664 (id, ty, storage, attrs) }
1665 | Tconstructorname topar parameter_type_list tcpar {
1666 let id = RegularName (mk_string_wrap $1) in
1667 let ret = mk_ty NoType [] in
1668 let ty = mk_ty (FunctionType (ret, $3)) [$2;$4] in
1669 let storage = ((NoSto,false),[]) in
1670 let attrs = [] in
1671 (id, ty, storage, attrs) }
485bce71
C
1672
1673/*(*----------------------------*)*/
1674/*(* workarounds *)*/
1675/*(*----------------------------*)*/
1676
5636bb2c
C
1677/* It would be very nice if we could make declarator aware that this is
1678coming from a function definition. Then on the ( and ) cases, it could
1679set the state to something other than InParameter. Then the case
1680(TIdent (s, i1)::(TComma _|TCPar _)::_ , (TComma _ |TOPar _)::_ )
1681in parsing_hacks.ml would not have to consider K&R variable declarations
1682as typedefs. Unfortunately, doing something about this problem seems to
1683introduce conflicts in the parser. */
1684
ae4735db 1685declaratorfd:
485bce71
C
1686 | declarator { et "declaratorfd" (); $1, Ast_c.noattr }
1687 /*(* gccext: *)*/
1688 | attributes declarator { et "declaratorfd" (); $2, $1 }
1689 | declarator attributes { et "declaratorfd" (); $1, Ast_c.noattr }
1690
1691
1692
1693/*(*************************************************************************)*/
1694/*(* cpp directives *)*/
1695/*(*************************************************************************)*/
1696
ae4735db
C
1697cpp_directive:
1698 | TIncludeStart TIncludeFilename
1699 {
485bce71
C
1700 let (i1, in_ifdef) = $1 in
1701 let (s, i2) = $2 in
1702
1703 (* redo some lexing work :( *)
ae4735db 1704 let inc_file =
485bce71 1705 match () with
ae4735db 1706 | _ when s =~ "^\"\\(.*\\)\"$" ->
485bce71 1707 Local (Common.split "/" (matched1 s))
ae4735db 1708 | _ when s =~ "^\\<\\(.*\\)\\>$" ->
485bce71 1709 NonLocal (Common.split "/" (matched1 s))
ae4735db
C
1710 | _ ->
1711 Weird s
485bce71
C
1712 in
1713 Include { i_include = (inc_file, [i1;i2]);
1714 i_rel_pos = Ast_c.noRelPos();
1715 i_is_in_ifdef = !in_ifdef;
1716 i_content = Ast_c.noi_content;
1717 }
1718 }
1719
ae4735db 1720 | TDefine TIdentDefine define_val TDefEOL
485bce71
C
1721 { Define ((fst $2, [$1; snd $2;$4]), (DefineVar, $3)) }
1722
1723 /*
1724 (* The TOParDefine is introduced to avoid ambiguity with previous rules.
1725 * A TOParDefine is a TOPar that was just next to the ident.
1726 *)*/
1727 | TDefine TIdentDefine TOParDefine param_define_list TCPar define_val TDefEOL
ae4735db 1728 { Define
3a314143 1729 ((fst $2, [$1; snd $2; $7]),
ae4735db 1730 (DefineFunc ($4, [$3;$5]), $6))
485bce71
C
1731 }
1732
3a314143
C
1733 | TUndef TIdentDefine TDefEOL
1734 { Define((fst $2, [$1; snd $2; $3]), (Undef,DefineEmpty)) }
485bce71
C
1735 | TCppDirectiveOther { PragmaAndCo ([$1]) }
1736
b1b2de81
C
1737
1738
1739
1740
ae4735db 1741/*(* perhaps better to use assign_expr ? but in that case need
485bce71
C
1742 * do a assign_expr_of_string in parse_c
1743 *)*/
ae4735db 1744define_val:
485bce71
C
1745 | expr { DefineExpr $1 }
1746 | statement { DefineStmt $1 }
708f4980
C
1747 | decl { DefineStmt (mk_st (Decl ($1 Ast_c.NotLocalDecl)) Ast_c.noii) }
1748
ae4735db 1749/*(*old:
708f4980 1750 * | TypedefIdent { DefineType (nQ,(TypeName(fst $1,noTypedefDef()),[snd $1]))}
ae4735db 1751 * get conflicts:
708f4980
C
1752 * | spec_qualif_list TMul
1753 * { let (returnType, _) = fixDeclSpecForDecl $1 in DefineType returnType }
1754 *)
1755*/
ae4735db
C
1756 | decl_spec
1757 { let returnType = fixDeclSpecForMacro $1 in
708f4980
C
1758 DefineType returnType
1759 }
ae4735db
C
1760 | decl_spec abstract_declarator
1761 { let returnType = fixDeclSpecForMacro $1 in
708f4980
C
1762 let typ = $2 returnType in
1763 DefineType typ
1764 }
1765
ae4735db 1766/* can be in conflict with decl_spec, maybe change fixDeclSpecForMacro
708f4980
C
1767 * to also allow storage ?
1768 | storage_class_spec { DefineTodo }
1769 | Tinline { DefineTodo }
1770*/
1771
1772 /*(* a few special cases *)*/
1773 | stat_or_decl stat_or_decl_list { DefineTodo }
1774/*
1775 | statement statement { DefineTodo }
1776 | decl function_definition { DefineTodo }
1777*/
1778
1779
1780
485bce71 1781
485bce71
C
1782 | function_definition { DefineFunction $1 }
1783
ae4735db 1784 | TOBraceDefineInit initialize_list gcc_comma_opt_struct TCBrace comma_opt
485bce71
C
1785 { DefineInit (InitList (List.rev $2), [$1;$4]++$3++$5) }
1786
1787 /*(* note: had a conflict before when were putting TInt instead of expr *)*/
ae4735db 1788 | Tdo statement Twhile TOPar expr TCPar
485bce71 1789 {
ae4735db
C
1790 (* TOREPUT
1791 if fst $5 <> "0"
0708f913 1792 then pr2 "WEIRD: in macro and have not a while(0)";
485bce71
C
1793 *)
1794 DefineDoWhileZero (($2,$5), [$1;$3;$4;$6])
1795 }
1796
485bce71
C
1797 | Tasm TOPar asmbody TCPar { DefineTodo }
1798 | Tasm Tvolatile TOPar asmbody TCPar { DefineTodo }
1799
485bce71
C
1800 /*(* aliases macro *)*/
1801 | TMacroAttr { DefineTodo }
485bce71
C
1802
1803 | /*(* empty *)*/ { DefineEmpty }
1804
1805
b1b2de81
C
1806
1807
485bce71 1808param_define:
ae4735db
C
1809 | TIdent { mk_string_wrap $1 }
1810 | TypedefIdent { mk_string_wrap $1 }
1811 | TDefParamVariadic { mk_string_wrap $1 }
485bce71
C
1812 | TEllipsis { "...", [$1] }
1813 /*(* they reuse keywords :( *)*/
1814 | Tregister { "register", [$1] }
1815
1816
1817
1818
ae4735db
C
1819cpp_ifdef_directive:
1820 | TIfdef
1821 { let (tag,ii) = $1 in
485bce71 1822 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1823 | TIfdefelse
1824 { let (tag,ii) = $1 in
485bce71 1825 IfdefDirective ((IfdefElse, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1826 | TIfdefelif
1827 { let (tag,ii) = $1 in
485bce71 1828 IfdefDirective ((IfdefElseif, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1829 | TEndif
1830 { let (tag,ii) = $1 in
485bce71
C
1831 IfdefDirective ((IfdefEndif, IfdefTag (Common.some !tag)), [ii]) }
1832
ae4735db
C
1833 | TIfdefBool
1834 { let (_b, tag,ii) = $1 in
485bce71 1835 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1836 | TIfdefMisc
1837 { let (_b, tag,ii) = $1 in
485bce71 1838 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
ae4735db
C
1839 | TIfdefVersion
1840 { let (_b, tag,ii) = $1 in
485bce71
C
1841 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
1842
1843
1844/*(* cppext: *)*/
ae4735db 1845cpp_other:
485bce71
C
1846 /*(* no conflict ? no need for a TMacroTop ? apparently not as at toplevel
1847 * the rule are slightly different, they cant be statement and so expr
1848 * at the top, only decl or function definition.
1849 *)*/
1850 | identifier TOPar argument_list TCPar TPtVirg
ae4735db
C
1851 {
1852 Declaration (MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]))
708f4980
C
1853 (* old: MacroTop (fst $1, $3, [snd $1;$2;$4;$5]) *)
1854 }
485bce71
C
1855
1856 /*(* TCParEOL to fix the end-of-stream bug of ocamlyacc *)*/
1857 | identifier TOPar argument_list TCParEOL
ae4735db 1858 { MacroTop (fst $1, $3, [snd $1;$2;$4;fakeInfo()]) }
485bce71
C
1859
1860 /*(* ex: EXPORT_NO_SYMBOLS; *)*/
1861 | identifier TPtVirg { EmptyDef [snd $1;$2] }
1862
1863
1864
1865/*(*************************************************************************)*/
1866/*(* celem *)*/
1867/*(*************************************************************************)*/
1868
ae4735db 1869external_declaration:
485bce71
C
1870 | function_definition { Definition $1 }
1871 | decl { Declaration ($1 Ast_c.NotLocalDecl) }
1872
1873
ae4735db 1874celem:
f59c9fb7 1875 | external_declaration { $1 }
485bce71
C
1876
1877 /*(* cppext: *)*/
ae4735db 1878 | cpp_directive
485bce71 1879 { CppTop $1 }
ae4735db 1880 | cpp_other
485bce71
C
1881 { $1 }
1882 | cpp_ifdef_directive /* (*external_declaration_list ...*)*/
1883 { IfdefTop $1 }
1884
1885 /*(* can have asm declaration at toplevel *)*/
ae4735db 1886 | Tasm TOPar asmbody TCPar TPtVirg { EmptyDef [$1;$2;$4;$5] }
485bce71
C
1887
1888 /*
1889 (* in ~/kernels/src/linux-2.5.2/drivers/isdn/hisax/isdnl3.c sometimes
ae4735db 1890 * the function ends with }; instead of just }
485bce71
C
1891 * can also remove this rule and report "parse error" pb to morton
1892 *)*/
ae4735db
C
1893 | TPtVirg { EmptyDef [$1] }
1894
485bce71 1895
ae4735db 1896 | EOF { FinalDef $1 }
485bce71
C
1897
1898
1899
1900
1901/*(*************************************************************************)*/
1902/*(* some generic workarounds *)*/
1903/*(*************************************************************************)*/
1904
1905tobrace: TOBrace { LP.push_context LP.InFunction; LP.new_scope (); $1 }
1906tcbrace: TCBrace { LP.pop_context(); LP.del_scope (); $1 }
1907
1908tobrace_enum: TOBrace { LP.push_context LP.InEnum; $1 }
1909tcbrace_enum: TCBrace { LP.pop_context (); $1 }
1910
1911tobrace_ini: TOBrace { LP.push_context LP.InInitializer; $1 }
1912tcbrace_ini: TCBrace { LP.pop_context (); $1 }
1913
1914tobrace_struct: TOBrace { LP.push_context LP.InStruct; $1}
1915tcbrace_struct: TCBrace { LP.pop_context (); $1 }
1916
1917
1918
1919
ae4735db
C
1920topar: TOPar
1921 { LP.new_scope ();et "topar" ();
485bce71 1922 LP.push_context LP.InParameter;
ae4735db 1923 $1
485bce71 1924 }
ae4735db
C
1925tcpar: TCPar
1926 { LP.del_scope ();dt "tcpar" ();
1927 LP.pop_context ();
1928 $1
485bce71
C
1929 }
1930
1931
1932
1933
1934/*(*************************************************************************)*/
1935/*(* xxx_list, xxx_opt *)*/
1936/*(*************************************************************************)*/
1937
1938
1939/*(* old:
ae4735db 1940compound2:
485bce71
C
1941 | { ([],[]) }
1942 | statement_list { ([], $1) }
1943 | decl_list { ($1, []) }
1944 | decl_list statement_list { ($1,$2) }
1945
1946statement_list: stat_or_decl_list { $1 }
1947*)*/
1948
1949
1950/*(*
ae4735db 1951decl_list:
485bce71
C
1952 | decl { [$1] }
1953 | decl_list decl { $1 ++ [$2] }
1954
ae4735db 1955statement_list:
485bce71
C
1956 | statement { [$1] }
1957 | statement_list statement { $1 ++ [$2] }
1958*)*/
34e49164 1959
34e49164
C
1960
1961
1962
1963
ae4735db 1964string_list:
34e49164 1965 | string_elem { $1 }
ae4735db 1966 | string_list string_elem { $1 ++ $2 }
34e49164 1967
ae4735db 1968colon_asm_list:
34e49164
C
1969 | colon_asm { [$1] }
1970 | colon_asm_list colon_asm { $1 ++ [$2] }
1971
ae4735db
C
1972colon_option_list:
1973 | colon_option { [$1, []] }
34e49164
C
1974 | colon_option_list TComma colon_option { $1 ++ [$3, [$2]] }
1975
1976
ae4735db 1977argument_list_ne:
34e49164
C
1978 | argument_ne { [$1, []] }
1979 | argument_list_ne TComma argument { $1 ++ [$3, [$2]] }
1980
ae4735db 1981argument_list:
34e49164
C
1982 | argument { [$1, []] }
1983 | argument_list TComma argument { $1 ++ [$3, [$2]] }
1984
1985/*(*
1986expression_list:
1987 | assign_expr { [$1, []] }
1988 | expression_list TComma assign_expr { $1 ++ [$3, [$2]] }
1989*)*/
1990
1991
ae4735db 1992struct_decl_list:
34e49164
C
1993 | struct_decl { [$1] }
1994 | struct_decl_list struct_decl { $1 ++ [$2] }
1995
1996
ae4735db 1997struct_declarator_list:
34e49164
C
1998 | struct_declarator { [$1, []] }
1999 | struct_declarator_list TComma struct_declarator { $1 ++ [$3, [$2]] }
2000
2001
ae4735db 2002enumerator_list:
34e49164
C
2003 | enumerator { [$1, []] }
2004 | enumerator_list TComma enumerator { $1 ++ [$3, [$2]] }
2005
2006
ae4735db 2007init_declarator_list:
34e49164
C
2008 | init_declarator { [$1, []] }
2009 | init_declarator_list TComma init_declarator { $1 ++ [$3, [$2]] }
2010
2011
ae4735db 2012parameter_list:
34e49164
C
2013 | parameter_decl { [$1, []] }
2014 | parameter_list TComma parameter_decl { $1 ++ [$3, [$2]] }
2015
ae4735db 2016taction_list_ne:
34e49164
C
2017 | TAction { [$1] }
2018 | TAction taction_list_ne { $1 :: $2 }
2019
ae4735db
C
2020taction_list:
2021/*old: was generating conflict, hence now taction_list_ne
485bce71
C
2022 | (* empty *) { [] }
2023 | TAction { [$1] }
2024 | taction_list TAction { $1 ++ [$2] }
2025*/
34e49164
C
2026 | { [] }
2027 | TAction taction_list { $1 :: $2 }
2028
ae4735db 2029param_define_list:
34e49164
C
2030 | /*(* empty *)*/ { [] }
2031 | param_define { [$1, []] }
2032 | param_define_list TComma param_define { $1 ++ [$3, [$2]] }
2033
ae4735db 2034designator_list:
34e49164
C
2035 | designator { [$1] }
2036 | designator_list designator { $1 ++ [$2] }
2037
485bce71
C
2038attribute_list:
2039 | attribute { [$1] }
2040 | attribute_list attribute { $1 ++ [$2] }
2041
2042attribute_storage_list:
2043 | attribute_storage { [$1] }
2044 | attribute_storage_list attribute_storage { $1 ++ [$2] }
2045
2046
2047attributes: attribute_list { $1 }
2048
485bce71 2049
34e49164
C
2050
2051/*(* gccext: which allow a trailing ',' in enum, as in perl *)*/
ae4735db
C
2052gcc_comma_opt:
2053 | TComma { [$1] }
34e49164
C
2054 | /*(* empty *)*/ { [] }
2055
ae4735db
C
2056comma_opt:
2057 | TComma { [$1] }
485bce71
C
2058 | /*(* empty *)*/ { [] }
2059
34e49164
C
2060/*(*
2061gcc_opt_virg:
2062 | TPtVirg { }
2063 | { }
2064*)*/
2065
ae4735db 2066gcc_opt_expr:
34e49164
C
2067 | expr { Some $1 }
2068 | /*(* empty *)*/ { None }
2069
2070/*(*
2071opt_ptvirg:
2072 | TPtVirg { [$1] }
2073 | { [] }
2074*)*/
2075
2076
ae4735db 2077expr_opt:
485bce71
C
2078 | expr { Some $1 }
2079 | /*(* empty *)*/ { None }
34e49164 2080