From 754e1788b2c690a5520d34b967cae31fb44726b9 Mon Sep 17 00:00:00 2001 From: Carson McManus Date: Mon, 18 Dec 2023 06:33:29 -0500 Subject: [PATCH] Fix a parser bug causing `x.)` to be treated as a field access (#2962) --- crates/typst-syntax/src/parser.rs | 17 +++++++++-------- tests/ref/bugs/2044-invalid-parsed-ident.png | Bin 0 -> 603 bytes tests/typ/bugs/2044-invalid-parsed-ident.typ | 6 ++++++ 3 files changed, 15 insertions(+), 8 deletions(-) create mode 100644 tests/ref/bugs/2044-invalid-parsed-ident.png create mode 100644 tests/typ/bugs/2044-invalid-parsed-ident.typ diff --git a/crates/typst-syntax/src/parser.rs b/crates/typst-syntax/src/parser.rs index 11bb4e8d9..1d8875ddd 100644 --- a/crates/typst-syntax/src/parser.rs +++ b/crates/typst-syntax/src/parser.rs @@ -4,7 +4,7 @@ use std::ops::Range; use ecow::{eco_format, EcoString}; use unicode_math_class::MathClass; -use crate::{ast, is_newline, LexMode, Lexer, SyntaxKind, SyntaxNode}; +use crate::{ast, is_ident, is_newline, LexMode, Lexer, SyntaxKind, SyntaxNode}; /// Parse a source file. #[tracing::instrument(skip_all)] @@ -258,13 +258,14 @@ fn math_expr_prec(p: &mut Parser, min_prec: usize, stop: SyntaxKind) { SyntaxKind::MathIdent => { continuable = true; p.eat(); - while p.directly_at(SyntaxKind::Text) - && p.current_text() == "." - && matches!( - p.lexer.clone().next(), - SyntaxKind::MathIdent | SyntaxKind::Text - ) - { + while p.directly_at(SyntaxKind::Text) && p.current_text() == "." && { + let mut copy = p.lexer.clone(); + let start = copy.cursor(); + let next = copy.next(); + let end = copy.cursor(); + matches!(next, SyntaxKind::MathIdent | SyntaxKind::Text) + && is_ident(&p.text[start..end]) + } { p.convert(SyntaxKind::Dot); p.convert(SyntaxKind::Ident); p.wrap(m, SyntaxKind::FieldAccess); diff --git a/tests/ref/bugs/2044-invalid-parsed-ident.png b/tests/ref/bugs/2044-invalid-parsed-ident.png new file mode 100644 index 0000000000000000000000000000000000000000..327150e788177af723a5428be1827f6b5fb988f5 GIT binary patch literal 603 zcmeAS@N?(olHy`uVBq!ia0y~yU}OQZy*PjbLxo#u9RmZClBbJfNX4zUxBWdXC(0Zz zlq}_3P z_~*?5jp%fxHwRa&?YQ_aakjv(_Z7|>+miI1uDj=Rtk;X`5jZ04bUwIR@Se#N8^u32 zrf(EUd{v5H`0# zO(MoFRBYjk{1$KjgxoWBEp2BFq}vqlJ4CkZ4t>ACl7DONHARsy*9H1~w);+Q;y8ZI z!H^@q_WBy<6MEhUW}3XY=NZ}JpuES1f3NnjHO>jYEi;;;P2(3#II}}3<|fBe%x`#usyy4>(*E3~zaMR|D2;Ij9Qp0oOjIHB>wPvU_VED@i)a13%_{58843O zJheDkFJNZbH<_^`d79qZ?O|3Gtccr`hi0#)uFt g+uFaukSP1jJ8R2H-?hIr96+hY)78&qol`;+03Wgi5dZ)H literal 0 HcmV?d00001 diff --git a/tests/typ/bugs/2044-invalid-parsed-ident.typ b/tests/typ/bugs/2044-invalid-parsed-ident.typ new file mode 100644 index 000000000..5e4b560ca --- /dev/null +++ b/tests/typ/bugs/2044-invalid-parsed-ident.typ @@ -0,0 +1,6 @@ +// In this bug, the dot at the end was causing the right parenthesis to be +// parsed as an identifier instead of the closing right parenthesis. +// Issue: https://github.com/typst/typst/issues/2044 + +$floor(phi.alt.)$ +$floor(phi.alt. )$