-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathquant_parser.mly
131 lines (107 loc) · 2.19 KB
/
quant_parser.mly
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
/* Grammar for formula input */
%{
open Quant_ast
open Herald
(* Ensure antecedent is a conjunction of atoms *)
let form pos vars antec concl =
match antec with
| Disj [Quant ([], conj)] -> Form (pos, Quant (vars, conj), concl)
| _ -> raise Parsing.Parse_error
(* Code for parsing size bounds, step limits, and input order in
the source *)
let herald xs =
match parse_herald xs with
| Some h -> h
| None -> raise Parsing.Parse_error
%}
%token <string> SYMBOL
%token <int> DIGITS
%token FORALL
%token EXISTS
%token IMPLIES
%token VBAR
%token EQUAL
%token TRUE
%token FALSE
%token LPAR
%token RPAR
%token LBRA
%token RBRA
%token AMP
%token COMMA
%token PERIOD
%token EOF
%start file
%type <Herald.herald * Quant_ast.ast_form list> file
%%
file:
herald forms EOF { $1, List.rev $2 }
;
herald: /* Handle optional runtime parameters */
{ empty_herald }
| LBRA params RBRA { herald $2 }
;
params:
param { [$1] }
| params COMMA param { $3 :: $1 }
;
param:
SYMBOL { $1, None }
| SYMBOL EQUAL DIGITS { $1, Some $3 }
;
forms:
{ [] }
| forms form { $2 :: $1 }
;
form: /* A formula in geometric form */
forall head IMPLIES head period { form $5 $1 $2 $4 }
| forall head period { form $3 $1 (Disj [Quant ([], Conj [])]) $2 }
;
period: /* Record position of formula */
PERIOD { symbol_start_pos () }
;
forall:
{ [] }
| FORALL vars COMMA { List.rev $2 }
;
vars:
symbol { [$1] }
| vars symbol { $2 :: $1 }
;
head: /* Consequent */
FALSE { Disj [] }
| disj { Disj (List.rev $1) }
;
disj:
quant { [$1] }
| disj VBAR quant { $3 :: $1 }
quant:
exists body { Quant ($1, $2) }
exists:
{ [] }
| EXISTS vars COMMA { List.rev $2 }
;
body: /* Body */
TRUE { Conj [] }
| conj { Conj (List.rev $1) }
;
conj:
atom { [$1] }
| conj AMP atom { $3 :: $1 }
;
atom:
term { let Term (s, a) = $1 in Atom (s, a) }
| term EQUAL term { Equal ($1, $3) }
;
term:
symbol { Term ($1, []) }
| symbol LPAR args RPAR
{ Term ($1, List.rev $3) }
;
symbol:
SYMBOL { Sym (symbol_start_pos (), $1) }
;
args:
term { [ $1 ] }
| args COMMA term { $3 :: $1 }
;