• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

ocaml / odoc / 2927

17 Mar 2025 05:09PM UTC coverage: 73.273% (-0.1%) from 73.372%
2927

push

github

jonludlam
Parser: Ensure parser can be called concurrently

10393 of 14184 relevant lines covered (73.27%)

9819.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

42.22
/src/parser/token.ml
1
(* This module contains the token type, emitted by the lexer, and consumed by
2
   the comment syntax parser. It also contains two functions that format tokens
3
   for error messages. *)
4

5
type section_heading = [ `Begin_section_heading of int * string option ]
6
type style = [ `Bold | `Italic | `Emphasis | `Superscript | `Subscript ]
7
type paragraph_style = [ `Left | `Center | `Right ]
8

9
type tag =
10
  [ `Tag of
11
    [ `Author of string
12
    | `Deprecated
13
    | `Param of string
14
    | `Raise of string
15
    | `Return
16
    | `See of [ `Url | `File | `Document ] * string
17
    | `Since of string
18
    | `Before of string
19
    | `Version of string
20
    | `Canonical of string
21
    | `Children_order
22
    | `Toc_status
23
    | `Order_category
24
    | `Short_title
25
    | `Inline
26
    | `Open
27
    | `Closed
28
    | `Hidden ] ]
29

30
type media = [ `Audio | `Video | `Image ]
31
type media_href = [ `Reference of string | `Link of string ]
32

33
type media_markup =
34
  [ `Simple_media of media_href * media
35
  | `Media_with_replacement_text of media_href * media * string ]
36

37
let s_of_media kind media =
38
  match (kind, media) with
59✔
39
  | `Simple, `Audio -> "{audio!"
5✔
40
  | `Simple, `Video -> "{video!"
5✔
41
  | `Simple, `Image -> "{image!"
7✔
42
  | `Replaced, `Audio -> "{{audio!"
8✔
43
  | `Replaced, `Video -> "{{video!"
8✔
44
  | `Replaced, `Image -> "{{image!"
26✔
45

46
type code_block_tag =
47
  [ `Tag of string Loc.with_location
48
  | `Binding of string Loc.with_location * string Loc.with_location ]
49

50
type code_block_tags = code_block_tag list
51

52
type t =
53
  [ (* End of input. *)
54
    `End
55
  | (* Runs of whitespace. [Blank_line] is any run of whitespace that contains two
56
       or more newline characters. [Single_newline] is any run of whitespace that
57
       contains exactly one newline character. [Space] is any run of whitespace
58
       that contains no newline characters.
59

60
       It is an important invariant in the parser that no adjacent whitespace
61
       tokens are emitted by the lexer. Otherwise, there would be the need for
62
       unbounded lookahead, a (co-?)ambiguity between
63
       [Single_newline Single_newline] and [Blank_line], and other problems. *)
64
    `Space of string
65
  | `Single_newline of string
66
  | `Blank_line of string
67
  | (* A right curly brace ([}]), i.e. end of markup. *)
68
    `Right_brace
69
  | `Right_code_delimiter
70
  | (* Words are anything that is not whitespace or markup. Markup symbols can be
71
       be part of words if escaped.
72

73
       Words can contain plus and minus symbols, but those are emitted as [Plus]
74
       and [Minus] tokens. The parser combines plus and minus into words, except
75
       when they appear first on a line, in which case the tokens are list item
76
       bullets. *)
77
    `Word of string
78
  | `Code_span of string
79
  | `Raw_markup of string option * string
80
  | `Math_span of string
81
  | `Math_block of string
82
  | `Begin_style of style
83
  | `Begin_paragraph_style of paragraph_style
84
  | (* Other inline element markup. *)
85
    `Simple_reference of string
86
  | `Begin_reference_with_replacement_text of string
87
  | `Simple_link of string
88
  | `Begin_link_with_replacement_text of string
89
  | media_markup
90
  | (* Leaf block element markup. *)
91
    `Code_block of
92
    (string Loc.with_location * code_block_tags) option
93
    * string
94
    * string Loc.with_location
95
    * bool
96
  | `Verbatim of string
97
  | `Modules of string
98
  | (* List markup. *)
99
    `Begin_list of [ `Unordered | `Ordered ]
100
  | `Begin_list_item of [ `Li | `Dash ]
101
  | (* Table markup. *)
102
    `Begin_table_light
103
  | `Begin_table_heavy
104
  | `Begin_table_row
105
  | `Begin_table_cell of [ `Header | `Data ]
106
  | `Minus
107
  | `Plus
108
  | `Bar
109
  | section_heading
110
  | tag ]
111

112
let print : [< t ] -> string = function
113
  | `Begin_paragraph_style `Left -> "'{L'"
×
114
  | `Begin_paragraph_style `Center -> "'{C'"
×
115
  | `Begin_paragraph_style `Right -> "'{R'"
×
116
  | `Begin_style `Bold -> "'{b'"
3✔
117
  | `Begin_style `Italic -> "'{i'"
×
118
  | `Begin_style `Emphasis -> "'{e'"
×
119
  | `Begin_style `Superscript -> "'{^'"
×
120
  | `Begin_style `Subscript -> "'{_'"
×
121
  | `Begin_reference_with_replacement_text _ -> "'{{!'"
×
122
  | `Begin_link_with_replacement_text _ -> "'{{:'"
×
123
  | `Begin_list_item `Li -> "'{li ...}'"
10✔
124
  | `Begin_list_item `Dash -> "'{- ...}'"
5✔
125
  | `Begin_table_light -> "{t"
×
126
  | `Begin_table_heavy -> "{table"
×
127
  | `Begin_table_row -> "'{tr'"
×
128
  | `Begin_table_cell `Header -> "'{th'"
×
129
  | `Begin_table_cell `Data -> "'{td'"
×
130
  | `Minus -> "'-'"
2✔
131
  | `Plus -> "'+'"
2✔
132
  | `Bar -> "'|'"
×
133
  | `Begin_section_heading (level, label) ->
4✔
134
      let label = match label with None -> "" | Some label -> ":" ^ label in
×
135
      Printf.sprintf "'{%i%s'" level label
136
  | `Tag (`Author _) -> "'@author'"
5✔
137
  | `Tag `Deprecated -> "'@deprecated'"
2✔
138
  | `Tag (`Param _) -> "'@param'"
