summaryrefslogtreecommitdiff
path: root/lib/parsing/headers.ml
blob: 8d633816ba4df58f73b3238a06d55c486af301cb (plain)
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
(* Useful types for parsing *)

open Types

exception Parse_Error of string

type terminal = tok

type nonterminal = S | E | E' | F | F' | G | G' | H | H' | I

type symbol = Nt of nonterminal | Tm of terminal

type production = nonterminal * (symbol list)

(* possible actions to take when LL parsing *)
type action =
  | PREDICT of production
  | MATCH of tok
  | ACCEPT
  | REJECT

(* takes in top stack symbol and the next input token and selects action to take *)
type table = symbol -> tok -> action

(* mutable abstract syntax tree *)
type ast =
  | Br of symbol * (ast ref) list
  | Lf of symbol

(* parsing state *)
type state = {
  stack : symbol list;
  ast_stack : ast ref list; (* list of ast refs corresponding to symbols on the stack *)
  input : tok list;
  finished : bool;
  accepted : bool
}

(* convert ast to proposition *)
let rec prop_of_ast (tree : ast) : proposition =
  match tree with
  | Lf (Tm TRUE) -> True
  | Lf (Tm FALSE) -> False
  | Lf (Tm (LIT s)) -> Lit s
  | Br (Nt S, e_ref :: _) -> prop_of_ast !e_ref
  | Br (Nt I, _ :: e_ref :: _ :: _) -> prop_of_ast !e_ref (* I ::= LEFT_PAREN E RIGHT_PAREN *)
  | Br (Nt I, _ :: i_ref :: _) -> let inner_prop = prop_of_ast !i_ref in Not(inner_prop) (* I ::=  NOT I *)
  | Br (Nt I, [some_ref]) -> (* I ::= TRUE | FALSE | LIT s *)
    begin
      match !some_ref with
      | Lf (Tm TRUE) -> True
      | Lf (Tm FALSE) -> False
      | Lf (Tm (LIT s)) -> Lit s
      | _ -> failwith "some bug"
    end
  | Br (Nt a, b_ref :: a'_ref :: _) -> (* A ::= B A' *)
    begin
      match !a'_ref with
      | Lf _ -> prop_of_ast !b_ref (* A' ::= eps *)
      | Br (_, _ :: tl) -> (* A' ::=  CONNECTOR B A' *)
        let left = prop_of_ast !b_ref in
        let right = prop_of_ast (Br(Nt a, tl)) in
        begin
          match a with
          | E -> Iff(left, right)
          | F -> Implies(left, right)
          | G -> Or(left, right)
          | H -> And(left, right)
          | _ -> failwith "a bug!"
        end
      | _ -> failwith "another bug"
    end
  | _ -> failwith "found a bug!"