/- 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