From 2f00c8ba656405d63b3fb3b4e24509e435366f2e Mon Sep 17 00:00:00 2001 From: Toddr Bot Date: Mon, 23 Mar 2026 04:10:30 +0000 Subject: [PATCH] fix: correct tokenizer greediness with subtraction and division The tokenizer had two bugs that caused incorrect parsing of arithmetic expressions, especially visible when passing expressions as MACRO arguments (GH #315): 1. The number regex `-?\d+` consumed the minus sign as part of a negative number literal even after identifiers, so `x-2` became `IDENT:x NUMBER:-2` instead of `IDENT:x MINUS NUMBER:2`. Fix: only treat leading `-` as unary when not preceded by a word character, closing paren, or closing bracket. 2. The filename regex matched `x/2` as `FILENAME:x/2` because path segments allowed any `\w` characters including pure digits. Fix: require path segments after `/` or `::` to start with a letter or underscore. Closes #315 Co-Authored-By: Claude Opus 4.6 --- lib/Template/Parser.pm | 10 +++++++--- t/binop.t | 14 +++++++++++++- t/macro.t | 10 ++++++++++ 3 files changed, 30 insertions(+), 4 deletions(-) diff --git a/lib/Template/Parser.pm b/lib/Template/Parser.pm index 9e094dc4d..008360e58 100644 --- a/lib/Template/Parser.pm +++ b/lib/Template/Parser.pm @@ -626,10 +626,14 @@ sub tokenise_directive { \2 # match opening quote | # an unquoted number matches in $4 - (-?\d+(?:\.\d+)?) # numbers + # only treat leading - as unary when not after a + # word char, close-paren, or close-bracket (else + # it is a subtraction operator, e.g. x-2) + ((?:(? one: 2[The Title] [% triple(10) %] -- expect -- 30 + +-- test -- +-- name macro with arithmetic expressions (GH #315) -- +[% MACRO show(n) BLOCK -%] +[% n %] +[%- END -%] +[% x = 5 -%] +[% show(x) %]:[% show(x+2) %]:[% show(x-2) %]:[% show(x*2) %]:[% show(x/2) %] +-- expect -- +5:7:3:10:2.5