1✔
139
  | `Tag (`Raise _) -> "'@raise'"
×
140
  | `Tag `Return -> "'@return'"
×
141
  | `Tag `Children_order -> "'@children_order'"
×
142
  | `Tag `Order_category -> "'@order_category'"
×
143
  | `Tag `Toc_status -> "'@toc_status'"
×
144
  | `Tag `Short_title -> "'@short_title'"
×
145
  | `Tag (`See _) -> "'@see'"
×
146
  | `Tag (`Since _) -> "'@since'"
×
147
  | `Tag (`Before _) -> "'@before'"
×
148
  | `Tag (`Version _) -> "'@version'"
×
149
  | `Tag (`Canonical _) -> "'@canonical'"
×
150
  | `Tag `Inline -> "'@inline'"
×
151
  | `Tag `Open -> "'@open'"
×
152
  | `Tag `Closed -> "'@closed'"
×
153
  | `Tag `Hidden -> "'@hidden"
×
154
  | `Raw_markup (None, _) -> "'{%...%}'"
×
155
  | `Raw_markup (Some target, _) -> "'{%" ^ target ^ ":...%}'"
×
156
  | `Simple_media (`Reference _, `Image) -> "{image!...}"
×
157
  | `Simple_media (`Reference _, `Audio) -> "{audio!...}"
×
158
  | `Simple_media (`Reference _, `Video) -> "{video!...}"
×
159
  | `Simple_media (`Link _, `Image) -> "{image:...}"
×
160
  | `Simple_media (`Link _, `Audio) -> "{audio:...}"
×
161
  | `Simple_media (`Link _, `Video) -> "{video:...}"
×
162
  | `Media_with_replacement_text (`Reference _, `Image, _) ->
×
163
      "{{image!...} ...}"
164
  | `Media_with_replacement_text (`Reference _, `Audio, _) ->
×
165
      "{{audio!...} ...}"
166
  | `Media_with_replacement_text (`Reference _, `Video, _) ->
×
167
      "{{video!...} ...}"
168
  | `Media_with_replacement_text (`Link _, `Image, _) -> "{{image:...} ...}"
×
169
  | `Media_with_replacement_text (`Link _, `Audio, _) -> "{{audio:...} ...}"
×
170
  | `Media_with_replacement_text (`Link _, `Video, _) -> "{{video:...} ...}"
×
171

172
(* [`Minus] and [`Plus] are interpreted as if they start list items. Therefore,
173
   for error messages based on [Token.describe] to be accurate, formatted
174
   [`Minus] and [`Plus] should always be plausibly list item bullets. *)
