File: JavaGenParser_lib.ml

package info (click to toggle)
herdtools7 7.58-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 19,732 kB
  • sloc: ml: 128,583; ansic: 3,827; makefile: 670; python: 407; sh: 212; awk: 14
file content (240 lines) | stat: -rw-r--r-- 7,530 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
(****************************************************************************)
(*                           the diy toolsuite                              *)
(*                                                                          *)
(* Jade Alglave, University College London, UK.                             *)
(* Luc Maranget, INRIA Paris-Rocquencourt, France.                          *)
(*                                                                          *)
(* Copyright 2015-present Institut National de Recherche en Informatique et *)
(* en Automatique and the authors. All rights reserved.                     *)
(*                                                                          *)
(* This software is governed by the CeCILL-B license under French law and   *)
(* abiding by the rules of distribution of free software. You can use,      *)
(* modify and/ or redistribute the software under the terms of the CeCILL-B *)
(* license as circulated by CEA, CNRS and INRIA at the following URL        *)
(* "http://www.cecill.info". We also give a copy in LICENSE.txt.            *)
(****************************************************************************)

(* Configuration, to change kinds and condition *)
module type Config = sig
  val debuglexer : bool
  val check_kind : string -> ConstrGen.kind option
  val check_cond : string -> string option
  val macros : string option
  val libfind : string -> string
end

module DefaultConfig = struct
  let debuglexer    = false
  let check_kind _  = None
  let check_cond _  = None
  let macros        = None
  let libfind       = Misc.identity
end

(* input signature, a lexer and a parser for a given architecture *)
module type LexParse = sig
  type token
  type pseudo
  val lexer : Lexing.lexbuf -> token
  val parser : (Lexing.lexbuf -> token) -> Lexing.lexbuf -> JavaAst.thread_body list
end

(* Output signature *)
module type S = sig
  type pseudo = JavaBase.pseudo
  type init = MiscParser.state
  type prog = (MiscParser.proc * pseudo list) list
  type locations = MiscParser.LocSet.t

  val parse : in_channel -> (* input channel *)
              Splitter.result ->  (* result from splitter *)
              pseudo MiscParser.t (* Result of generic parsing *)

  val parse_string : string -> 
              Splitter.result -> 
              pseudo MiscParser.t
end

module DumpJava = struct

  type code = MiscParser.proc * JavaBase.pseudo list
  let dump_prog _ ((proc, _, _) , body) =
    let body_str =
      let unwrapped = (List.map (fun ps -> match ps with
                                          | JavaBase.Instruction i -> i
                                          | _ -> assert false ) body) in
      String.concat "\n" (List.map (JavaBase.dump_instruction) unwrapped) in

    [ (Printf.sprintf "Thread%d {\n%s\n}" proc body_str) ]

  let dump_prog_lines prog =
      let pp = List.map (dump_prog true) prog in
      let pp = List.concat pp in
      List.map (Printf.sprintf "%s\n") pp

  let print_prog chan prog =
    let pp = dump_prog_lines prog in
    List.iter (Printf.fprintf chan "%s") pp
end


module Make
    (O:Config)
    (A:ArchBase.S)
    (L: LexParse with type pseudo = A.pseudo) : S = 
struct

    type pseudo     = JavaBase.pseudo
    type init       = MiscParser.state
    type prog       = (MiscParser.proc * pseudo list) list
    type locations  = MiscParser.LocSet.t

    (****************)
    (* Basic Checks *)
    (****************)
    module U = GenParserUtils

    let call_parser = U.call_parser

    (* Check whether the thread numbers starts from 0 and are consecutive *)
    let check_procs procs =
      Misc.iteri
        (fun k p ->
          if k <> p then
            Warn.fatal "Processes must be Thread0, Thread1, ...")
        procs

    let check_regs = U.check_regs



(***********)
(* Parsing *)
(***********)

(* Lexers *)
    module LexConfig = struct let debug = O.debuglexer end
    module LU = LexUtils.Make (LexConfig)
    module SL = StateLexer.Make (LexConfig)

    let parse_cond lexbuf =
      let cond =  call_parser "cond" lexbuf SL.token StateParser.main_constr in
        cond

(* Compute hash as litmus does *)
(* we are just using the CTestHash for now *)
    module D = CTestHash.Make(DumpJava)

    module Do
         (I:sig
      	    type src
      	    val call_parser_loc :
                string ->             (* name of the section *)
                src ->                (* input channel *)
                Pos.pos2 ->           (* position of the section, see splitter's result *)
                'a ->                 (* a lexer *)
                ('a -> Lexing.lexbuf -> 'b) -> (* a parser *)
                'b                    (* AST list *)
          end) = 
    struct

    let parse chan (* input channel *)
              {
                Splitter.locs = (init_loc, prog_loc, constr_loc, _) ; (* The four sections of a litmus file *)
                name = name ;  (* All names of the test grouped *)
                info = info ; _(* Additional information as (key * value) pairs *)
        }  =

    (* Initial state specification. *)
    let init =
      I.call_parser_loc "init"
		      chan init_loc SL.token StateParser.init in

    (* Program *)
    let prog =
      I.call_parser_loc "prog" chan prog_loc L.lexer L.parser in

    (* check the list of thread numbers 0, ..., n *)
    let procs = List.map (fun p -> p.JavaAst.proc) prog in
      check_procs procs ;

    (* Condition to be checked after the run. *)
    let (locs, filter, final, _quantifiers) =
      I.call_parser_loc "final"
		      chan constr_loc SL.token StateParser.constraints in

    (* Check *)
      check_regs procs init locs final ;

    let all_locs = U.get_visible_locs locs final in

    (* transform from JavaAST.threadBody to a pair with the same content *)
    let prog =  List.map (fun p -> ((p.JavaAst.proc, None, MiscParser.Main), p.JavaAst.body)) prog in


    (* The output of the parser *)
    let parsed = {
        MiscParser.info;
        init = init;
        prog = prog;
        filter = filter;
        condition = final;
        locations = locs;
        extra_data = []
      } in

    let name  = name.Name.name in

    let parsed =
      match O.check_cond name  with
      | None -> parsed
      | Some k ->
         let cond = parse_cond (Lexing.from_string k) in
         { parsed with
           MiscParser.condition = cond ;} in

    let parsed =
      match O.check_kind name  with
      | None -> parsed
      | Some k ->
         { parsed with
           MiscParser.condition =
             ConstrGen.set_kind k parsed.MiscParser.condition; } in

    let parsed = 
      match MiscParser.get_hash parsed with
        | None ->
            let info = parsed.MiscParser.info in
            { parsed with MiscParser.info =
	       ("Hash", D.digest info init prog all_locs)::info ; }
        | Some _ -> parsed in

    parsed

end


(*************************************************************************)


  let parse chan x =
    let module Src = struct
      type src = in_channel
      let call_parser_loc name chan loc =
        let lexbuf = LU.from_section loc chan in
        call_parser name lexbuf
    end in
    let module P = Do(Src) in
    P.parse chan x

  let parse_string s x =
    let module Src = struct
      type src = string
      let call_parser_loc name s loc =
        let lexbuf = LU.from_section_string loc s in
        call_parser name lexbuf
    end in
    let module P = Do(Src) in
    P.parse s x

end