当表达式无法通过 fpeval 求值时,分支到某个地方

当表达式无法通过 fpeval 求值时,分支到某个地方

我想设计一个\comparator依赖于fpeval具有 3 个分支的可扩展命令:

  • 真枝当比较结果等于 1 时
  • 假枝当比较结果等于零时
  • 无效分支当无法进行比较时(而不是返回编译错误)

这是我当前使用的代码:

\documentclass[preview = true, varwidth = true]{standalone}

\usepackage{xparse}
\usepackage{xfp}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\compare}{r[] m m m m m}{
    \compare_evaluation:eeennn{#1}{#2}{#3}{#4}{#5}{#6}
}
\cs_new:Nn \compare_evaluation:nnnnnn{
    \compare_result:ennn{\fpeval{#2 #1 #3}}{#4}{#5}{#6}
}
\cs_new:Nn \compare_result:nnnn{
    \str_case:nnTF{#1}{
        {0}{#3}
        {1}{#2}
    }{}{#4}
}
\cs_generate_variant:Nn \compare_evaluation:nnnnnn{eeennn}
\cs_generate_variant:Nn \compare_result:nnnn{ennn}
\ExplSyntaxOff

\begin{document}
\begin{tabular}{c}
\compare[<]{1.5}{2.5}{true}{false}{invalid} \\
\compare[<]{2.5}{1.5}{true}{false}{invalid} \\
\compare[<]{xx}{xx}{true}{false}{invalid} \\ % CRASHES
\end{tabular}
\end{document}

当然,测试的最后一行会崩溃。

问题:如何使其可编译并正确分支(此处打印invalid)?

答案1

如果可扩展性不是必需的,则可以使用正则表达式检查语法

在此处输入图片描述

\documentclass[preview = true, varwidth = true]{standalone}

% These only needed in old latex releases
% \usepackage{xparse}
% \usepackage{xfp}

\ExplSyntaxOn
\NewExpandableDocumentCommand{\compare}{r[] m m m m m}{
    \compare_evaluation:eeennn{#1}{#2}{#3}{#4}{#5}{#6}
}
\cs_new:Nn \compare_evaluation:nnnnnn{
  \regex_match:nnTF
  {^[0-9]*(\.[0-9]*)?([eE][0-9]+)?@@@[0-9]*(\.[0-9]*)?([eE][0-9]+)?$}
  {#2@@@#3}
  {
    \compare_result:ennn{\fpeval{#2 #1 #3}}{#4}{#5}{#6}
  }
  {#6}
  }
\cs_new:Nn \compare_result:nnnn{
    \str_case:nnTF{#1}{
        {0}{#3}
        {1}{#2}
    }{}{#4}
}
\cs_generate_variant:Nn \compare_evaluation:nnnnnn{eeennn}
\cs_generate_variant:Nn \compare_result:nnnn{ennn}
\ExplSyntaxOff

\begin{document}
\begin{tabular}{c}
\compare[<]{1.5}{2.5}{true}{false}{invalid} \\
\compare[<]{2.5}{1.5}{true}{false}{invalid} \\
\compare[<]{2.5e2}{15e3}{true}{false}{invalid} \\
\compare[<]{xx}{xx}{true}{false}{invalid} \\ % CRASHES
\end{tabular}
\end{document}

这里我假设@@@可以安全地用作分隔符,您可以分别对两个参数使用正则表达式,或者使用自定义命令 tken,但这显示了基本思想。此外,在极端情况下,正则表达式的语法可能与 l3fp 不完全相同(并且不涵盖 fp 表达式),但可以捕获主要的文字语法。

相关内容