~npalix/coccinelle/upstream

« back to all changes in this revision

Viewing changes to parsing_c/lexer_parser.ml

  • Committer: Nicolas Palix
  • Date: 2010-01-28 14:23:49 UTC
  • Revision ID: git-v1:70d17887795852eca805bfe27745b9810c0a39be
Remove trailing whitespace/tab

svn path=/coccinelle/; revision=8684

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
(* Yoann Padioleau
2
 
 * 
 
2
 *
3
3
 * Copyright (C) 2010, University of Copenhagen DIKU and INRIA.
4
4
 * Copyright (C) 2002, 2006 Yoann Padioleau
5
5
 *
6
6
 * This program is free software; you can redistribute it and/or
7
7
 * modify it under the terms of the GNU General Public License (GPL)
8
8
 * version 2 as published by the Free Software Foundation.
9
 
 * 
 
9
 *
10
10
 * This program is distributed in the hope that it will be useful,
11
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
16
 
17
17
(* Tricks used to handle the ambiguity in the grammar with the typedef
18
18
 * which impose a cooperation between the lexer and the parser.
19
 
 * 
 
19
 *
20
20
 * An example by hughes casse: "in the symbol table, local
21
21
 * definition must replace type definition in order to correctly parse
22
22
 * local variable in functions body. This is the only way to correctly
23
23
 * handle this kind of exception, that is,
24
 
 * 
 
24
 *
25
25
 * typedef ... ID; int f(int *p) {int ID; return (ID) * *p;} If ID
26
26
 * isn't overload, last expression is parsed as a type cast, if it
27
27
 * isn't, this a multiplication."
28
 
 * 
 
28
 *
29
29
 * Why parse_typedef_fix2 ? Cos when introduce new variable, for
30
30
 * instance when declare parameters for a function such as int var_t,
31
31
 * then the var_t must not be lexed as a typedef, so we must disable
49
49
type identkind = TypeDefI | IdentI
50
50
 
51
51
(* Ca marche ce code ? on peut avoir un typedef puis un ident puis
52
 
 * un typedef nested ? oui car Hashtbl (dans scoped_h_env) gere l'historique. 
53
 
 * 
54
 
 * oldsimple:  but slow,  take 2 secondes on some C files 
 
52
 * un typedef nested ? oui car Hashtbl (dans scoped_h_env) gere l'historique.
 
53
 *
 
54
 * oldsimple:  but slow,  take 2 secondes on some C files
55
55
 *    let (typedef: typedef list list ref) = ref [[]]
56
56
 *)
57
 
let (_typedef : (string, identkind) Common.scoped_h_env ref) = 
 
57
let (_typedef : (string, identkind) Common.scoped_h_env ref) =
58
58
  ref (Common.empty_scoped_h_env ())
59
 
   
 
59
 
60
60
let is_typedef s  = if !_handle_typedef || !_always_look_typedef then
61
61
  (match (Common.optionise (fun () -> Common.lookup_h_env s !_typedef)) with
62
62
  | Some TypeDefI -> true
71
71
let add_typedef  s = Common.add_in_scope_h _typedef (s, TypeDefI)
72
72
let add_ident s    = Common.add_in_scope_h _typedef (s, IdentI)
73
73
 
74
 
let add_typedef_root s = 
 
74
let add_typedef_root s =
75
75
  if !Flag_parsing_c.add_typedef_root
76
 
  then 
 
76
  then
77
77
    Hashtbl.add !_typedef.scoped_h s TypeDefI
78
78
  else add_typedef s (* have far more .failed without this *)
79
79
 
83
83
 *)
84
84
let _old_state = ref (Common.clone_scoped_h_env !_typedef)
85
85
 
86
 
let save_typedef_state () = 
 
86
let save_typedef_state () =
87
87
  _old_state := Common.clone_scoped_h_env !_typedef
88
88
 
89
 
let restore_typedef_state () = 
 
89
let restore_typedef_state () =
90
90
  _typedef := !_old_state
91
 
  
92
 
 
93
 
 
94
 
 
95
 
type context = 
 
91
 
 
92
 
 
93
 
 
94
 
 
95
type context =
96
96
  | InTopLevel
97
97
  | InFunction
98
98
  | InStruct
99
99
  | InParameter
100
100
  | InInitializer
101
101
  | InEnum
102
 
(* InExpr ? but then orthogonal to InFunction. Could assign InExpr for 
103
 
 * instance after a '=' as in 'a = (irq_t) b;' 
 
102
(* InExpr ? but then orthogonal to InFunction. Could assign InExpr for
 
103
 * instance after a '=' as in 'a = (irq_t) b;'
104
104
 *)
105
105
 
106
106
let is_top_or_struct = function
107
107
  | InTopLevel
108
 
  | InStruct 
 
108
  | InStruct
109
109
      -> true
110
110
  | _ -> false
111
111
 
112
 
type lexer_hint = { 
 
112
type lexer_hint = {
113
113
  mutable context_stack: context Common.stack;
114
114
 }
115
115
 
116
 
let default_hint () = { 
 
116
let default_hint () = {
117
117
  context_stack = [InTopLevel];
118
118
}
119
119
 
120
120
let _lexer_hint = ref (default_hint())
121
121
 
122
 
let current_context () = List.hd !_lexer_hint.context_stack 
123
 
let push_context ctx = 
 
122
let current_context () = List.hd !_lexer_hint.context_stack
 
123
let push_context ctx =
124
124
  !_lexer_hint.context_stack <- ctx::!_lexer_hint.context_stack
125
 
let pop_context () = 
 
125
let pop_context () =
126
126
  !_lexer_hint.context_stack <- List.tl !_lexer_hint.context_stack
127
127
 
128
128
 
129
129
 
130
 
let lexer_reset_typedef () = 
 
130
let lexer_reset_typedef () =
131
131
  begin
132
132
  _handle_typedef := true;
133
133
  _typedef := Common.empty_scoped_h_env ();