4 * Copyright (C) 2002, 2006, 2007, 2008, 2009 Yoann Padioleau
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.
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.
19 module LP = Lexer_parser
20 open Lexer_parser (* for the fields *)
22 open Semantic_c (* Semantic exn *)
24 module Stat = Parsing_stat
26 (*****************************************************************************)
28 (*****************************************************************************)
30 if !Flag_parsing_c.verbose_parsing
31 then Common.warning ("PARSING: " ^ s) v
36 if !Flag_parsing_c.verbose_parsing
39 (*****************************************************************************)
40 (* Parse helpers functions *)
41 (*****************************************************************************)
43 (*-------------------------------------------------------------------------- *)
45 (*-------------------------------------------------------------------------- *)
47 type shortLong = Short | Long | LongLong
50 storageD: storagebis wrap;
51 typeD: ((sign option) * (shortLong option) * (typeCbis option)) wrap;
52 qualifD: typeQualifierbis 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 *)
61 typeD = (None, None, None), [];
65 let fake_pi = Common.fake_parse_info
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))
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
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}
89 | ((Middle3 Short,ii), ({typeD = ((a,Some Short,c),ii2)} as v)) ->
90 warning "duplicate 'short'" v
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
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}
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}
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}
117 internal_error "there is no noconst or novolatile keyword"
119 let addQualifD ((qu,ii), ({qualifD = (v,ii2)} as x)) =
120 { x with qualifD = (addQualif (qu, v),ii::ii2) }
123 (*-------------------------------------------------------------------------- *)
124 (* Declaration/Function related *)
125 (*-------------------------------------------------------------------------- *)
128 (* stdC: type section, basic integer types (and ritchie)
129 * To understand the code, just look at the result (right part of the PM)
132 let (fixDeclSpecForDecl: decl -> (fullType * (storage wrap))) = function
133 {storageD = (st,iist);
136 inlineD = (inline,iinl);
141 | (None,None,None) ->
142 (* generate fake_info, otherwise type_annotater can crash in
145 warning "type defaults to 'int'" (defaultInt, [fakeInfo fake_pi])
146 | (None, None, Some t) -> (t, iit)
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
157 | (Some _,_, Some _) ->
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))
165 | (_, Some _, Some _) ->
167 raise (Semantic ("long, short valid only for int or float", fake_pi))
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) *)
178 ,((st, inline),iist++iinl)
181 let fixDeclSpecForParam = function ({storageD = (st,iist)} as r) ->
182 let ((qu,ty) as v,_st) = fixDeclSpecForDecl r in
184 | (Sto Register) -> (v, true), iist
185 | NoSto -> (v, false), iist
188 (Semantic ("storage class specified for parameter of function",
191 let fixDeclSpecForFuncDef x =
192 let (returnType,storage) = fixDeclSpecForDecl x in
193 (match fst (unwrap storage) with
195 raise (Semantic ("function definition declared 'typedef'", fake_pi))
196 | _ -> (returnType, storage)
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)
209 let (fixOldCDecl: fullType -> fullType) = fun ty ->
211 | ((FunctionType (fullt, (params, (b, iib)))),iifunc) ->
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. *)
218 | [{p_namei = None; p_type = ((_qua, (BaseType Void,_)))},_] ->
221 (params +> List.iter (fun (param,_) ->
223 | {p_namei = None} ->
224 (* if majuscule, then certainly macro-parameter *)
225 pr2 ("SEMANTIC:parameter name omitted, but I continue");
230 (* todo? can we declare prototype in the decl or structdef,
231 ... => length <> but good kan meme *)
233 (* gcc say parse error but dont see why *)
234 raise (Semantic ("seems this is not a function", fake_pi))
237 let fixFunc (typ, compound, old_style_opt) =
238 let (cp,iicp) = compound in
242 (nQ, (FunctionType (fullt, (params,bool)),iifunc)),
246 let iistart = Ast_c.fakeInfo () in
247 assert (nQ =*= nullQualif);
249 | [{p_namei= None; p_type =((_qua, (BaseType Void,_)))}, _] -> ()
251 params +> List.iter (function
252 | ({p_namei = Some s}, _) -> ()
254 (* failwith "internal errror: fixOldCDecl not good" *)
257 (* bugfix: cf tests_c/function_pointer4.c.
258 * Apparemment en C on peut syntaxiquement ecrire ca:
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).
272 (match Ast_c.unwrap_typeC fullt with
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))
282 (* it must be nullQualif,cos parser construct only this*)
284 f_type = (fullt, (params, bool));
288 f_old_c_style = old_style_opt;
290 (iifunc++iicp++[iistart]++iist)
294 ("you are trying to do a function definition but you dont give " ^
295 "any parameter", fake_pi))
298 (*-------------------------------------------------------------------------- *)
299 (* parse_typedef_fix2 *)
300 (*-------------------------------------------------------------------------- *)
303 if !Flag_parsing_c.debug_etdt then pr2 ("<" ^ s);
304 LP.disable_typedef ()
307 if !Flag_parsing_c.debug_etdt then pr2 (">" ^ s);
311 let fix_add_params_ident = function
312 | ((s, (nQ, (FunctionType (fullt, (params, bool)),_)), st, _attrs)) ->
315 | [{p_namei=None; p_type=((_qua, (BaseType Void,_)))}, _] -> ()
317 params +> List.iter (function
318 | ({p_namei= Some name}, _) ->
319 LP.add_ident (Ast_c.str_of_name s)
322 (* failwith "internal errror: fixOldCDecl not good" *)
329 (*-------------------------------------------------------------------------- *)
331 (*-------------------------------------------------------------------------- *)
333 let mk_e e ii = ((e, Ast_c.noType()), ii)
335 let mk_string_wrap (s,info) = (s, [info])
339 /*(*****************************************************************************)*/
341 /*(*************************************************************************)*/
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)
352 %token <Ast_c.info> TUnknown /*(* unrecognized token *)*/
354 /*(* coupling: Token_helpers.is_real_comment *)*/
355 %token <Ast_c.info> TCommentSpace TCommentNewline TComment
357 /*(*-----------------------------------------*)*/
358 /*(* the normal tokens *)*/
359 /*(*-----------------------------------------*)*/
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
366 %token <string * Ast_c.info> TIdent
367 /*(* appears mostly after some fix_xxx in parsing_hack *)*/
368 %token <string * Ast_c.info> TypedefIdent
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.
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
387 %token <Ast_c.info> TPtVirg
389 TOrLog TAndLog TOr TXor TAnd TEqEq TNotEq TInf TSup TInfEq TSupEq
391 TPlus TMinus TMul TDiv TMod
394 Tchar Tshort Tint Tdouble Tfloat Tlong Tunsigned Tsigned Tvoid
395 Tauto Tregister Textern Tstatic
399 Tbreak Telse Tswitch Tcase Tcontinue Tfor Tdo Tif Twhile Treturn
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
415 /*(*-----------------------------------------*)*/
416 /*(* cppext: extra tokens *)*/
417 /*(*-----------------------------------------*)*/
418 /*(* coupling with Token_helpers.is_cpp_token *)*/
421 /*(*---------------*)*/
423 /*(*---------------*)*/
425 %token <Ast_c.info> TDefine
426 %token <(string * Ast_c.info)> TDefParamVariadic
428 /*(* disappear after fix_tokens_define *)*/
429 %token <Ast_c.info> TCppEscapedNewline
431 %token <Ast_c.info> TCppConcatOp
433 /*(* appear after fix_tokens_define *)*/
434 %token <Ast_c.info> TOParDefine
435 %token <Ast_c.info> TOBraceDefineInit
437 %token <(string * Ast_c.info)> TIdentDefine /*(* same *)*/
438 %token <Ast_c.info> TDefEOL /*(* same *)*/
441 /*(*---------------*)*/
443 /*(*---------------*)*/
446 /*(* used only in lexer_c, then transformed in comment or splitted in tokens *)*/
447 %token <(string * string * bool ref * Ast_c.info)> TInclude
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
454 /*(*---------------*)*/
456 /*(*---------------*)*/
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
464 /*(*---------------*)*/
466 /*(*---------------*)*/
469 %token <string * Ast_c.info> TUndef
471 %token <Ast_c.info> TCppDirectiveOther
473 /*(*---------------*)*/
475 /*(*---------------*)*/
477 /*(* appear after fix_tokens_cpp, cf also parsing_hacks#hint *)*/
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 *)*/
490 %token <(string * Ast_c.info)> TMacroAttrStorage
493 /*(*---------------*)*/
495 /*(*---------------*)*/
498 /*(* should disappear after parsing_hack *)*/
499 %token <Ast_c.info> TCommentSkipTagStart TCommentSkipTagEnd
502 /*(* appear after parsing_hack *)*/
503 %token <Ast_c.info> TCParEOL
505 %token <Ast_c.info> TAction
508 /*(* TCommentMisc still useful ? obsolete ? *)*/
509 %token <Ast_c.info> TCommentMisc
510 %token <(Token_c.cppcommentkind * Ast_c.info)> TCommentCpp
513 /*(*-----------------------------------------*)*/
514 %token <Ast_c.info> EOF
516 /*(*-----------------------------------------*)*/
518 /*(* must be at the top so that it has the lowest priority *)*/
529 %left TInf TSup TInfEq TSupEq
534 /*(*************************************************************************)*/
535 /*(* Rules type declaration *)*/
536 /*(*************************************************************************)*/
538 %start main celem statement expr type_name
539 %type <Ast_c.program> main
540 %type <Ast_c.toplevel> celem
542 %type <Ast_c.statement> statement
543 %type <Ast_c.expression> expr
544 %type <Ast_c.fullType> type_name
547 /*(*************************************************************************)*/
550 * toplevel (obsolete)
556 * - left part (type_spec, qualif),
557 * - right part (declarator, abstract declarator)
558 * - aux part (parameters)
559 * declaration, storage, initializers
565 * generic workarounds (obrace, cbrace for context setting)
569 /*(*************************************************************************)*/
571 /*(*************************************************************************)*/
573 /*(*************************************************************************)*/
574 /*(* no more used; now that use error recovery *)*/
576 main: translation_unit EOF { $1 }
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] }
586 /*(*************************************************************************)*/
588 /*(*************************************************************************)*/
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.
596 | TypedefIdent { $1 }
603 (* cppext: string concatenation of idents
604 * also cppext: gccext: ##args for variadic macro
609 { RegularName (mk_string_wrap $1) }
610 | TIdent TCppConcatOp identifier_cpp_list
612 CppConcatenatedName (
614 | [] -> raise Impossible
615 | (x,concatnull)::xs ->
616 assert(null concatnull);
617 (mk_string_wrap $1, [])::(x,[$2])::xs
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) }
626 | TIdent { [mk_string_wrap $1, []] }
627 | identifier_cpp_list TCppConcatOp TIdent { $1 ++ [mk_string_wrap $3, [$2]] }
629 /*(*************************************************************************)*/
631 /*(*************************************************************************)*/
635 | expr TComma assign_expr { mk_e (Sequence ($1,$3)) [$2] }
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
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]}
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
652 | arith_expr TWhy gcc_opt_expr TDotDot assign_expr
653 { mk_e (CondExpr ($1,$3,$5)) [$2;$4] }
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] }
679 | topar2 type_name tcpar2 cast_expr { mk_e(Cast ($2, $4)) [$1;$3] }
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] }
690 | TAnd { GetRef, $1 }
692 | TPlus { UnPlus, $1 }
693 | TMinus { UnMinus, $1 }
694 | TTilde { Tilde, $1 }
696 /*(* gccext: have that a lot in old kernel to get address of local label.
697 * cf gcc manual "local labels as values".
699 | TAndLog { GetRefLabel, $1 }
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] }
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) }
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: *)*/
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) }
734 /*(* gccext: allow statement as expressions via ({ statement }) *)*/
735 | TOPar compound TCPar { mk_e(StatementExpr ($2)) [$1;$3] }
739 /*(*----------------------------*)*/
741 /*(*----------------------------*)*/
744 /*(* to avoid conflicts have to introduce a _not_empty (ne) version *)*/
746 | assign_expr { Left $1 }
747 | parameter_decl { Right (ArgType $1) }
748 | action_higherordermacro_ne { Right (ArgAction $1) }
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) }
757 action_higherordermacro_ne:
760 then ActMisc [Ast_c.fakeInfo()]
765 action_higherordermacro:
768 then ActMisc [Ast_c.fakeInfo()]
773 /*(*----------------------------*)*/
774 /*(* workarounds *)*/
775 /*(*----------------------------*)*/
777 /*(* would like evalInt $1 but require too much info *)*/
778 const_expr: cond_expr { $1 }
781 topar2: TOPar { et "topar2" (); $1 }
782 tcpar2: TCPar { et "tcpar2" (); $1 (*TODO? et ? sure ? c pas dt plutot ? *) }
786 /*(*************************************************************************)*/
788 /*(*************************************************************************)*/
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] }
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] }
803 | TMacroStmt { MacroStmt, [snd $1] }
808 /*(* note that case 1: case 2: i++; would be correctly parsed, but with
809 * a Case (1, (Case (2, i++))) :(
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] }
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
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] }
834 compound: tobrace compound2 tcbrace { $2, [$1; $3] }
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.
847 | stat_or_decl_list { $1 }
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 }
858 | decl { StmtElem (Decl ($1 Ast_c.LocalDecl), []) }
859 | statement { StmtElem $1 }
862 | function_definition { StmtElem (NestedFunc $1, []) }
866 { CppDirectiveStmt $1 }
867 | cpp_ifdef_directive/*(* stat_or_decl_list ...*)*/
875 | TPtVirg { None, [$1] }
876 | expr TPtVirg { Some $1, [$2] }
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] }
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
898 (* pr2 "DECL in for"; *)
899 MacroIteration ("toto", [], $7),[$1;$2;$6] (* TODOfake ast, TODO need decl2 ? *)
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] }
907 /*(* the ';' in the caller grammar rule will be appended to the infos *)*/
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] }
918 /*(*----------------------------*)*/
920 /*(*----------------------------*)*/
922 | TString { [snd $1] }
923 /*(* cppext: ex= printk (KERN_INFO "xxx" UTS_RELEASE) *)*/
924 | TMacroString { [snd $1] }
928 | string_list colon_asm_list { $1, $2 }
929 | string_list { $1, [] } /*(* in old kernel *)*/
932 colon_asm: TDotDot colon_option_list { Colon $2, [$1] }
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, [] }
943 asm_expr: assign_expr { $1 }
945 /*(*************************************************************************)*/
947 /*(*************************************************************************)*/
950 /*(*-----------------------------------------------------------------------*)*/
951 /*(* Type spec, left part of a type *)*/
952 /*(*-----------------------------------------------------------------------*)*/
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 }
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.
971 * parse_typedef_fix2: this is not enough, and you must use
972 * parse_typedef_fix2 to fully manage typedef problems in grammar.
974 * parse_typedef_fix3:
976 * parse_typedef_fix4: try also to do now some consistency checking in
980 { let name = RegularName (mk_string_wrap $1) in
981 Right3 (TypeName (name, Ast_c.noTypedefDef())),[] }
983 | Ttypeof TOPar assign_expr TCPar { Right3 (TypeOfExpr ($3)), [$1;$2;$4] }
984 | Ttypeof TOPar type_name TCPar { Right3 (TypeOfType ($3)), [$1;$2;$4] }
986 /*(*----------------------------*)*/
987 /*(* workarounds *)*/
988 /*(*----------------------------*)*/
990 type_spec: type_spec2 { dt "type" (); $1 }
992 /*(*-----------------------------------------------------------------------*)*/
994 /*(*-----------------------------------------------------------------------*)*/
997 | Tconst { {const=true ; volatile=false}, $1 }
998 | Tvolatile { {const=false ; volatile=true}, $1 }
1000 | Trestrict { (* TODO *) {const=false ; volatile=false}, $1 }
1003 /*(*-----------------------------------------------------------------------*)*/
1004 /*(* gccext: attributes *)*/
1005 /*(*-----------------------------------------------------------------------*)*/
1008 | Tattribute TOPar /*stuff*/ TCPar { raise Todo }
1010 | TMacroAttr { Attribute (fst $1), [snd $1] }
1014 | TMacroAttrStorage { $1 }
1017 | type_qualif { $1 }
1019 | TMacroAttr { {const=true ; volatile=false}, snd $1 }
1021 /*(*-----------------------------------------------------------------------*)*/
1022 /*(* Declarator, right part of a type + second part of decl (the ident) *)*/
1023 /*(*-----------------------------------------------------------------------*)*/
1026 (* declarator return a couple:
1027 * (name, partial type (a function to be applied to return type))
1029 * when int* f(int) we must return Func(Pointer int,int) and not
1030 * Pointer (Func(int,int)
1034 | pointer direct_d { (fst $2, fun x -> x +> $1 +> (snd $2) ) }
1037 /*(* so must do int * const p; if the pointer is constant, not the pointee *)*/
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]))}
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
1057 (nQ,(FunctionType (x,(([],(false, [])))),[$2;$3])))
1059 | direct_d topar parameter_type_list tcpar
1060 { (fst $1,fun x->(snd $1) (nQ,(FunctionType (x, $3), [$2;$4]))) }
1063 /*(*----------------------------*)*/
1064 /*(* workarounds *)*/
1065 /*(*----------------------------*)*/
1067 tocro: TOCro { et "tocro" ();$1 }
1068 tccro: TCCro { dt "tccro" ();$1 }
1070 /*(*-----------------------------------------------------------------------*)*/
1071 abstract_declarator:
1073 | direct_abstract_declarator { $1 }
1074 | pointer direct_abstract_declarator { fun x -> x +> $2 +> $1 }
1076 direct_abstract_declarator:
1077 | TOPar abstract_declarator TCPar /*(* forunparser: old: $2 *)*/
1078 { (fun x -> (nQ, (ParenType ($2 x), [$1;$3]))) }
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])) }
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.
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])) }
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])) }
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);
1123 | decl_spec abstract_declaratorp
1124 { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in
1126 p_type = $2 returnType;
1127 p_register = hasreg, iihasreg;
1131 { let ((returnType,hasreg), iihasreg) = fixDeclSpecForParam $1 in
1133 p_type = returnType;
1134 p_register = hasreg, iihasreg;
1139 /*(*----------------------------*)*/
1140 /*(* workarounds *)*/
1141 /*(*----------------------------*)*/
1143 parameter_decl: parameter_decl2 { et "param" (); $1 }
1146 | declarator { LP.add_ident (str_of_name (fst $1)); $1 }
1148 | attributes declarator { LP.add_ident (str_of_name (fst $2)); $2 }
1149 | declarator attributes { LP.add_ident (str_of_name (fst $1)); $1 }
1151 abstract_declaratorp:
1152 | abstract_declarator { $1 }
1154 | attributes abstract_declarator { $2 }
1156 /*(*-----------------------------------------------------------------------*)*/
1157 /*(* helper type rules *)*/
1158 /*(*-----------------------------------------------------------------------*)*/
1160 /*(* for struct and also typename *)*/
1161 /*(* cant put decl_spec cos no storage is allowed for field struct *)*/
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) }
1168 spec_qualif_list: spec_qualif_list2 { dt "spec_qualif" (); $1 }
1171 /*(* for pointers in direct_declarator and abstract_declarator *)*/
1173 | type_qualif_attr { {nullDecl with qualifD = (fst $1,[snd $1])} }
1174 | type_qualif_list type_qualif_attr { addQualifD ($2,$1) }
1181 /*(*-----------------------------------------------------------------------*)*/
1182 /*(* xxx_type_id *)*/
1183 /*(*-----------------------------------------------------------------------*)*/
1187 { let (returnType, _) = fixDeclSpecForDecl $1 in returnType }
1188 | spec_qualif_list abstract_declaratort
1189 { let (returnType, _) = fixDeclSpecForDecl $1 in $2 returnType }
1193 abstract_declaratort:
1194 | abstract_declarator { $1 }
1196 | attributes abstract_declarator { $2 }
1199 /*(*************************************************************************)*/
1200 /*(* declaration and initializers *)*/
1201 /*(*************************************************************************)*/
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;
1212 ($2::iistart::snd storage))
1214 | decl_spec init_declarator_list TPtVirg
1216 let (returnType,storage) = fixDeclSpecForDecl $1 in
1217 let iistart = Ast_c.fakeInfo () in
1219 ($2 +> List.map (fun ((((name,f),attrs), ini), iivirg) ->
1220 let s = str_of_name name in
1224 | Some (ini, iini) -> Some (iini, ini)
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;
1236 ), ($3::iistart::snd storage))
1240 | TMacroDecl TOPar argument_list TCPar TPtVirg
1242 MacroDecl ((fst $1, $3), [snd $1;$2;$4;$5;fakeInfo()]) }
1243 | Tstatic TMacroDecl TOPar argument_list TCPar TPtVirg
1245 MacroDecl ((fst $2, $4), [snd $2;$3;$5;$6;fakeInfo();$1]) }
1246 | Tstatic TMacroDeclConst TMacroDecl TOPar argument_list TCPar TPtVirg
1248 MacroDecl ((fst $3, $5), [snd $3;$4;$6;$7;fakeInfo();$1;$2])}
1251 /*(*-----------------------------------------------------------------------*)*/
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) }
1262 /*(* can simplify by putting all in _opt ? must have at least one otherwise
1263 * decl_list is ambiguous ? (no cos have ';' between decl)
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 }
1276 | storage_class_spec2 { $1 }
1277 | storage_class_spec2 attributes_storage { $1 (* TODO *) }
1281 /*(*----------------------------*)*/
1282 /*(* workarounds *)*/
1283 /*(*----------------------------*)*/
1285 decl: decl2 { et "decl" (); $1 }
1286 decl_spec: decl_spec2 { dt "declspec" (); $1 }
1288 /*(*-----------------------------------------------------------------------*)*/
1289 /*(* declarators (right part of type and variable) *)*/
1290 /*(*-----------------------------------------------------------------------*)*/
1292 | declaratori { ($1, None) }
1293 | declaratori teq initialize { ($1, Some ($3, $2)) }
1297 /*(*----------------------------*)*/
1298 /*(* workarounds *)*/
1299 /*(*----------------------------*)*/
1300 teq: TEq { et "teq" (); $1 }
1302 init_declarator: init_declarator2 { dt "init" (); $1 }
1305 /*(*----------------------------*)*/
1307 /*(*----------------------------*)*/
1310 | declarator { LP.add_ident (str_of_name (fst $1)); $1, Ast_c.noattr }
1312 | declarator gcc_asm_decl { LP.add_ident (str_of_name (fst $1)); $1, Ast_c.noattr }
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 *) }
1320 | Tasm TOPar asmbody TCPar { }
1321 | Tasm Tvolatile TOPar asmbody TCPar { }
1324 /*(*-----------------------------------------------------------------------*)*/
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: *)*/
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'.
1342 | initialize2 { [$1, []] }
1343 | initialize_list TComma initialize2 { ($3, [$2])::$1 }
1346 /*(* gccext: condexpr and no assign_expr cos can have ambiguity with comma *)*/
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] }
1355 /*(* gccext: labeled elements, a.k.a designators *)*/
1356 | designator_list TEq initialize2
1357 { InitDesignators ($1, $3), [$2] }
1359 /*(* gccext: old format *)*/
1360 | ident TDotDot initialize2
1361 { InitFieldOld (fst $1, $3), [snd $1; $2] } /*(* in old kernel *)*/
1363 | TOCro const_expr TCCro initialize2
1364 { InitIndexOld ($2, $4), [$1;$3] }
1369 /*(* they can be nested, can have a .x[3].y *)*/
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] }
1379 /*(*----------------------------*)*/
1380 /*(* workarounds *)*/
1381 /*(*----------------------------*)*/
1383 gcc_comma_opt_struct:
1385 | /*(* empty *)*/ { [Ast_c.fakeInfo() +> Ast_c.rewrap_str ","] }
1394 /*(*************************************************************************)*/
1396 /*(*************************************************************************)*/
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] }
1407 | Tstruct { Struct, $1 }
1408 | Tunion { Union, $1 }
1410 | Tstruct attributes { Struct, $1 (* TODO *) }
1411 | Tunion attributes { Union, $1 (* TODO *) }
1416 | field_declaration { DeclarationField $1, noii }
1417 | TPtVirg { EmptyField, [$1] }
1418 | TMacroStructDecl { MacroStructDeclTodo, [] }
1422 { CppDirectiveStruct $1, noii }
1423 | cpp_ifdef_directive/*(* struct_decl_list ... *)*/
1424 { IfdefStruct $1, noii }
1428 | spec_qualif_list struct_declarator_list TPtVirg
1430 let (returnType,storage) = fixDeclSpecForDecl $1 in
1431 if fst (unwrap storage) <> NoSto
1432 then internal_error "parsing dont allow this";
1434 FieldDeclList ($2 +> (List.map (fun (f, iivirg) ->
1435 f returnType, iivirg))
1437 (* dont need to check if typedef or func initialised cos
1438 * grammar dont allow typedef nor initialiser in struct
1442 | spec_qualif_list TPtVirg
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";
1449 FieldDeclList ([(Simple (None, returnType)) , []], [$2])
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)) }
1465 /*(*----------------------------*)*/
1466 /*(* workarounds *)*/
1467 /*(*----------------------------*)*/
1469 | declarator { (*also ? LP.add_ident (fst (fst $1)); *) $1 }
1471 | attributes declarator { $2 }
1472 | declarator attributes { $1 }
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 }
1481 dotdot: TDotDot { et "dotdot" (); $1 }
1482 const_expr2: const_expr { dt "const_expr2" (); $1 }
1484 struct_decl_list_gcc:
1485 | struct_decl_list { $1 }
1486 | /*(* empty *)*/ { [] } /*(* gccext: allow empty struct *)*/
1489 /*(*************************************************************************)*/
1491 /*(*************************************************************************)*/
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 }
1498 { EnumName (fst $2), [$1; snd $2] }
1501 | idente { $1, None }
1502 | idente TEq const_expr { $1, Some ($2, $3) }
1505 /*(*----------------------------*)*/
1506 /*(* workarounds *)*/
1507 /*(*----------------------------*)*/
1509 idente: ident_cpp { LP.add_ident (str_of_name $1); $1 }
1513 /*(*************************************************************************)*/
1515 /*(*************************************************************************)*/
1516 function_definition: function_def { fixFunc $1 }
1519 | decl { [$1 Ast_c.LocalDecl] }
1520 | decl_list decl { $1 ++ [$2 Ast_c.LocalDecl] }
1523 | start_fun compound { LP.del_scope(); ($1, $2, None) }
1524 | start_fun decl_list compound {
1525 (* TODO: undo the typedef added ? *)
1530 start_fun: start_fun2
1532 fix_add_params_ident $1;
1533 (* toreput? !LP._lexer_hint.toplevel <- false; *)
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)
1543 /*(*----------------------------*)*/
1544 /*(* workarounds *)*/
1545 /*(*----------------------------*)*/
1548 | declarator { et "declaratorfd" (); $1, Ast_c.noattr }
1550 | attributes declarator { et "declaratorfd" (); $2, $1 }
1551 | declarator attributes { et "declaratorfd" (); $1, Ast_c.noattr }
1555 /*(*************************************************************************)*/
1556 /*(* cpp directives *)*/
1557 /*(*************************************************************************)*/
1560 | TIncludeStart TIncludeFilename
1562 let (i1, in_ifdef) = $1 in
1565 (* redo some lexing work :( *)
1568 | _ when s =~ "^\"\\(.*\\)\"$" ->
1569 Local (Common.split "/" (matched1 s))
1570 | _ when s =~ "^\\<\\(.*\\)\\>$" ->
1571 NonLocal (Common.split "/" (matched1 s))
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;
1582 | TDefine TIdentDefine define_val TDefEOL
1583 { Define ((fst $2, [$1; snd $2;$4]), (DefineVar, $3)) }
1586 (* The TOParDefine is introduced to avoid ambiguity with previous rules.
1587 * A TOParDefine is a TOPar that was just next to the ident.
1589 | TDefine TIdentDefine TOParDefine param_define_list TCPar define_val TDefEOL
1591 ((fst $2, [$1; snd $2;$7]),
1592 (DefineFunc ($4, [$3;$5]), $6))
1595 | TUndef { Undef (fst $1, [snd $1]) }
1596 | TCppDirectiveOther { PragmaAndCo ([$1]) }
1602 /*(* perhaps better to use assign_expr ? but in that case need
1603 * do a assign_expr_of_string in parse_c
1606 | expr { DefineExpr $1 }
1607 | statement { DefineStmt $1 }
1608 | decl { DefineStmt (Decl ($1 Ast_c.NotLocalDecl), []) }
1610 /*(*old: | TypedefIdent { DefineType (nQ,(TypeName(fst $1,noTypedefDef()),[snd $1]))}*)*/
1611 | spec_qualif_list { DefineTodo }
1612 | function_definition { DefineFunction $1 }
1614 | TOBraceDefineInit initialize_list gcc_comma_opt_struct TCBrace comma_opt
1615 { DefineInit (InitList (List.rev $2), [$1;$4]++$3++$5) }
1617 /*(* note: had a conflict before when were putting TInt instead of expr *)*/
1618 | Tdo statement Twhile TOPar expr TCPar
1622 then pr2 "WEIRD: in macro and have not a while(0)";
1624 DefineDoWhileZero (($2,$5), [$1;$3;$4;$6])
1627 /*(* a few special cases *)*/
1628 | stat_or_decl stat_or_decl_list { DefineTodo }
1630 | statement statement { DefineTodo }
1631 | decl function_definition { DefineTodo }
1634 | Tasm TOPar asmbody TCPar { DefineTodo }
1635 | Tasm Tvolatile TOPar asmbody TCPar { DefineTodo }
1638 /*(* aliases macro *)*/
1639 | TMacroAttr { DefineTodo }
1640 | storage_class_spec { DefineTodo }
1641 | Tinline { DefineTodo }
1643 | /*(* empty *)*/ { DefineEmpty }
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] }
1659 cpp_ifdef_directive:
1661 { let (tag,ii) = $1 in
1662 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
1664 { let (tag,ii) = $1 in
1665 IfdefDirective ((IfdefElse, IfdefTag (Common.some !tag)), [ii]) }
1667 { let (tag,ii) = $1 in
1668 IfdefDirective ((IfdefElseif, IfdefTag (Common.some !tag)), [ii]) }
1670 { let (tag,ii) = $1 in
1671 IfdefDirective ((IfdefEndif, IfdefTag (Common.some !tag)), [ii]) }
1674 { let (_b, tag,ii) = $1 in
1675 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
1677 { let (_b, tag,ii) = $1 in
1678 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
1680 { let (_b, tag,ii) = $1 in
1681 IfdefDirective ((Ifdef, IfdefTag (Common.some !tag)), [ii]) }
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.
1690 | identifier TOPar argument_list TCPar TPtVirg
1691 { MacroTop (fst $1, $3, [snd $1;$2;$4;$5]) }
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()]) }
1697 /*(* ex: EXPORT_NO_SYMBOLS; *)*/
1698 | identifier TPtVirg { EmptyDef [snd $1;$2] }
1702 /*(*************************************************************************)*/
1704 /*(*************************************************************************)*/
1706 external_declaration:
1707 | function_definition { Definition $1 }
1708 | decl { Declaration ($1 Ast_c.NotLocalDecl) }
1712 | external_declaration { $1 }
1719 | cpp_ifdef_directive /* (*external_declaration_list ...*)*/
1722 /*(* can have asm declaration at toplevel *)*/
1723 | Tasm TOPar asmbody TCPar TPtVirg { EmptyDef [$1;$2;$4;$5] }
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
1730 | TPtVirg { EmptyDef [$1] }
1733 | EOF { FinalDef $1 }
1738 /*(*************************************************************************)*/
1739 /*(* some generic workarounds *)*/
1740 /*(*************************************************************************)*/
1742 tobrace: TOBrace { LP.push_context LP.InFunction; LP.new_scope (); $1 }
1743 tcbrace: TCBrace { LP.pop_context(); LP.del_scope (); $1 }
1745 tobrace_enum: TOBrace { LP.push_context LP.InEnum; $1 }
1746 tcbrace_enum: TCBrace { LP.pop_context (); $1 }
1748 tobrace_ini: TOBrace { LP.push_context LP.InInitializer; $1 }
1749 tcbrace_ini: TCBrace { LP.pop_context (); $1 }
1751 tobrace_struct: TOBrace { LP.push_context LP.InStruct; $1}
1752 tcbrace_struct: TCBrace { LP.pop_context (); $1 }
1758 { LP.new_scope ();et "topar" ();
1759 LP.push_context LP.InParameter;
1763 { LP.del_scope ();dt "tcpar" ();
1771 /*(*************************************************************************)*/
1772 /*(* xxx_list, xxx_opt *)*/
1773 /*(*************************************************************************)*/
1779 | statement_list { ([], $1) }
1780 | decl_list { ($1, []) }
1781 | decl_list statement_list { ($1,$2) }
1783 statement_list: stat_or_decl_list { $1 }
1790 | decl_list decl { $1 ++ [$2] }
1793 | statement { [$1] }
1794 | statement_list statement { $1 ++ [$2] }
1802 | string_elem { $1 }
1803 | string_list string_elem { $1 ++ $2 }
1806 | colon_asm { [$1] }
1807 | colon_asm_list colon_asm { $1 ++ [$2] }
1810 | colon_option { [$1, []] }
1811 | colon_option_list TComma colon_option { $1 ++ [$3, [$2]] }
1815 | argument_ne { [$1, []] }
1816 | argument_list_ne TComma argument { $1 ++ [$3, [$2]] }
1819 | argument { [$1, []] }
1820 | argument_list TComma argument { $1 ++ [$3, [$2]] }
1824 | assign_expr { [$1, []] }
1825 | expression_list TComma assign_expr { $1 ++ [$3, [$2]] }
1830 | struct_decl { [$1] }
1831 | struct_decl_list struct_decl { $1 ++ [$2] }
1834 struct_declarator_list:
1835 | struct_declarator { [$1, []] }
1836 | struct_declarator_list TComma struct_declarator { $1 ++ [$3, [$2]] }
1840 | enumerator { [$1, []] }
1841 | enumerator_list TComma enumerator { $1 ++ [$3, [$2]] }
1844 init_declarator_list:
1845 | init_declarator { [$1, []] }
1846 | init_declarator_list TComma init_declarator { $1 ++ [$3, [$2]] }
1850 | parameter_decl { [$1, []] }
1851 | parameter_list TComma parameter_decl { $1 ++ [$3, [$2]] }
1855 | TAction taction_list_ne { $1 :: $2 }
1858 /*old: was generating conflict, hence now taction_list_ne
1859 | (* empty *) { [] }
1861 | taction_list TAction { $1 ++ [$2] }
1864 | TAction taction_list { $1 :: $2 }
1867 | /*(* empty *)*/ { [] }
1868 | param_define { [$1, []] }
1869 | param_define_list TComma param_define { $1 ++ [$3, [$2]] }
1872 | designator { [$1] }
1873 | designator_list designator { $1 ++ [$2] }
1876 | attribute { [$1] }
1877 | attribute_list attribute { $1 ++ [$2] }
1879 attribute_storage_list:
1880 | attribute_storage { [$1] }
1881 | attribute_storage_list attribute_storage { $1 ++ [$2] }
1884 attributes: attribute_list { $1 }
1886 attributes_storage: attribute_storage_list { $1 }
1889 /*(* gccext: which allow a trailing ',' in enum, as in perl *)*/
1892 | /*(* empty *)*/ { [] }
1896 | /*(* empty *)*/ { [] }
1906 | /*(* empty *)*/ { None }
1917 | /*(* empty *)*/ { None }