refactor: simplify withPosition combinator
Add `checkColGt`
This commit is contained in:
parent
5b4247a9c7
commit
6ddec22763
6 changed files with 33 additions and 32 deletions
|
|
@ -125,6 +125,7 @@ structure ParserContext extends InputContext :=
|
|||
(env : Environment)
|
||||
(tokens : TokenTable)
|
||||
(insideQuot : Bool := false)
|
||||
(savedPos : Position := { line := 1, column := 0 })
|
||||
|
||||
structure Error :=
|
||||
(unexpected : String := "")
|
||||
|
|
@ -1373,29 +1374,30 @@ def anyOfFn : List Parser → ParserFn
|
|||
| [p], c, s => p.fn c s
|
||||
| p::ps, c, s => orelseFn p.fn (anyOfFn ps) c s
|
||||
|
||||
@[inline] def checkColGeFn (col : Nat) (errorMsg : String) : ParserFn :=
|
||||
|
||||
@[inline] def checkColGeFn (errorMsg : String) : ParserFn :=
|
||||
fun c s =>
|
||||
let pos := c.fileMap.toPosition s.pos;
|
||||
if pos.column ≥ col then s
|
||||
if pos.column ≥ c.savedPos.column then s
|
||||
else s.mkError errorMsg
|
||||
|
||||
@[inline] def checkColGe (col : Nat) (errorMsg : String) : Parser :=
|
||||
{ fn := checkColGeFn col errorMsg }
|
||||
@[inline] def checkColGe (errorMsg : String) : Parser :=
|
||||
{ fn := checkColGeFn errorMsg }
|
||||
|
||||
@[inline] def checkLineLeFn (line : Nat) (errorMsg : String) : ParserFn :=
|
||||
@[inline] def checkColGtFn (errorMsg : String) : ParserFn :=
|
||||
fun c s =>
|
||||
let pos := c.fileMap.toPosition s.pos;
|
||||
if pos.line ≤ line then s
|
||||
if pos.column > c.savedPos.column then s
|
||||
else s.mkError errorMsg
|
||||
|
||||
@[inline] def checkLineLe (line : Nat) (errorMsg : String) : Parser :=
|
||||
{ fn := checkLineLeFn line errorMsg }
|
||||
@[inline] def checkColGt (errorMsg : String) : Parser :=
|
||||
{ fn := checkColGtFn errorMsg }
|
||||
|
||||
@[inline] def withPosition (p : Position → Parser) : Parser :=
|
||||
{ info := (p { line := 1, column := 0 }).info,
|
||||
@[inline] def withPosition (p : Parser) : Parser :=
|
||||
{ info := p.info,
|
||||
fn := fun c s =>
|
||||
let pos := c.fileMap.toPosition s.pos;
|
||||
(p pos).fn c s }
|
||||
p.fn { c with savedPos := pos } s }
|
||||
|
||||
def eoiFn : ParserFn :=
|
||||
fun c s =>
|
||||
|
|
@ -1407,7 +1409,7 @@ fun c s =>
|
|||
{ fn := eoiFn }
|
||||
|
||||
@[inline] def many1Indent (p : Parser) (errorMsg : String) : Parser :=
|
||||
withPosition $ fun pos => many1 (checkColGe pos.column errorMsg >> p)
|
||||
withPosition $ many1 (checkColGe errorMsg >> p)
|
||||
|
||||
open Std (RBMap RBMap.empty)
|
||||
|
||||
|
|
|
|||
|
|
@ -71,13 +71,13 @@ def leftArrow : Parser := unicodeSymbol " ← " " <- "
|
|||
`notFollowedByTermToken >> notFollowedBy (ident <|> numLit <|> strLit <|> charLit <|> nameLit)`
|
||||
-/
|
||||
def doSeqIndent :=
|
||||
withPosition fun pos₁ =>
|
||||
withPosition $
|
||||
sepBy1
|
||||
doElemParser
|
||||
-- The separator for the indented `do`-block
|
||||
("; "
|
||||
-- check indentation
|
||||
>> checkColGe pos₁.column "do-elements must be indented"
|
||||
>> checkColGe "do-elements must be indented"
|
||||
>> notFollowedByCommandToken >> notFollowedBy eoi)
|
||||
>> optional (try ("; " >> notFollowedByTermToken >> notFollowedBy (ident <|> numLit <|> strLit <|> charLit <|> nameLit)))
|
||||
def doSeqBracketed := parser! "{" >> sepBy1 doElemParser "; " true >> "}"
|
||||
|
|
@ -117,15 +117,15 @@ else if c_2 then
|
|||
action_3
|
||||
```
|
||||
-/
|
||||
@[builtinDoElemParser] def doIf := parser! withPosition fun pos =>
|
||||
@[builtinDoElemParser] def doIf := parser! withPosition $
|
||||
"if " >> termParser >> " then " >> doSeq
|
||||
>> many (checkColGe pos.column "'else if' in 'do' must be indented" >> try (" else " >> " if ") >> termParser >> " then " >> doSeq)
|
||||
>> optional (checkColGe pos.column "'else' in 'do' must be indented" >> " else " >> doSeq)
|
||||
>> many (checkColGe "'else if' in 'do' must be indented" >> try (" else " >> " if ") >> termParser >> " then " >> doSeq)
|
||||
>> optional (checkColGe "'else' in 'do' must be indented" >> " else " >> doSeq)
|
||||
@[builtinDoElemParser] def doFor := parser! "for " >> termParser >> " in " >> termParser maxPrec >> doSeq
|
||||
|
||||
/- `match`-expression where the right-hand-side of alternatives is a `doSeq` instead of a `term` -/
|
||||
def doMatchAlt : Parser := sepBy1 termParser ", " >> darrow >> doSeq
|
||||
def doMatchAlts : Parser := parser! withPosition fun pos => (optional "| ") >> sepBy1 doMatchAlt (checkColGe pos.column "alternatives must be indented" >> "|")
|
||||
def doMatchAlts : Parser := parser! withPosition $ (optional "| ") >> sepBy1 doMatchAlt (checkColGe "alternatives must be indented" >> "|")
|
||||
@[builtinDoElemParser] def doMatch := parser!:leadPrec "match " >> sepBy1 matchDiscr ", " >> optType >> " with " >> doMatchAlts
|
||||
|
||||
@[builtinDoElemParser] def «break» := parser! "break"
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ def rwRuleSeq := parser! "[" >> sepBy1 rwRule ", " true >> "]"
|
|||
def majorPremise := parser! optional (try (ident >> " : ")) >> termParser
|
||||
def altRHS := Term.hole <|> Term.syntheticHole <|> indentedNonEmptySeq
|
||||
def inductionAlt : Parser := nodeWithAntiquot "inductionAlt" `Lean.Parser.Tactic.inductionAlt $ ident' >> many ident' >> darrow >> altRHS
|
||||
def inductionAlts : Parser := withPosition $ fun pos => "|" >> sepBy1 inductionAlt (checkColGe pos.column "alternatives must be indented" >> "|")
|
||||
def inductionAlts : Parser := withPosition $ "|" >> sepBy1 inductionAlt (checkColGe "alternatives must be indented" >> "|")
|
||||
def withAlts : Parser := optional (" with " >> inductionAlts)
|
||||
def usingRec : Parser := optional (" using " >> ident)
|
||||
def generalizingVars := optional (" generalizing " >> many1 ident)
|
||||
|
|
@ -71,7 +71,7 @@ def generalizingVars := optional (" generalizing " >> many1 ident)
|
|||
@[builtinTacticParser] def «cases» := parser! nonReservedSymbol "cases " >> majorPremise >> withAlts
|
||||
|
||||
def matchAlt : Parser := parser! sepBy1 termParser ", " >> darrow >> altRHS
|
||||
def matchAlts : Parser := group $ withPosition $ fun pos => (optional "| ") >> sepBy1 matchAlt (checkColGe pos.column "alternatives must be indented" >> "|")
|
||||
def matchAlts : Parser := group $ withPosition $ (optional "| ") >> sepBy1 matchAlt (checkColGe "alternatives must be indented" >> "|")
|
||||
@[builtinTacticParser] def «match» := parser! nonReservedSymbol "match " >> sepBy1 Term.matchDiscr ", " >> Term.optType >> " with " >> matchAlts
|
||||
@[builtinTacticParser] def «introMatch» := parser! nonReservedSymbol "intro " >> matchAlts
|
||||
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@ registerBuiltinDynamicParserAttribute `tacticParser `tactic
|
|||
categoryParser `tactic rbp
|
||||
|
||||
def Tactic.indentedNonEmptySeq : Parser :=
|
||||
nodeWithAntiquot "tacticSeq" `Lean.Parser.Tactic.seq $ withPosition fun pos =>
|
||||
sepBy1 tacticParser (try ("; " >> checkColGe pos.column "tatic must be indented"))
|
||||
nodeWithAntiquot "tacticSeq" `Lean.Parser.Tactic.seq $ withPosition $
|
||||
sepBy1 tacticParser (try ("; " >> checkColGe "tatic must be indented"))
|
||||
|
||||
def darrow : Parser := " => "
|
||||
|
||||
|
|
@ -117,9 +117,9 @@ nodeWithAntiquot "matchAlt" `Lean.Parser.Term.matchAlt $
|
|||
sepBy1 termParser ", " >> darrow >> termParser
|
||||
|
||||
def matchAlts (optionalFirstBar := true) : Parser :=
|
||||
parser! withPosition fun pos =>
|
||||
parser! withPosition $
|
||||
(if optionalFirstBar then optional "| " else "| ") >>
|
||||
sepBy1 matchAlt (checkColGe pos.column "alternatives must be indented" >> "|")
|
||||
sepBy1 matchAlt (checkColGe "alternatives must be indented" >> "|")
|
||||
|
||||
def matchDiscr := parser! optional (try (ident >> checkNoWsBefore "no space before ':'" >> ":")) >> termParser
|
||||
|
||||
|
|
|
|||
|
|
@ -365,9 +365,8 @@ if stx.getKind == k then do
|
|||
else
|
||||
p
|
||||
|
||||
@[combinatorFormatter Lean.Parser.withPosition] def withPosition.formatter (p : Position → Formatter) : Formatter := do
|
||||
-- call closure with dummy position
|
||||
p ⟨0, 0⟩
|
||||
@[combinatorFormatter Lean.Parser.withPosition] def withPosition.formatter (p : Formatter) : Formatter := do
|
||||
p
|
||||
|
||||
@[combinatorFormatter Lean.Parser.setExpected]
|
||||
def setExpected.formatter (expected : List String) (p : Formatter) : Formatter :=
|
||||
|
|
@ -386,7 +385,8 @@ pushLine
|
|||
@[combinatorFormatter checkNoWsBefore] def checkNoWsBefore.formatter : Formatter := pure ()
|
||||
@[combinatorFormatter checkTailWs] def checkTailWs.formatter : Formatter := pure ()
|
||||
@[combinatorFormatter checkColGe] def checkColGe.formatter : Formatter := pure ()
|
||||
@[combinatorFormatter checkLineLe] def checkLineLe.formatter : Formatter := pure ()
|
||||
@[combinatorFormatter checkColGt] def checkColGt.formatter : Formatter := pure ()
|
||||
|
||||
@[combinatorFormatter eoi] def eoi.formatter : Formatter := pure ()
|
||||
@[combinatorFormatter notFollowedByCategoryToken] def notFollowedByCategoryToken.formatter : Formatter := pure ()
|
||||
@[combinatorFormatter checkNoImmediateColon] def checkNoImmediateColon.formatter : Formatter := pure ()
|
||||
|
|
|
|||
|
|
@ -430,9 +430,8 @@ if stx.getKind == k then
|
|||
else
|
||||
p
|
||||
|
||||
@[combinatorParenthesizer Lean.Parser.withPosition] def withPosition.parenthesizer (p : Position → Parenthesizer) : Parenthesizer := do
|
||||
-- call closure with dummy position
|
||||
p ⟨0, 0⟩
|
||||
@[combinatorParenthesizer Lean.Parser.withPosition] def withPosition.parenthesizer (p : Parenthesizer) : Parenthesizer := do
|
||||
p
|
||||
|
||||
@[combinatorParenthesizer Lean.Parser.setExpected]
|
||||
def setExpected.parenthesizer (expected : List String) (p : Parenthesizer) : Parenthesizer :=
|
||||
|
|
@ -447,9 +446,9 @@ p
|
|||
@[combinatorParenthesizer Lean.Parser.checkNoWsBefore] def checkNoWsBefore.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.checkTailWs] def checkTailWs.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.checkColGe] def checkColGe.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.checkColGt] def checkColGt.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.eoi] def eoi.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.notFollowedByCategoryToken] def notFollowedByCategoryToken.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.checkLineLe] def checkLineLe.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.checkNoImmediateColon] def checkNoImmediateColon.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.checkInsideQuot] def checkInsideQuot.parenthesizer : Parenthesizer := pure ()
|
||||
@[combinatorParenthesizer Lean.Parser.checkOutsideQuot] def checkOutsideQuot.parenthesizer : Parenthesizer := pure ()
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue