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