fix: longestMatch at trailing parsers
Before this commit, if we execut `longestMatch [p1, p2]` in a trailing parser where both `p1` and `p2` succeed, then an incorrect syntax tree is generated by `p2`. The issue is that before executing `p2`, the trailing stack is of the form `#[..., left, syntax-by-p1]` Then, the trailing parser `p2` incorrectly assumes that `syntax-by-p1` was the "left" syntax node. This commit fix this issue by storing the `left` node at the `ParserContext` at `trailingLoop` @Kha This bug was introduced when we unified leading and trailing parsers. I think this is the simplest solution. We can observe the bug before this commit by using ``` set_option syntaxMaxDepth 1000 set_option trace.Elab true ``` at `choiceMacroRules.lean`. It is funny the correct result was produced even with the bug. It was working because the `macro_rules` was matching the buggy syntax with the nested `syntax-by-p1` there :)
This commit is contained in:
parent
8b1cb0fcb8
commit
52c7709cb3
1 changed files with 5 additions and 3 deletions
|
|
@ -145,6 +145,7 @@ instance InputContext.inhabited : Inhabited InputContext :=
|
|||
|
||||
structure ParserContext extends InputContext :=
|
||||
(rbp : Nat)
|
||||
(left : Syntax := Syntax.missing)
|
||||
(env : Environment)
|
||||
(tokens : TokenTable)
|
||||
|
||||
|
|
@ -236,10 +237,10 @@ match s with
|
|||
let stack := stack.push newNode;
|
||||
⟨stack, pos, cache, err⟩
|
||||
|
||||
def mkTrailingNode (s : ParserState) (k : SyntaxNodeKind) (iniStackSz : Nat) : ParserState :=
|
||||
def mkTrailingNode (s : ParserState) (k : SyntaxNodeKind) (left : Syntax) (iniStackSz : Nat) : ParserState :=
|
||||
match s with
|
||||
| ⟨stack, pos, cache, err⟩ =>
|
||||
let newNode := Syntax.node k (stack.extract (iniStackSz - 1) stack.size);
|
||||
let newNode := Syntax.node k (#[left] ++ stack.extract iniStackSz stack.size);
|
||||
let stack := stack.shrink iniStackSz;
|
||||
let stack := stack.push newNode;
|
||||
⟨stack, pos, cache, err⟩
|
||||
|
|
@ -363,7 +364,7 @@ instance hasAndthen : HasAndthen Parser :=
|
|||
| c, s =>
|
||||
let iniSz := s.stackSize;
|
||||
let s := p c s;
|
||||
s.mkTrailingNode n iniSz
|
||||
s.mkTrailingNode n c.left iniSz
|
||||
|
||||
@[noinline] def nodeInfo (n : SyntaxNodeKind) (p : ParserInfo) : ParserInfo :=
|
||||
{ collectTokens := p.collectTokens,
|
||||
|
|
@ -1601,6 +1602,7 @@ partial def trailingLoop (tables : PrattParsingTables) (c : ParserContext) : Par
|
|||
let (s, lbp) := currLbp left c s;
|
||||
if c.rbp ≥ lbp then s
|
||||
else
|
||||
let c := { c with left := s.stxStack.back };
|
||||
let iniSz := s.stackSize;
|
||||
let identAsSymbol := false;
|
||||
let (s, ps) := indexed tables.trailingTable c s identAsSymbol;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue