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