可以用什么方式用纯 TeX 或无包 LaTeX 编写解析器?

可以用什么方式用纯 TeX 或无包 LaTeX 编写解析器?

我想将自己的文档类编写为一个文学程序,并尽可能少地使用依赖树,作为测试我的能力的练习。

我通过分解参数实现了稳定的 foreach 循环,但同样尝试解析日历失败。

\def\@pointer{\@pointer}
\long\def\@iterate#1#2#3,{
    \def\cell{#3}
    \ifx\cell\@pointer
        \let\next=\relax
    \else
        \def#1{#3}
        #2
        \def\next{\@iterate{#1}{#2}}
    \fi
    \next
}
\long\gdef\foreach#1in#2#3%
{\@iterate{#1}{#3}#2,\@pointer,}

\def\@testOccidental#1 #2, #3{
    \def\subject{#1}
    \foreach \month in {January,February,March,April,May,June,July,August,October,September,November,December}{
        \ifx\subject\month
            #1 #2, #3 (Occidental Solar)
        \fi
    }
}
\def\checkCalendar#1{
    \def\subject{#1}
    \@testOccidental\subject
}

\checkCalendar{\today}

答案1

问题标题提出了一个无法回答的问题,关于如何(一般来说)编写解析器,但仅限于发布的代码

\catcode`\@=11

\def\@pointer{\@pointer}
\long\def\@iterate#1#2#3,{
    \def\cell{#3}
    \ifx\cell\@pointer
        \let\next=\relax
    \else
        \def#1{#3}
        #2
        \def\next{\@iterate{#1}{#2}}
    \fi
    \next
}



\long\gdef\foreach#1in#2#3%
{\@iterate{#1}{#3}#2,\@pointer,}

X\foreach \z in {a,b,c,d}{[\z]}X

\bye

循环有效,但会给输出增加很多空间

在此处输入图片描述

从定义过程中删除空格标记

在此处输入图片描述

\catcode`\@=11

\def\@pointer{\@pointer}
\long\def\@iterate#1#2#3,{%
    \def\cell{#3}%
    \ifx\cell\@pointer
        \let\next=\relax
    \else
        \def#1{#3}%
        #2%
        \def\next{\@iterate{#1}{#2}}%
    \fi
    \next
}



\long\gdef\foreach#1in#2#3%
{\@iterate{#1}{#3}#2,\@pointer,}

X\foreach \z in {a,b,c,d}{[\z]}X

\bye

猜测日历示例的意图更加困难。

\def\@testOccidental#1 #2, #3{

定义一个接受三个参数的命令,第一个参数由空格分隔,第二个参数由逗号和空格分隔,第三个参数为未分隔的{..}参数。

您只能在一个地方使用它,因为\@testOccidental\subject 那里只有一个标记并且没有空格或逗号分隔符。由 so\subject定义始终为 false,(并且对于循环变量来说是一个坏名称,因为它是当前月份数字的 TeX 原语)\def\subject{\today}\ifx\subject\month\month

尝试猜测几个月来循环的目的,也许是这样的:

在此处输入图片描述

\catcode`\@=11

\def\@pointer{\@pointer}
\long\def\@iterate#1#2#3,{%
    \def\cell{#3}%
    \ifx\cell\@pointer
        \let\next=\relax
    \else
        \def#1{#3}%
        #2%
        \def\next{\@iterate{#1}{#2}}%
    \fi
    \next
}



\long\gdef\foreach#1in#2#3%
{\@iterate{#1}{#3}#2,\@pointer,}

X\foreach \z in {a,b,c,d}{[\z]}X






\def\@testOccidental#1 #2, #3\relax{%
    \def\subject{#1}%
    \foreach \xmonth in {January,February,March,April,May,June,July,August,October,September,November,December}{%
        \ifx\subject\xmonth
            #1 #2, #3 (Occidental Solar)\par
        \else
             not \xmonth\par % just for debugging
        \fi
    }%
}
\def\checkCalendar#1{%
    \@testOccidental#1\relax
}

\checkCalendar{June 7, 2019}

\bye

相关内容