模块 Location

module Location: sig .. end

源代码位置(位置范围),用于语法树。

警告:此模块不稳定,并且是 compiler-libs 的一部分。


type t = Warnings.loc = {
   loc_start : Lexing.position;
   loc_end : Lexing.position;
   loc_ghost : bool;
}

关于此模块中 Lexing.position 用法的说明。如果 pos_fname = "",则使用 !input_name 代替。如果 pos_lnum = -1,则 pos_bol = 0。使用 pos_cnum 并重新解析文件以获取行号和字符号。否则所有字段都是正确的。

val none : t

类型 t 的任意值;描述一个空的幽灵范围。

val is_none : t -> bool

对于 Location.none 为真,对于任何其他位置为假

val in_file : string -> t

返回位于给定文件中的空幽灵范围。

val init : Lexing.lexbuf -> string -> unit

lexbuf 的文件名和行号设置为命名文件的开头。

val curr : Lexing.lexbuf -> t

lexbuf 获取当前标记的位置。

val symbol_rloc : unit -> t
val symbol_gloc : unit -> t
val rhs_loc : int -> t

rhs_loc n 返回当前解析器规则中位置 n(从 1 开始)处的符号的位置。

val rhs_interval : int -> int -> t
val get_pos_info : Lexing.position -> string * int * int

文件、行、字符

type 'a loc = {
   txt : 'a;
   loc : t;
}
val mknoloc : 'a -> 'a loc
val mkloc : 'a -> t -> 'a loc

输入信息

val input_name : string ref
val input_lexbuf : Lexing.lexbuf option ref
val input_phrase_buffer : Buffer.t option ref

顶层特定函数

val echo_eof : unit -> unit
val separate_new_message : Format.formatter -> unit
val reset : unit -> unit

重写路径

val rewrite_absolute_path : string -> string

rewrite_absolute_path path 重写 path 以尊重 BUILD_PATH_PREFIX_MAP 变量(如果已设置)。它不检查 path 是否为绝对路径。结果如下

  • 如果未设置 BUILD_PATH_PREFIX_MAP,则只返回 path
  • 否则,使用映射进行重写(如果没有匹配的前缀,则只返回 path)。

参见 BUILD_PATH_PREFIX_MAP 规范

val rewrite_find_first_existing : string -> string option

rewrite_find_first_existing path 使用 BUILD_PATH_PREFIX_MAP 映射并尝试在映射中查找一个源,该源映射到文件系统中存在的结果。有以下返回值

  • None,表示以下情况之一
    • 未设置 BUILD_PATH_PREFIX_MAP 且 path 不存在,或者
    • 在映射中未找到 path 的任何源前缀,
  • Some target,表示 target 存在,并且以下情况之一
    • 未设置 BUILD_PATH_PREFIX_MAP 且 target = path,或者
    • targetpath 映射到的第一个在文件系统中存在的文件(按优先级顺序)。
  • Not_found 抛出,表示在映射中找到了一些与 path 匹配的源前缀,但它们都不存在于文件系统中。调用者应该捕获此异常并发出相应的错误消息。

参见 BUILD_PATH_PREFIX_MAP 规范

val rewrite_find_all_existing_dirs : string -> string list

rewrite_find_all_existing_dirs dir 累积一个现存目录列表 dirs,这些目录是将潜在的抽象目录 dir 映射到 BUILD_PATH_PREFIX_MAP 环境变量(如果有)中的所有映射对的结果。列表 dirs 将按优先级顺序排列(头部为最高优先级)。

可能的结果是

  • [],表示以下情况之一
    • 未设置 BUILD_PATH_PREFIX_MAP 且 dir 不是现存目录,或者
    • 如果已设置,则 dir 没有匹配的前缀。
  • Some dirs,表示 dirs 是找到的目录。以下情况之一
    • 未设置 BUILD_PATH_PREFIX_MAP 且 dirs = [dir],或者
    • 它已设置,并且 dirs 是映射的现存目录。
  • Not_found 抛出,表示在映射中找到了一些与 dir 匹配的源前缀,但没有任何映射结果是现存目录(可能是由于配置错误)。调用者应该捕获此异常并发出相应的错误消息。

参见 BUILD_PATH_PREFIX_MAP 规范

val absolute_path : string -> string

absolute_path path 首先从 path 创建一个绝对路径 s,如果 path 是相对路径,则在其前面加上当前工作目录。然后使用 rewrite_absolute_path 重写 s。最后,通过消除 '.''..' 的实例来规范化结果。

打印位置

val show_filename : string -> string

在 -absname 模式下,返回此文件名的绝对路径。否则,返回未更改的文件名。

val print_filename : Format.formatter -> string -> unit
val print_loc : Format.formatter -> t -> unit
val print_locs : Format.formatter -> t list -> unit

顶层特定位置高亮

val highlight_terminfo : Lexing.lexbuf -> Format.formatter -> t list -> unit

报告错误和警告

报告类型和报告打印机

type msg = (Format.formatter -> unit) loc 
val msg : ?loc:t ->
('a, Format.formatter, unit, msg) format4 -> 'a
type report_kind = 
| Report_error
| Report_warning of string
| Report_warning_as_error of string
| Report_alert of string
| Report_alert_as_error of string
type report = {
   kind : report_kind;
   main : msg;
   sub : msg list;
}
type report_printer = {
   pp : report_printer -> Format.formatter -> report -> unit;
   pp_report_kind : report_printer ->
report -> Format.formatter -> report_kind -> unit
;
   pp_main_loc : report_printer ->
report -> Format.formatter -> t -> unit
;
   pp_main_txt : report_printer ->
report ->
Format.formatter -> (Format.formatter -> unit) -> unit
;
   pp_submsgs : report_printer ->
report -> Format.formatter -> msg list -> unit
;
   pp_submsg : report_printer ->
report -> Format.formatter -> msg -> unit
;
   pp_submsg_loc : report_printer ->
report -> Format.formatter -> t -> unit
;
   pp_submsg_txt : report_printer ->
report ->
Format.formatter -> (Format.formatter -> unit) -> unit
;
}

用于 report 的打印机,使用开放递归定义。目标是通过重用现有打印机的代码来简化新打印机的定义。

编译器中使用的报告打印机

val batch_mode_printer : report_printer
val terminfo_toplevel_printer : Lexing.lexbuf -> report_printer
val best_toplevel_printer : unit -> report_printer

检测终端功能并选择合适的打印机

打印 report

val print_report : Format.formatter -> report -> unit

显示错误或警告报告。

val report_printer : (unit -> report_printer) ref

重新定义报告打印机的钩子。

钩子是一个 unit -> report_printer 而不是简单的 report_printer:这很有用,因为它可以检测输出的类型(文件、终端等)并相应地选择打印机。

val default_report_printer : unit -> report_printer

用于钩子中的原始报告打印机。

报告警告

Warnings.t 转换为 report

val report_warning : t -> Warnings.t -> report option

report_warning loc w 为给定的警告 w 生成一个报告,或者如果该警告不需要打印则生成 None

val warning_reporter : (t -> Warnings.t -> report option) ref

用于拦截警告的钩子。

val default_warning_reporter : t -> Warnings.t -> report option

用于钩子中的原始警告报告器。

打印警告

val formatter_for_warnings : Format.formatter ref
val print_warning : t -> Format.formatter -> Warnings.t -> unit

打印警告。这仅仅是 report_warningprint_report 的组合。

val prerr_warning : t -> Warnings.t -> unit

print_warning 相同,但使用 !formatter_for_warnings 作为输出格式化程序。

报告警报

Alert.t 转换为 report

val report_alert : t -> Warnings.alert -> report option

report_alert loc w 为给定的警报 w 生成一个报告,或者如果该警报不需要打印则生成 None

val alert_reporter : (t -> Warnings.alert -> report option) ref

用于拦截警报的钩子。

val default_alert_reporter : t -> Warnings.alert -> report option

用于钩子中的原始警报报告器。

打印警报

val print_alert : t -> Format.formatter -> Warnings.alert -> unit

打印警报。这仅仅是 report_alertprint_report 的组合。

val prerr_alert : t -> Warnings.alert -> unit

print_alert 相同,但使用 !formatter_for_warnings 作为输出格式化程序。

val deprecated : ?def:t -> ?use:t -> t -> string -> unit

打印弃用警报。

val alert : ?def:t ->
?use:t -> kind:string -> t -> string -> unit

打印任意警报。

val auto_include_alert : string -> unit

打印已自动将 -I +lib 添加到加载路径的警报

val deprecated_script_alert : string -> unit

deprecated_script_alert command 打印一个警报,指示 command foo 已被弃用,取而代之的是 command ./foo

报告错误

type error = report 

error 是一个 report,其中 report_kind 必须是 Report_error

val error : ?loc:t -> ?sub:msg list -> string -> error
val errorf : ?loc:t ->
?sub:msg list ->
('a, Format.formatter, unit, error) format4 -> 'a
val error_of_printer : ?loc:t ->
?sub:msg list ->
(Format.formatter -> 'a -> unit) -> 'a -> error
val error_of_printer_file : (Format.formatter -> 'a -> unit) -> 'a -> error

自动为抛出的异常报告错误

val register_error_of_exn : (exn -> error option) -> unit

每个定义可作为用户可见错误出现的自定义异常类型的编译器模块都应该使用 register_error_of_exn 注册此异常的“打印机”。打印机的结果是一个 error 值,其中包含位置、消息以及可选的子消息(每个子消息也都有位置)。

val error_of_exn : exn -> [ `Already_displayed | `Ok of error ] option
exception Error of error

抛出 Error e 表示发生错误 e;该异常将被捕获,并且错误将被打印。

exception Already_displayed_error

抛出 Already_displayed_error 表示错误已打印。该异常将被捕获,但不会打印任何内容

val raise_errorf : ?loc:t ->
?sub:msg list ->
('a, Format.formatter, unit, 'b) format4 -> 'a
val report_exception : Format.formatter -> exn -> unit

如果异常未知,则重新抛出。