Release coccinelle-0.1.2
[bpt/coccinelle.git] / parsing_c / lexer_parser.ml
CommitLineData
34e49164
C
1(* Copyright (C) 2002-2008 Yoann Padioleau
2 *
3 * This program is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU General Public License (GPL)
5 * version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * file license.txt for more details.
11 *)
12open Common
13
14(* Tricks used to handle the ambiguity in the grammar with the typedef
15 * which impose a cooperation between the lexer and the parser.
16 *
17 * An example by hughes casse: "in the symbol table, local
18 * definition must replace type definition in order to correctly parse
19 * local variable in functions body. This is the only way to correctly
20 * handle this kind of exception, that is,
21 *
22 * typedef ... ID; int f(int *p) {int ID; return (ID) * *p;} If ID
23 * isn't overload, last expression is parsed as a type cast, if it
24 * isn't, this a multiplication."
25 *
26 * Why parse_typedef_fix2 ? Cos when introduce new variable, for
27 * instance when declare parameters for a function such as int var_t,
28 * then the var_t must not be lexed as a typedef, so we must disable
29 * temporaly the typedef mechanism to allow variable with same name as
30 * a typedef. *)
31
32(* parse_typedef_fix *)
33let _handle_typedef = ref true
34
35(* parse_typedef_fix2 *)
36let enable_typedef () = _handle_typedef := true
37let disable_typedef () = _handle_typedef := false
38
39let is_enabled_typedef () = !_handle_typedef
40
41
42
43
44type identkind = TypeDefI | IdentI
45
46(* Ca marche ce code ? on peut avoir un typedef puis un ident puis
47 * un typedef nested ? oui car Hashtbl (dans scoped_h_env) gere l'historique.
48 *
49 * oldsimple: but slow, take 2 secondes on some C files
50 * let (typedef: typedef list list ref) = ref [[]]
51 *)
52let (_typedef : (string, identkind) Common.scoped_h_env ref) =
53 ref (Common.empty_scoped_h_env ())
54
55let is_typedef s = if !_handle_typedef then
56 (match (Common.optionise (fun () -> Common.lookup_h_env s !_typedef)) with
57 | Some TypeDefI -> true
58 | Some IdentI -> false
59 | None -> false
60 )
61 else false
62
63let new_scope() = Common.new_scope_h _typedef
64let del_scope() = Common.del_scope_h _typedef
65
66let add_typedef s = Common.add_in_scope_h _typedef (s, TypeDefI)
67let add_ident s = Common.add_in_scope_h _typedef (s, IdentI)
68
69let add_typedef_root s =
70 if !Flag_parsing_c.add_typedef_root
71 then
72 Hashtbl.add !_typedef.scoped_h s TypeDefI
73 else add_typedef s (* have far more .failed without this *)
74
75
76(* Used by parse_c when do some error recovery. The parse error may
77 * have some bad side effects on typedef hash, so recover this.
78 *)
79let _old_state = ref (Common.clone_scoped_h_env !_typedef)
80
81let save_typedef_state () =
82 _old_state := Common.clone_scoped_h_env !_typedef
83
84let restore_typedef_state () =
85 _typedef := !_old_state
86
87
88
89
485bce71
C
90type context =
91 | InTopLevel
92 | InFunction
93 | InStruct
94 | InParameter
95 | InInitializer
96 | InEnum
97
98let is_top_or_struct = function
99 | InTopLevel
100 | InStruct
101 -> true
102 | _ -> false
103
34e49164 104type lexer_hint = {
485bce71
C
105 mutable context_stack: context Common.stack;
106 }
34e49164
C
107
108let default_hint () = {
485bce71 109 context_stack = [InTopLevel];
34e49164
C
110}
111
112let _lexer_hint = ref (default_hint())
113
485bce71
C
114let current_context () = List.hd !_lexer_hint.context_stack
115let push_context ctx =
116 !_lexer_hint.context_stack <- ctx::!_lexer_hint.context_stack
117let pop_context () =
118 !_lexer_hint.context_stack <- List.tl !_lexer_hint.context_stack
119
120
34e49164
C
121
122let lexer_reset_typedef () =
123 begin
124 _handle_typedef := true;
125 _typedef := Common.empty_scoped_h_env ();
485bce71 126 _lexer_hint := (default_hint ());
34e49164
C
127 end
128