Wishes for Camlp5 - coq/coq GitHub Wiki
I'm collecting here a few wishes about Camlp5 which would help for the purpose of Coq. Please edit/extend...
Required type invariants not enforced by the API
To write a Camlp5 action Coq-side, one needs to know the type of this action in the implementation of Camlp5 (for instance, a Gramext.Stoken
action is supposed to return a string
(which is the type of parser_of_token
in this code.
There is a proposal to use GADT to enforce these invariants
Grammar
, delete_rule
is not symmetric to extend
In If one creates a level, then creates a rule in this level, then deletes this rule, this deletes not only the rule but also the level. This forces Coq to maintain a copy of the stack of levels to manually re-define the level after a deletion. It would be useful to have atomic deletions commands symmetrical to the extension commands.
LIST1
SEP
and LIST0
SEP
simpler
How to make factorization of For instance, if I have two rules sharing a LIST1 foo SEP "bar"
prefix, they are factorized but if I have two rules sharing a LIST1 foo SEP [ "bar" ]
(which itself is a short-hand for sharing a
LIST1 foo SEP [ _ = "bar" -> () ]`), there are not factorized.
I believe that this can be made simpler, e.g. by SEP
taking a list of symbols rather than a single symbol. This is consistent with the fact that the result of parsing the separator is dropped in LIST1
SEP
and LIST0
SEP
, (v
here), so that it should be correct to have the parsing of the separator returns ()
. Then, the syntactic equality on what SEP
parses could be equality of components of the list.
On this topic, see Camlp5 issue 16 and #6167.
How to ask Camlp5 to strictly respect levels?
There are some tolerance to bypass the levels in case of failure of finding a rule which applies. Sometimes this is convenient as it parses more things when otherwise there would have been a failure, but in other cases, this is disconcerting.
Notation "[ x + 1 ]" := (Some x) (x at level 40).
Check [ 0 + 0 + 1 ].
(* Syntax error: '+' '1' ']' expected, even though "+" is at level 50 *)
Even more disconcerting:
Notation "[ x + 1 ]" := (Some x) (x at level 40).
Check [ 0 + 0 + 1 ].
(* Syntax error: '+' '1' ']' expected *)
Check [ fun A => A + 1 ].
(* Syntax error: '+' '1' ']' expected, even though "fun" is at level 200 *)
Notation "[ : x + 1 ]" := (Some x) (x at level 40).
Check [ fun A => A + 1 ].
(* Error changed: Syntax error: ':' or [constr:operconstr level 40] expected after '[' *)
Check [ 0 + 0 + 1 ].
(* Error unchanged: Syntax error: '+' '1' ']' expected after [constr:operconstr level 40] *)
As a consequence, we cannot e.g. enforce the non associativity of an operator.
See also item 2 of this comment and how to parse both { forall A, A } + { True }
, { x : A | P }
and { ' x : A | P }
.