feat(library/init/lean/parser/parsec): longest_match should return all longest parses
In the case of overlapping notations, we will return a choice node of all possible parses.
This commit is contained in:
parent
18b4456a84
commit
134d27dbec
2 changed files with 12 additions and 8 deletions
|
|
@ -479,21 +479,23 @@ error msg
|
|||
def unexpected_at (msg : string) (pos : position) : m α :=
|
||||
error msg dlist.empty pos
|
||||
|
||||
/- Execute all parsers in `ps` and return the result of the longest parse if any,
|
||||
/- Execute all parsers in `ps` and return the result of the longest parse(s) if any,
|
||||
or else the result of the furthest error. If there are two parses of
|
||||
equal length, the first parse wins. -/
|
||||
def longest_match [monad_except message m] (ps : list (m α)) : m α :=
|
||||
def longest_match [monad_except message m] (ps : list (m α)) : m (list α) :=
|
||||
do it ← left_over,
|
||||
r ← ps.mfoldl (λ (r : result α) p,
|
||||
r ← ps.mfoldr (λ p r,
|
||||
catch
|
||||
(lookahead $ do
|
||||
a ← p,
|
||||
it ← left_over,
|
||||
pure $ match r with
|
||||
| result.ok _ it' := if it'.offset ≥ it.offset then r else result.ok a it
|
||||
| _ := result.ok a it)
|
||||
| result.ok as it' := if it'.offset > it.offset then r
|
||||
else if it.offset > it'.offset then result.ok [a] it
|
||||
else result.ok (a::as) it
|
||||
| _ := result.ok [a] it)
|
||||
(λ msg, pure $ match r with
|
||||
| result.error msg' _ := if nat.lt msg.pos msg'.pos then r
|
||||
| result.error msg' _ := if nat.lt msg.pos msg'.pos then r -- FIXME
|
||||
else if nat.lt msg'.pos msg.pos then result.error msg tt
|
||||
else result.error (merge msg msg') tt
|
||||
| _ := r))
|
||||
|
|
|
|||
|
|
@ -98,10 +98,12 @@ do tk ← match_token,
|
|||
| none := error
|
||||
|
||||
def token : read_m syntax :=
|
||||
do (r, i) ← with_source_info $
|
||||
do (r, i) ← with_source_info $ do {
|
||||
-- NOTE the order: if a token is both a symbol and a valid identifier (i.e. a keyword),
|
||||
-- we want it to be recognized as a symbol
|
||||
longest_match [symbol', ident', number'],
|
||||
f::_ ← longest_match [symbol', ident', number'] | failure,
|
||||
pure f
|
||||
},
|
||||
pure (r i)
|
||||
|
||||
--TODO(Sebastian): error messages
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue