aboutsummaryrefslogtreecommitdiffhomepage
path: root/parsing/g_vernac.ml4
blob: c28cfde1222d26cea828c3473633db35e5f9b00a (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
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
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525

(* $Id$ *)

open Pcoq

open Tactic

GEXTEND Gram
  simple_tactic:
    [ [ IDENT "ML"; s = Prim.string -> <:ast< (MLTACTIC $s) >> ] ]
  ;
END

open Vernac

GEXTEND Gram
  vernac: LAST
    [ [ tac = tacarg; "." -> <:ast< (SOLVE 1 (TACTIC $tac)) >> ] ]
  ;
END

GEXTEND Gram
  tacarg:
    [ [ tcl = Tactic.tactic_com_list -> tcl ] ]
  ;
  theorem_body_line:
    [ [ n = numarg; ":"; tac = tacarg; "." ->
          <:ast< (VERNACCALL {SOLVE} $n (TACTIC $tac)) >>
      | tac = tacarg; "." -> <:ast< (VERNACCALL {SOLVE} 1 (TACTIC $tac)) >>
      ] ]
  ;
  theorem_body_line_list:
    [ [ t = theorem_body_line -> [t]
      | t = theorem_body_line; l = theorem_body_line_list -> t :: l ] ]
  ;
  theorem_body:
    [ [ l = theorem_body_line_list ->
          <:ast< (VERNACARGLIST ($LIST $l)) >> ] ]
  ;
  destruct_location :
  [ [ IDENT "Conclusion"  -> <:ast< (CONCL)>>
    | IDENT "Discardable"; "Hypothesis"  -> <:ast< (DiscardableHYP)>>
    | "Hypothesis"   -> <:ast< (PreciousHYP)>> ]]
  ;
  ne_comarg_list:
  [ [ l = LIST1 comarg -> l ] ]
  ;

  opt_identarg_list:
  [ [ -> []
    | ":"; l = LIST1 identarg -> l ] ]
  ;

  finite_tok:
    [ [ "Inductive" -> <:ast< "Inductive" >>
      | "CoInductive" -> <:ast< "CoInductive" >> ] ]
  ;
  block_old_style:
    [ [ ind = oneind_old_style; "with"; indl = block_old_style -> ind :: indl
      | ind = oneind_old_style -> [ind] ] ]
  ;
  oneind_old_style:
    [ [ id = identarg; ":"; c = comarg; ":="; lidcom = lidcom ->
          <:ast< (VERNACARGLIST $id $c $lidcom) >> ] ]
  ;
  block:
    [ [ ind = oneind; "with"; indl = block -> ind :: indl
      | ind = oneind -> [ind] ] ]
  ;
  oneind:
    [ [ id = identarg; indpar = indpar; ":"; c = comarg; ":="; lidcom = lidcom
      -> <:ast< (VERNACARGLIST $id $c $indpar $lidcom) >> ] ]
  ;
  onerec:
    [ [ id = identarg; "["; idl = ne_binder_list; "]"; ":"; c = comarg;
        ":="; def = comarg ->
          <:ast< (VERNACARGLIST $id (BINDERLIST ($LIST $idl)) $c $def) >> ] ]
  ;
  specifrec:
    [ [ rec_ = onerec; "with"; recl = specifrec -> rec_ :: recl
      | rec_ = onerec -> [rec_] ] ]
  ;
  onecorec:
    [ [ id = identarg; ":"; c = comarg; ":="; def = comarg ->
          <:ast< (VERNACARGLIST $id $c $def) >> ] ]
  ;
  specifcorec:
    [ [ corec = onecorec; "with"; corecl = specifcorec -> corec :: corecl
      | corec = onecorec -> [corec] ] ]
  ;
  rec_constr:
    [ [ c = Vernac.identarg -> <:ast< (VERNACARGLIST $c) >>
      |  -> <:ast< (VERNACARGLIST) >> ] ]
  ;
  record_tok:
    [ [ IDENT "Record" -> <:ast< "Record" >>
      | IDENT "Structure" -> <:ast< "Structure" >> ] ]
  ;
  field:
    [ [ id = identarg; ":"; c = Command.command ->
          <:ast< (VERNACARGLIST "" $id (COMMAND $c)) >>
      | id = identarg; ":>"; c = Command.command ->
          <:ast< (VERNACARGLIST "COERCION" $id (COMMAND $c)) >> ] ]
  ;
  nefields:
    [ [ idc = field; ";"; fs = nefields -> idc :: fs
      | idc = field -> [idc] ] ]
  ;
  fields:
    [ [ fs = nefields -> <:ast< (VERNACARGLIST ($LIST $fs)) >>
      |  -> <:ast< (VERNACARGLIST) >> ] ]
  ;
  onescheme:
    [ [ id = identarg; ":="; dep = dep; c = comarg; IDENT "Sort";
        s = sortdef ->
          <:ast< (VERNACARGLIST $id $dep $c (COMMAND $s)) >> ] ]
  ;
  specifscheme:
    [ [ rec_ = onescheme; "with"; recl = specifscheme -> rec_ :: recl
      | rec_ = onescheme -> [rec_] ] ]
  ;
  dep:
    [ [ IDENT "Induction"; IDENT "for" -> <:ast< "DEP" >>
      | IDENT "Minimality"; IDENT "for" -> <:ast< "NODEP" >> ] ]
  ;
  ne_binder_list:
    [ [ id = binder; ";"; idl = ne_binder_list -> id :: idl
      | id = binder -> [id] ] ]
  ;
  indpar:
    [ [ "["; bl = ne_binder_list; "]" ->
          <:ast< (BINDERLIST ($LIST $bl)) >>
      |  -> <:ast< (BINDERLIST) >> ] ]
  ;
  sortdef:
    [ [ "Set" -> <:ast< (PROP {Pos}) >>
      | "Prop" -> <:ast< (PROP {Null}) >>
      | "Type" -> <:ast< (TYPE) >> ] ]
  ;
  thm_tok:
    [ [ "Theorem" -> <:ast< "THEOREM" >>
      | IDENT "Lemma" -> <:ast< "LEMMA" >>
      | IDENT "Fact" -> <:ast< "FACT" >>
      | IDENT "Remark" -> <:ast< "REMARK" >> ] ]
  ;

  def_tok:
    [ [ "Definition" -> <:ast< "DEFINITION" >>
      | IDENT "Local" -> <:ast< "LOCAL" >> 
      | "@"; "Definition"  -> <:ast< "OBJECT" >>
      | "@"; IDENT "Local"  -> <:ast< "LOBJECT" >>
      | "@"; IDENT "Coercion"  -> <:ast< "OBJCOERCION" >>
      | "@"; IDENT "Local"; IDENT "Coercion"  -> <:ast< "LOBJCOERCION" >>
      | IDENT "SubClass"  -> <:ast< "SUBCLASS" >>
      | IDENT "Local"; IDENT "SubClass"  -> <:ast< "LSUBCLASS" >> ] ]  
  ;
  import_tok:
    [ [ IDENT "Import" -> <:ast< "IMPORT" >>
      | IDENT "Export" -> <:ast< "EXPORT" >>
      |  -> <:ast< "IMPORT" >> ] ]
  ;
  specif_tok:
    [ [ IDENT "Implementation" -> <:ast< "IMPLEMENTATION" >>
      | IDENT "Specification" -> <:ast< "SPECIFICATION" >>
      |  -> <:ast< "UNSPECIFIED" >> ] ]
  ;
  hyp_tok:
    [ [ "Hypothesis" -> <:ast< "HYPOTHESIS" >>
      | "Variable" -> <:ast< "VARIABLE" >> ] ]
  ;
  hyps_tok:
    [ [ IDENT "Hypotheses" -> <:ast< "HYPOTHESES" >>
      | IDENT "Variables" -> <:ast< "VARIABLES" >> ] ]
  ;
  param_tok:
    [ [ "Axiom" -> <:ast< "AXIOM" >>
      | "Parameter" -> <:ast< "PARAMETER" >> ] ]
  ;
  params_tok:
    [ [ IDENT "Parameters" -> <:ast< "PARAMETERS" >> ] ]
  ;
  binder:
    [ [ idl = ne_identarg_comma_list; ":"; c = Command.command ->
          <:ast< (BINDER $c ($LIST $idl)) >> ] ]
  ;
  idcom:
    [ [ id = IDENT; ":"; c = Command.command ->
          <:ast< (BINDER $c ($VAR $id)) >> ] ]
  ;
  ne_lidcom:
    [ [ idc = idcom; "|"; l = ne_lidcom -> idc :: l
      | idc = idcom -> [idc] ] ]
  ;
  lidcom:
    [ [ l = ne_lidcom -> <:ast< (BINDERLIST ($LIST $l)) >>
      | "|"; l = ne_lidcom -> <:ast< (BINDERLIST ($LIST $l)) >>
      |  -> <:ast< (BINDERLIST) >> ] ]
  ;
  END

GEXTEND Gram
  vernac:
      (* Definition, Goal *)
    [ [ thm = thm_tok; id = identarg; ":"; c = comarg; "." ->
          <:ast< (StartProof $thm $id $c) >>
      | thm = thm_tok; id = identarg; ":"; c = comarg; ":="; "Proof";
        tb = theorem_body; "Qed"; "." ->
          <:ast< (TheoremProof $thm $id $c $tb) >>

      | def = def_tok; s = identarg; ":"; c1 = Command.command; "." ->
          <:ast< (StartProof $def $s (COMMAND $c1)) >>
      | def = def_tok; s = identarg; ":="; c1 = Command.command; "." ->
          <:ast< (DEFINITION $def $s (COMMAND $c1)) >>
      | def = def_tok; s = identarg; ":="; c1 = Command.command; ":";
        c2 = Command.command; "." ->
          <:ast< (DEFINITION $def $s (COMMAND (CAST $c1 $c2))) >>
      | def = def_tok; s = identarg; ":"; c1 = Command.command; ":=";
        c2 = Command.command; "." ->
          <:ast< (DEFINITION $def $s (COMMAND (CAST $c2 $c1))) >>

(* CP / Juillet 99 
   Ajout de la possibilite d'appliquer une regle de reduction au 
   corps d'une definition 
   Definition t := Eval red in term
*)

      | def = def_tok; s = identarg; ":="; 
      IDENT "Eval"; r = Tactic.red_tactic; "in"; c1 = Command.command; "." ->
          <:ast< (DEFINITION $def $s (COMMAND $c1) (TACTIC_ARG (REDEXP $r))) >>
      | def = def_tok; s = identarg; ":="; 
      IDENT "Eval"; r = Tactic.red_tactic; "in"; c1 = Command.command; ":";
        c2 = Command.command; "." ->
          <:ast< (DEFINITION $def $s 
                 (COMMAND (CAST $c1 $c2)) (TACTIC_ARG (REDEXP $r))) >>
      | def = def_tok; s = identarg; ":"; c1 = Command.command; ":=";
        IDENT "Eval"; r = Tactic.red_tactic; "in"; 
	c2 = Command.command; "." ->
          <:ast< (DEFINITION $def $s (COMMAND (CAST $c2 $c1)) 
		    (TACTIC_ARG (REDEXP $r))) >>

(* Papageno / Février 99
   Ajout du racourci "Definition x [c:nat] := t" pour 
                     "Definition x := [c:nat]t" *)

      | def = def_tok; s = identarg; "["; id1 = IDENT; ":"; 
	c = Command.command; t = definition_tail;  "." -> 
	  <:ast< (DEFINITION $def $s (COMMAND (LAMBDA $c [$id1]$t))) >>

      | def = def_tok; s = identarg; "["; id1 = IDENT; ",";
	idl = Command.ne_ident_comma_list; ":"; c = Command.command; 
	t = definition_tail; "." -> 
	  <:ast< (DEFINITION $def $s (COMMAND 
			(LAMBDALIST $c [$id1]($SLAM $idl $t)))) >>


      | hyp = hyp_tok; bl = ne_binder_list; "." ->
          <:ast< (VARIABLE $hyp  (BINDERLIST ($LIST $bl))) >>
      | hyp = hyps_tok; bl = ne_binder_list; "." ->
          <:ast< (VARIABLE $hyp  (BINDERLIST ($LIST $bl))) >>
      | hyp = param_tok; bl = ne_binder_list; "." ->
          <:ast< (PARAMETER $hyp (BINDERLIST ($LIST $bl))) >>
      | hyp = params_tok; bl = ne_binder_list; "." ->
          <:ast< (PARAMETER $hyp (BINDERLIST ($LIST $bl))) >>
      | IDENT "Abstraction"; id = identarg; "["; l = ne_numarg_list; "]";
        ":="; c = comarg; "." ->
          <:ast< (ABSTRACTION $id $c ($LIST $l)) >>
      | f = finite_tok; "Set"; id = identarg; indpar = indpar; ":=";
        lidcom = lidcom; "." ->
          <:ast< (ONEINDUCTIVE $f $id (COMMAND (PROP {Pos})) $indpar
                   $lidcom) >>
      | f = finite_tok; "Type"; id = identarg; indpar = indpar; ":=";
        lidcom = lidcom; "." ->
          <:ast< (ONEINDUCTIVE $f $id (COMMAND (TYPE)) $indpar $lidcom) >>
      | f = finite_tok; "Prop"; id = identarg; indpar = indpar; ":=";
        lidcom = lidcom; "." ->
          <:ast< (ONEINDUCTIVE $f $id (COMMAND (PROP {Null})) $indpar
                   $lidcom) >>
      | f = finite_tok; indl = block; "." ->
          <:ast< (MUTUALINDUCTIVE $f (VERNACARGLIST ($LIST $indl))) >>

      | record_tok; name = identarg; ps = indpar; ":"; s = sortdef; ":=";
        c = rec_constr; "{"; fs = fields; "}"; "." ->
          <:ast< (RECORD "" $name $ps (COMMAND $s) $c $fs) >>
      | record_tok; ">"; name = identarg; ps = indpar; ":"; s = sortdef; ":=";
        c = rec_constr; "{"; fs = fields; "}"; "." ->
          <:ast< (RECORD "COERCION" $name $ps (COMMAND $s) $c $fs) >>

      | IDENT "Mutual"; "["; bl = ne_binder_list; "]" ; f = finite_tok;
        indl = block_old_style; "." ->
          <:ast< (OLDMUTUALINDUCTIVE (BINDERLIST ($LIST $bl)) $f
                                     (VERNACARGLIST ($LIST $indl))) >>
      | IDENT "Mutual"; f = finite_tok; indl = block; "." ->
          <:ast< (MUTUALINDUCTIVE $f (VERNACARGLIST ($LIST $indl))) >>
      | "Fixpoint"; recs = specifrec; "." ->
          <:ast< (MUTUALRECURSIVE (VERNACARGLIST ($LIST $recs))) >>
      | "CoFixpoint"; corecs = specifcorec; "." ->
          <:ast< (MUTUALCORECURSIVE (VERNACARGLIST ($LIST $corecs))) >>
      | IDENT "Scheme"; schemes = specifscheme; "." ->
          <:ast< (INDUCTIONSCHEME (VERNACARGLIST ($LIST $schemes))) >>
      ] ];

      
      definition_tail:
    	[ [ ";"; idl = Command.ne_ident_comma_list;
            ":"; c = Command.command; c2 = definition_tail ->
              <:ast< (LAMBDALIST $c ($SLAM $idl $c2)) >>
	| "]"; ":"; ty = Command.command; ":=" ; c = Command.command -> 
	    <:ast< (CAST $c $ty) >>
 	| "]"; ":="; c = Command.command -> c 
	] ];

  END

GEXTEND Gram
  vernac:
    [ [ 

(* State management *)
        IDENT "Write"; IDENT "State"; id = identarg; "." ->
          <:ast< (WriteState $id) >>
      | IDENT "Write"; IDENT "State"; s = stringarg; "." ->
          <:ast< (WriteState $s) >>
      | IDENT "Restore";  IDENT "State"; id = identarg; "." ->
          <:ast< (RestoreState $id) >>
      | IDENT "Restore";  IDENT "State"; s = stringarg; "." ->
          <:ast< (RestoreState $s) >>
      | IDENT "Reset"; id = identarg; "." -> <:ast< (ResetName $id) >>
      | IDENT "Reset"; IDENT "Initial"; "." -> <:ast< (ResetInitial) >>
      | IDENT "Reset"; IDENT "Section"; id = identarg; "." ->
          <:ast< (ResetSection $id) >>

(* Modules and Sections *)   

      | IDENT "Read"; IDENT "Module"; id = identarg; "." ->
          <:ast< (ReadModule $id) >>
      | IDENT "Require"; import = import_tok; specif = specif_tok;
        id = identarg; "." -> <:ast< (Require $import $specif $id) >>
      | IDENT "Require"; import = import_tok; specif = specif_tok;
        id = identarg; filename = stringarg; "." ->
          <:ast< (RequireFrom $import $specif $id $filename) >>
      | IDENT "Section"; id = identarg; "." -> <:ast< (BeginSection $id) >>
      | IDENT "Chapter"; id = identarg; "." -> <:ast< (BeginSection $id) >>
      | IDENT "Module"; id = identarg; "." -> <:ast< (BeginModule $id) >>
      | IDENT "Write"; IDENT "Module"; id = identarg; "." -> 
	  <:ast< (WriteModule $id) >>
      | IDENT "Write"; IDENT "Module"; id = identarg; s = stringarg; "." -> 
	  <:ast< (WriteModule $id $s) >>
      | IDENT "Begin"; IDENT "Silent"; "." -> <:ast< (BeginSilent) >>
      | IDENT "End"; IDENT "Silent"; "." -> <:ast< (EndSilent) >>
      | IDENT "End"; id = identarg; "." -> <:ast< (EndSection $id) >>
      | IDENT "Declare"; IDENT "ML"; IDENT "Module";
        l = ne_stringarg_list; "." -> <:ast< (DeclareMLModule ($LIST $l)) >>
      | IDENT "Import"; id = identarg; "." -> <:ast< (ImportModule $id) >>
	  (* Transparent and Opaque *)
      | IDENT "Transparent"; l = ne_identarg_list; "." ->
          <:ast< (TRANSPARENT ($LIST $l)) >>
      | IDENT "Opaque"; l = ne_identarg_list; "." -> 
	  <:ast< (OPAQUE ($LIST $l)) >>
      
	  (* Extraction *)
      | IDENT "Extraction"; id = identarg; "." ->
          <:ast< (PrintExtractId $id) >>
      | IDENT "Extraction"; "." -> <:ast< (PrintExtract) >>

(* Grammar extensions, Coercions, Implicits *)
	  
     | IDENT "Coercion"; s = identarg; ":="; c1 = Command.command; "." ->
         <:ast< (DEFINITION "COERCION" $s (COMMAND $c1)) >>
     | IDENT "Coercion"; s = identarg; ":="; c1 = Command.command; ":";
        c2 = Command.command; "." ->
          <:ast< (DEFINITION "COERCION" $s (COMMAND (CAST $c1 $c2))) >>
     | IDENT "Coercion"; IDENT "Local"; s = identarg; ":="; 
	c1 = Command.command; "." ->
          <:ast< (DEFINITION "LCOERCION" $s (COMMAND $c1)) >>
     | IDENT "Coercion"; IDENT "Local"; s = identarg; ":="; 
	c1 = Command.command; ":"; c2 = Command.command; "." ->
          <:ast< (DEFINITION "LCOERCION" $s (COMMAND (CAST $c1 $c2))) >>
	  
	  
     | IDENT "Syntactic"; "Definition"; id = identarg; ":="; com = comarg;
        "." -> <:ast< (SyntaxMacro $id $com) >>
     | IDENT "Syntactic"; "Definition"; id = identarg; ":="; com = comarg;
        "|"; n = numarg; "." -> <:ast< (SyntaxMacro $id $com $n) >>
     | IDENT "Print"; "Grammar"; uni = identarg; ent = identarg; "." ->
         <:ast< (PrintGrammar $uni $ent) >>
     | IDENT "Identity"; IDENT "Coercion"; IDENT "Local"; f = identarg;
        ":"; c = identarg; ">->"; d = identarg; "." ->
          <:ast< (COERCION "LOCAL" "IDENTITY" $f $c $d) >>
     | IDENT "Identity"; IDENT "Coercion"; f = identarg; ":";
        c = identarg; ">->"; d = identarg; "." ->
          <:ast< (COERCION "" "IDENTITY" $f $c $d) >>
     | IDENT "Coercion"; IDENT "Local"; f = identarg; ":"; c = identarg;
        ">->"; d = identarg; "." ->
          <:ast< (COERCION "LOCAL" "" $f $c $d) >>
     | IDENT "Coercion"; f = identarg; ":"; c = identarg; ">->";
        d = identarg; "." -> <:ast< (COERCION "" "" $f $c $d) >>
     | IDENT "Class"; IDENT "Local"; c = identarg; "." ->
         <:ast< (CLASS "LOCAL" $c) >>
     | IDENT "Class"; c = identarg; "." -> <:ast< (CLASS "" $c) >>
     | IDENT "Implicit"; IDENT "Arguments"; IDENT "On"; "." ->
         <:ast< (IMPLICIT_ARGS_ON) >>
     | IDENT "Implicit"; IDENT "Arguments"; IDENT "Off"; "." ->
         <:ast< (IMPLICIT_ARGS_OFF) >>
     | IDENT "Implicits"; id = identarg; "["; l = numarg_list; "]"; "." ->
         <:ast< (IMPLICITS "" $id ($LIST $l)) >>
     | IDENT "Implicits"; id = identarg; "." ->
         <:ast< (IMPLICITS "Auto" $id) >> 
 ] ];
    END

(* Proof commands *)
GEXTEND Gram
  vernac:
    [ [ IDENT "Goal"; c = comarg; "." -> <:ast< (GOAL $c) >>
      | IDENT "Goal"; "." -> <:ast< (GOAL) >>
      | "Proof"; "." -> <:ast< (GOAL) >>
      | IDENT "Abort"; "." -> <:ast< (ABORT) >>
      | "Qed"; "." -> <:ast< (SaveNamed) >>
      | IDENT "Save"; "." -> <:ast< (SaveNamed) >>
      | IDENT "Defined"; "." -> <:ast< (DefinedNamed) >>
      | IDENT "Save"; IDENT "Remark"; id = identarg; "." ->
          <:ast< (SaveAnonymousRmk $id) >>
      | IDENT "Save"; IDENT "Theorem"; id = identarg; "." ->
          <:ast< (SaveAnonymousThm $id) >>
      | IDENT "Save"; id = identarg; "." -> <:ast< (SaveAnonymousThm $id) >>
      | IDENT "Suspend"; "." -> <:ast< (SUSPEND) >>
      | IDENT "Resume"; "." -> <:ast< (RESUME) >>
      | IDENT "Resume"; id = identarg; "." -> <:ast< (RESUME $id) >>
      | IDENT "Abort"; IDENT "All"; "." -> <:ast< (ABORTALL) >>
      | IDENT "Abort"; id = identarg; "." -> <:ast< (ABORT $id) >>
      | IDENT "Restart"; "." -> <:ast< (RESTART) >>
      | "Proof"; c = comarg; "." -> <:ast< (PROOF $c) >>
      | IDENT "Undo"; "." -> <:ast< (UNDO 1) >>
      | IDENT "Undo"; n = numarg; "." -> <:ast< (UNDO $n) >>
      | IDENT "Show"; n = numarg; "." -> <:ast< (SHOW $n) >>
      | IDENT "Show"; IDENT "Implicits"; n = numarg; "." ->
          <:ast< (SHOWIMPL $n) >>
      | IDENT "Focus"; "." -> <:ast< (FOCUS) >>
      | IDENT "Focus"; n = numarg; "." -> <:ast< (FOCUS $n) >>
      | IDENT "Unfocus"; "." -> <:ast< (UNFOCUS) >>
      | IDENT "Show"; "." -> <:ast< (SHOW) >>
      | IDENT "Show"; IDENT "Implicits"; "." -> <:ast< (SHOWIMPL) >>
      | IDENT "Show"; IDENT "Node"; "." -> <:ast< (ShowNode) >>
      | IDENT "Show"; IDENT "Script"; "." -> <:ast< (ShowScript) >>
      | IDENT "Show"; IDENT "Existentials"; "." -> <:ast< (ShowEx) >>
      | IDENT "Existential"; n = numarg; ":="; c = Command.command; "." ->
          <:ast< (EXISTENTIAL $n (COMMAND $c)) >>
      | IDENT "Existential"; n = numarg; ":="; c1 = Command.command; ":";
        c2 = Command.command; "." ->
          <:ast< (EXISTENTIAL $n (COMMAND (CAST $c1 $c2))) >>
      | IDENT "Existential"; n = numarg; ":"; c2 = Command.command; ":=";
        c1 = Command.command; "." ->
          <:ast< (EXISTENTIAL $n (COMMAND (CAST $c1 $c2))) >>
      | IDENT "Explain"; "Proof"; l = numarg_list; "." ->
          <:ast< (ExplainProof ($LIST $l)) >>
      | IDENT "Explain"; "Proof"; IDENT "Tree"; l = numarg_list; "." ->
          <:ast< (ExplainProofTree ($LIST $l)) >>
      | IDENT "Go"; n = numarg; "." -> <:ast< (Go $n) >>
      | IDENT "Go"; IDENT "top"; "." -> <:ast< (Go "top") >>
      | IDENT "Go"; IDENT "prev"; "." -> <:ast< (Go "prev") >>
      | IDENT "Go"; IDENT "next"; "." -> <:ast< (Go "next") >>
      | IDENT "Show"; "Proof"; "." -> <:ast< (ShowProof) >>
      | IDENT "Guarded"; "." -> <:ast< (CheckGuard) >>
      | IDENT "Show"; IDENT "Tree"; "." -> <:ast< (ShowTree) >>
      | IDENT "Show"; IDENT "Conjectures"; "." -> <:ast< (ShowProofs) >>

(* Tactic Definition *)

      | IDENT "Tactic"; "Definition"; id = identarg; "[";
        ids = ne_identarg_list; "]"; ":="; tac = Prim.astact; "." ->
          <:ast< (TacticDefinition $id (AST $tac) ($LIST $ids)) >>
      | IDENT "Tactic"; "Definition"; id = identarg; ":="; tac = Prim.astact;
        "." -> <:ast< (TacticDefinition $id (AST $tac)) >>

(* Hints for Auto and EAuto *)

      | IDENT "Hint"; hintname = identarg; dbname = opt_identarg_list; ":=";
	IDENT "Resolve"; c = comarg; "." ->
	  <:ast<(HintResolve $hintname (VERNACARGLIST ($LIST $dbname)) $c)>>
	  
      | IDENT "Hint"; hintname = identarg; dbnames = opt_identarg_list; ":=";
	IDENT "Immediate"; c = comarg; "." ->
	  <:ast<(HintImmediate $hintname (VERNACARGLIST ($LIST $dbnames)) $c)>>
	  
      | IDENT "Hint"; hintname = identarg; dbnames = opt_identarg_list; ":=";
	IDENT "Unfold"; c = identarg; "." ->
	  <:ast<(HintUnfold $hintname (VERNACARGLIST ($LIST $dbnames)) $c)>>
	  
      | IDENT "Hint"; hintname = identarg; dbnames = opt_identarg_list; ":=";
	IDENT "Constructors"; c = identarg;  "." ->
	  <:ast<(HintConstructors $hintname (VERNACARGLIST ($LIST $dbnames)) $c)>>
	  
      | IDENT "Hint"; hintname = identarg; dbnames = opt_identarg_list; ":=";
	IDENT "Extern"; n = numarg; c = comarg ; tac = tacarg; "." ->
	  <:ast<(HintExtern $hintname (VERNACARGLIST ($LIST $dbnames)) 
		   $n $c (TACTIC $tac))>>
	  
      | IDENT "Hints"; IDENT "Resolve"; l = ne_identarg_list; 
	dbnames = opt_identarg_list; "." ->
          <:ast< (HintsResolve (VERNACARGLIST ($LIST $dbnames)) ($LIST $l)) >>
	  
      | IDENT "Hints"; IDENT "Immediate"; l = ne_identarg_list; 
	dbnames = opt_identarg_list; "." ->
          <:ast< (HintsImmediate (VERNACARGLIST ($LIST $dbnames)) ($LIST $l)) >>
	  
      | IDENT "Hints"; IDENT "Unfold"; l = ne_identarg_list;
	dbnames = opt_identarg_list; "." ->
          <:ast< (HintsUnfold (VERNACARGLIST ($LIST $dbnames)) ($LIST $l)) >>
	  
      | IDENT "HintDestruct"; 
                dloc = destruct_location;
                na  = identarg;
                hyptyp = comarg;
                pri = numarg;
                tac = Prim.astact; "." -> 
          <:ast< (HintDestruct $na (AST $dloc) $hyptyp $pri (AST $tac))>>

      | n = numarg; ":"; tac = tacarg; "." ->
          <:ast< (SOLVE $n (TACTIC $tac)) >> 

(*This entry is not commented, only for debug*)
      | IDENT "PrintConstr"; com = comarg; "." ->
          <:ast< (PrintConstr $com)>>
      ] ];
  END