56 lines
1.8 KiB
Text
56 lines
1.8 KiB
Text
/-
|
|
Copyright (c) 2018 Microsoft Corporation. All rights reserved.
|
|
Released under Apache 2.0 license as described in the file LICENSE.
|
|
Author: Sebastian Ullrich
|
|
|
|
A combinator for building Pratt parsers
|
|
-/
|
|
prelude
|
|
import init.lean.parser.token
|
|
|
|
namespace lean.parser
|
|
open monad_parsec combinators
|
|
|
|
variables {base_m : Type → Type}
|
|
variables [monad base_m] [monad_basic_parser base_m] [monad_parsec syntax base_m] [monad_reader parser_config base_m]
|
|
|
|
local notation `m` := rec_t nat syntax base_m
|
|
local notation `parser` := m syntax
|
|
|
|
def curr_lbp : m nat :=
|
|
do except.ok tk ← monad_lift peek_token | pure 0,
|
|
match tk with
|
|
| syntax.atom ⟨_, sym⟩ := do
|
|
cfg ← read,
|
|
some ⟨_, tk_cfg⟩ ← pure (cfg.tokens.match_prefix sym.mk_iterator) | error "curr_lbp: unreachable",
|
|
pure tk_cfg.lbp
|
|
| syntax.ident _ := pure max_prec
|
|
| syntax.raw_node {kind := @number, ..} := pure max_prec
|
|
| syntax.raw_node {kind := @string_lit, ..} := pure max_prec
|
|
| _ := error "curr_lbp: unknown token kind"
|
|
|
|
private def trailing_loop (trailing : reader_t syntax m syntax) (rbp : nat) : nat → syntax → parser
|
|
| 0 _ := error "unreachable"
|
|
| (n+1) left := do
|
|
lbp ← curr_lbp,
|
|
if rbp < lbp then do
|
|
left ← trailing.run left,
|
|
trailing_loop n left
|
|
else
|
|
pure left
|
|
|
|
variables [monad_except (parsec.message syntax) base_m] [alternative base_m]
|
|
variables (leading : m syntax) (trailing : reader_t syntax m syntax) (p : m syntax)
|
|
|
|
def pratt_parser : base_m syntax :=
|
|
rec_t.run_parsec p $ λ rbp, do
|
|
left ← leading,
|
|
n ← remaining,
|
|
trailing_loop trailing rbp (n+1) left
|
|
|
|
instance pratt_parser.tokens [has_tokens leading] [has_tokens trailing] : has_tokens (pratt_parser leading trailing p) :=
|
|
⟨has_tokens.tokens leading ++ has_tokens.tokens trailing⟩
|
|
instance pratt_parser.view : has_view syntax (pratt_parser leading trailing p) :=
|
|
default _
|
|
|
|
end lean.parser
|