175
let describe : [< t | `Comment ] -> string = function
176
  | `Word w -> Printf.sprintf "'%s'" w
10✔
177
  | `Code_span _ -> "'[...]' (code)"
5✔
178
  | `Raw_markup _ -> "'{%...%}' (raw markup)"
3✔
179
  | `Begin_paragraph_style `Left -> "'{L ...}' (left alignment)"
1✔
180
  | `Begin_paragraph_style `Center -> "'{C ...}' (center alignment)"
1✔
181
  | `Begin_paragraph_style `Right -> "'{R ...}' (right alignment)"
1✔
182
  | `Begin_style `Bold -> "'{b ...}' (boldface text)"
16✔
183
  | `Begin_style `Italic -> "'{i ...}' (italic text)"
×
184
  | `Begin_style `Emphasis -> "'{e ...}' (emphasized text)"
×
185
  | `Begin_style `Superscript -> "'{^...}' (superscript)"
2✔
186
  | `Begin_style `Subscript -> "'{_...}' (subscript)"
×
187
  | `Math_span _ -> "'{m ...}' (math span)"
×
188
  | `Math_block _ -> "'{math ...}' (math block)"
×
189
  | `Simple_reference _ -> "'{!...}' (cross-reference)"
×
190
  | `Begin_reference_with_replacement_text _ ->
6✔
191
      "'{{!...} ...}' (cross-reference)"
192
  | `Simple_media (`Reference _, `Image) -> "'{image!...}' (image-reference)"
×
193
  | `Simple_media (`Reference _, `Audio) -> "'{audio!...}' (audio-reference)"
×
194
  | `Simple_media (`Reference _, `Video) -> "'{video!...}' (video-reference)"
×
195
  | `Simple_media (`Link _, `Image) -> "'{image:...}' (image-link)"
×
196
  | `Simple_media (`Link _, `Audio) -> "'{audio:...}' (audio-link)"
×
197
  | `Simple_media (`Link _, `Video) -> "'{video:...}' (video-link)"
×
198
  | `Media_with_replacement_text (`Reference _, `Image, _) ->
14✔
199
      "'{{image!...} ...}' (image-reference)"
200
  | `Media_with_replacement_text (`Reference _, `Audio, _) ->
3✔
201
      "'{{audio!...} ...}' (audio-reference)"
202
  | `Media_with_replacement_text (`Reference _, `Video, _) ->
3✔
203
      "'{{video!...} ...}' (video-reference)"
204
  | `Media_with_replacement_text (`Link _, `Image, _) ->
2✔
205
      "'{{image:...} ...}' (image-link)"
206
  | `Media_with_replacement_text (`Link _, `Audio, _) ->
2✔
207
      "'{{audio:...} ...}' (audio-link)"
208
  | `Media_with_replacement_text (`Link _, `Video, _) ->
2✔
209
      "'{{video:...} ...}' (video-link)"
210
  | `Simple_link _ -> "'{:...} (external link)'"
2✔
211
  | `Begin_link_with_replacement_text _ -> "'{{:...} ...}' (external link)"
3✔
212
  | `End -> "end of text"
21✔
213
  | `Space _ -> "whitespace"
×
214
  | `Single_newline _ -> "line break"
1✔
215
  | `Blank_line _ -> "blank line"
6✔
216
  | `Right_brace -> "'}'"
×
217
  | `Right_code_delimiter -> "']}'"
4✔
218
  | `Code_block _ -> "'{[...]}' (code block)"
9✔
219
  | `Verbatim _ -> "'{v ... v}' (verbatim text)"
12✔
220
  | `Modules _ -> "'{!modules ...}'"
5✔
221
  | `Begin_list `Unordered -> "'{ul ...}' (bulleted list)"
27✔
222
  | `Begin_list `Ordered -> "'{ol ...}' (numbered list)"
×
223
  | `Begin_list_item `Li -> "'{li ...}' (list item)"
13✔
224
  | `Begin_list_item `Dash -> "'{- ...}' (list item)"
3✔
225
  | `Begin_table_light -> "'{t ...}' (table)"
3✔
226
  | `Begin_table_heavy -> "'{table ...}' (table)"
2✔
227
  | `Begin_table_row -> "'{tr ...}' (table row)"
2✔
228
  | `Begin_table_cell `Header -> "'{th ... }' (table header cell)"
×
229
  | `Begin_table_cell `Data -> "'{td ... }' (table data cell)"
×
230
  | `Minus -> "'-' (bulleted list item)"
18✔
231
  | `Plus -> "'+' (numbered list item)"
2✔
232
  | `Bar -> "'|'"
×
233
  | `Begin_section_heading (level, _) ->
18✔
234
      Printf.sprintf "'{%i ...}' (section heading)" level
235
  | `Tag (`Author _) -> "'@author'"
18✔
236
  | `Tag `Deprecated -> "'@deprecated'"
5✔
237
  | `Tag (`Param _) -> "'@param'"
3✔
238
  | `Tag (`Raise _) -> "'@raise'"
×
239
  | `Tag `Return -> "'@return'"
×
240
  | `Tag (`See _) -> "'@see'"
1✔
241
  | `Tag (`Since _) -> "'@since'"
2✔
242
  | `Tag (`Before _) -> "'@before'"
×
243
  | `Tag (`Version _) -> "'@version'"
2✔
244
  | `Tag (`Canonical _) -> "'@canonical'"
2✔
245
  | `Tag `Inline -> "'@inline'"
×
246
  | `Tag `Open -> "'@open'"
×
247
  | `Tag `Closed -> "'@closed'"
×
248
  | `Tag `Hidden -> "'@hidden"
×
249
  | `Tag `Children_order -> "'@children_order"
×
250
  | `Tag `Toc_status -> "'@toc_status"
×
251
  | `Tag `Order_category -> "'@order_category"
×
252
  | `Tag `Short_title -> "'@short_title"
×
253
  | `Comment -> "top-level text"
4✔
254

255
let describe_element = function
256
  | `Reference (`Simple, _, _) -> describe (`Simple_reference "")
×
257
  | `Reference (`With_text, _, _) ->
×
258
      describe (`Begin_reference_with_replacement_text "")
259
  | `Link _ -> describe (`Begin_link_with_replacement_text "")
×
260
  | `Heading (level, _, _) -> describe (`Begin_section_heading (level, None))
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc