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