Source file parse_with_lexer.ml
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
module type ANY = Fmlib_std.Interfaces.ANY
module Make
(State: ANY)
(Token: ANY)
(Final: ANY)
(Semantic: ANY)
(Lex: Interfaces.LEXER with type final = Position.range * Token.t)
(Parse: Interfaces.FULL_PARSER with
type state = State.t
and type token = Position.range * Token.t
and type expect= string * Indent.expectation option
and type final = Final.t
and type semantic = Semantic.t)
=
struct
type token = char
type item = token
type final = Final.t
type expect = string * Indent.expectation option
type semantic = Semantic.t
type state = State.t
type t = {
lex: Lex.t;
parse: Parse.t;
}
let make (lex: Lex.t) (parse: Parse.t): t =
{lex; parse}
let lex (p: t): Lex.t =
p.lex
let parse (p: t): Parse.t =
p.parse
let needs_more (p: t): bool =
Lex.needs_more p.lex
&&
Parse.needs_more p.parse
let has_succeeded (p: t): bool =
Parse.has_succeeded p.parse
let has_failed_syntax (p:t): bool =
if Parse.needs_more p.parse then
Lex.has_failed_syntax p.lex
else
Parse.has_failed_syntax p.parse
let has_failed_semantic (p: t): bool =
Parse.has_failed_semantic p.parse
let final (p: t): Final.t =
assert (has_succeeded p);
Parse.final p.parse
let failed_expectations
(p: t)
: expect list
=
assert (has_failed_syntax p);
if Parse.needs_more p.parse then
Lex.failed_expectations p.lex
else
Parse.failed_expectations p.parse
let failed_semantic (p: t): Semantic.t =
assert (has_failed_semantic p);
Parse.failed_semantic p.parse
let position (p: t): Position.t =
match Parse.first_lookahead_token p.parse with
| None ->
Lex.position p.lex
| Some ((p1, _), _) ->
p1
let state (p: t): State.t =
Parse.state p.parse
let rec check_token (p: t): t =
if Lex.has_succeeded p.lex then
check_token {
lex =
Lex.restart p.lex;
parse =
Parse.put (Lex.final p.lex) p.parse
}
else
p
let put (c: char) (p: t): t =
check_token {p with lex = Lex.put c p.lex}
let put_end (p: t): t =
let p =
check_token {p with lex = Lex.put_end p.lex}
in
assert (not (Lex.has_succeeded p.lex));
match Lex.first_lookahead_token p.lex with
| None ->
{p with parse = Parse.put_end p.parse}
| Some _ ->
p
let run_on_string = Run_on.string needs_more put put_end
end