Module Pcoq

Deprecated alias for Procq

include module type of struct include Procq end
include Gramlib.Grammar.S with type keyword_state := CLexer.keyword_state and type te := Tok.t and type 'a pattern := 'a Tok.p and type 'a with_gstate := 'a and type 'a with_kwstate := 'a and type 'a with_estate := 'a and type 'a mod_estate := 'a
type ty_pattern = Procq.ty_pattern =
| TPattern : 'a Tok.p -> ty_pattern

Type combinators to factor the module type between explicit state passing in Grammar and global state in Procq

module Parsable = Procq.Parsable
module Entry = Procq.Entry
module Symbol = Procq.Symbol
module Rule = Procq.Rule
module Rules = Procq.Rules
module Production = Procq.Production
type 'a single_extend_statement = string option * Gramlib.Gramext.g_assoc option * 'a Production.t list
type 'a extend_statement = 'a Procq.extend_statement =
| Reuse of string option * 'a Production.t list(*

Extend an existing level by its optional given name. If None, picks the topmost level.

*)
| Fresh of Gramlib.Gramext.position * 'a single_extend_statement list(*

Create a level at the given position.

*)
val generalize_symbol : ('a'tr'c) Symbol.t -> ('bGramlib.Grammar.norec'c) Symbol.t option
val level_of_nonterm : ('aGramlib.Grammar.norec'c) Symbol.t -> string option
module Lookahead = Procq.Lookahead
val terminal : string -> string Tok.p

When string is not an ident, returns a keyword.

The parser of Coq is built from three kinds of rule declarations:

  • dynamic rules declared at the evaluation of Coq files (using e.g. Notation, Infix, or Tactic Notation)
  • static rules explicitly defined in files g_*.mlg
  • static rules macro-generated by ARGUMENT EXTEND, TACTIC EXTEND and VERNAC EXTEND (see e.g. file extratactics.mlg)

Note that parsing a Coq document is in essence stateful: the parser needs to recognize commands that start proofs and use a different parsing entry point for them.

We thus provide two different interfaces: the "raw" parsing interface, in the style of camlp5, which provides more flexibility, and a more specialize "parse_vernac" one, which will indeed adjust the state as needed.

Dynamic extension of rules

For constr notations, dynamic addition of new rules is done in several steps:

  • "x + y" (user gives a notation string of type Topconstr.notation) | (together with a constr entry level, e.g. 50, and indications of) | (subentries, e.g. x in constr next level and y constr same level) | | splitting into tokens by Metasyntax.split_notation_string V String "x"; String "+"; String "y" : symbol_token list | | interpreted as a mixed parsing/printing production | by Metasyntax.analyse_notation_tokens V NonTerminal "x"; Terminal "+"; NonTerminal "y" : symbol list | | translated to a parsing production by Metasyntax.make_production V GramConstrNonTerminal (ETConstr (NextLevel,(BorderProd Left,LeftA)), Some "x"); GramConstrTerminal ("","+"); GramConstrNonTerminal (ETConstr (NextLevel,(BorderProd Right,LeftA)), Some "y") : grammar_constr_prod_item list | | Egrammar.make_constr_prod_item V Gramext.g_symbol list which is sent to camlp5

For user level tactic notations, dynamic addition of new rules is also done in several steps:

  • "f" constr(x) (user gives a Tactic Notation command) | | parsing V TacTerm "f"; TacNonTerm ("constr", Some "x") : grammar_tactic_prod_item_expr list | | Metasyntax.interp_prod_item V GramTerminal "f"; GramNonTerminal (ConstrArgType, Aentry ("constr","constr"), Some "x") : grammar_prod_item list | | Egrammar.make_prod_item V Gramext.g_symbol list

For TACTIC/VERNAC/ARGUMENT EXTEND, addition of new rules is done as follows:

  • "f" constr(x) (developer gives an EXTEND rule) | | macro-generation in tacextend.mlg/vernacextend.mlg/argextend.mlg V GramTerminal "f"; GramNonTerminal (ConstrArgType, Aentry ("constr","constr"), Some "x") | | Egrammar.make_prod_item V Gramext.g_symbol list

Parse a string

val parse_string : 'a Entry.t -> ?loc:Loc.t -> string -> 'a
val eoi_entry : 'a Entry.t -> 'a Entry.t
val create_generic_entry2 : string -> ('aGenarg.rlevel) Genarg.abstract_argument_type -> 'a Entry.t
val register_grammar : ('raw'glb'top) Genarg.genarg_type -> 'raw Entry.t -> unit
val genarg_grammar : ('raw'glb'top) Genarg.genarg_type -> 'raw Entry.t
module Prim = Procq.Prim
module Constr = Procq.Constr
module Module = Procq.Module
Type-safe grammar extension
val epsilon_value : ('a -> 'self) -> ('self_'a) Symbol.t -> 'self option
Extending the parser without synchronization
val grammar_extend : 'a Entry.t -> 'a extend_statement -> unit

Extend the grammar of Coq, without synchronizing it with the backtracking mechanism. This means that grammar extensions defined this way will survive an undo.

Extending the parser with summary-synchronized commands
module GramState = Procq.GramState

Auxiliary state of the grammar. Any added data must be marshallable.

Extension with parsing rules
type 'a grammar_command = 'a Procq.grammar_command

Type of synchronized parsing extensions. The 'a type should be marshallable.

Type of reinitialization data

type extend_rule = Procq.extend_rule =
| ExtendRule : 'a Entry.t * 'a extend_statement -> extend_rule
| ExtendRuleReinit : 'a Entry.t * gram_reinit * 'a extend_statement -> extend_rule
type 'a grammar_extension = 'a Procq.grammar_extension = {
gext_fun : 'a -> GramState.t -> extend_rule list * GramState.t;
gext_eq : 'a -> 'a -> bool;
}

Grammar extension entry point. Given some 'a and a current grammar state, such a function must produce the list of grammar extensions that will be applied in the same order and kept synchronized w.r.t. the summary, together with a new state. It should be pure.

val create_grammar_command : string -> 'a grammar_extension -> 'a grammar_command

Create a new grammar-modifying command with the given name. The extension function is called to generate the rules for a given data.

val extend_grammar_command : 'a grammar_command -> 'a -> unit

Extend the grammar of Coq with the given data.

Extension with parsing entries
type ('a, 'b) entry_command = ('a'b) Procq.entry_command

Type of synchronized entry creation. The 'a type should be marshallable.

type ('a, 'b) entry_extension = ('a'b) Procq.entry_extension = {
eext_fun : 'a -> GramState.t -> string list * GramState.t;
eext_eq : 'a -> 'a -> bool;
}

Entry extension entry point. Given some 'a and a current grammar state, such a function must produce the list of entry extensions that will be created and kept synchronized w.r.t. the summary, together with a new state. It should be pure.

val create_entry_command : string -> ('a'b) entry_extension -> ('a'b) entry_command

Create a new entry-creating command with the given name. The extension function is called to generate the new entries for a given data.

val extend_entry_command : ('a'b) entry_command -> 'a -> 'b Entry.t list

Create new synchronized entries using the provided data.

val find_custom_entry : ('a'b) entry_command -> string -> 'b Entry.t

Find an entry generated by the synchronized system in the current state.

  • raises Not_found

    if non-existent.

Protection w.r.t. backtrack
val with_grammar_rule_protection : ('a -> 'b) -> 'a -> 'b
type frozen_t = Procq.frozen_t
val parser_summary_tag : frozen_t Summary.Dyn.tag

Registering grammars by name

val register_grammars_by_name : string -> Entry.any_t list -> unit
val find_grammars_by_name : string -> Entry.any_t list
val freeze : unit -> frozen_t

Parsing state handling

val unfreeze : frozen_t -> unit
val get_keyword_state : unit -> CLexer.keyword_state
val set_keyword_state : CLexer.keyword_state -> unit