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