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