使用 ConTeXt BNF 模块

使用 ConTeXt BNF 模块

我想用 ConTeXt 编写 BNF 规则。我发现这个 BNF 模块并尝试加载它:

\usemodule[bnf]

然而,在加载时,ConTeXt 出现以下错误:

tex error       > tex error on line 157 in file /usr/local/texlive/2016/texmf-dist/tex/context/third/bnf/t-bnf.tex: ! Undefined control sequence

<argument> \c!terminalstart
                 =\tttf
\syst_helpers_process_comma_item #1,#2->\if ,#1
                                               ,\expandafter \syst_helpers_p...
<argument> \c!terminalstart =\tttf , \c!terminalstop
                                          =, \c!nonterminalstart =\mathematics
\syst_helpers_get_parameters ...cess_comma_item #1
                                                  ,],\_e_o_p_
l.157    \c!indentnext=\v!no]


147     \def\setupbnfgrammar%
148       {\dosingleargument\dosetupbnfgrammar}
149
150     \setupbnfgrammar
151       [\c!terminalstart=\tttf,
152        \c!terminalstop=,
153        \c!nonterminalstart=\mathematics{\langle},
154        \c!nonterminalstop=\mathematics{\rangle},
155        \c!is={ \mathematics{\longrightarrow}},
156        \c!option=\mathematics{\vert},
157 >>     \c!indentnext=\v!no]
158
159     %D \macros
160     %D   {BNF}
161     %D
162     %D We also define a useful abbreviation to be used for header texts and labels.
163
164     \logo[BNF]{bnf}
165
166     %D And we use it here:
167

我认为发生这种情况是因为 BNF 模块是为旧版本的 ConTeXt 编写的。有办法解决这个问题吗?

答案1

看起来这个模块是为 MKII 制作的。您可以通过重写几个宏来使其与 MKIV 配合使用。该模块完全损坏,因为它甚至不能与 MKII 配合使用。

% Missing constants
\setinterfaceconstant{terminalstart}{terminalstart}
\setinterfaceconstant{terminalstop}{terminalstop}
\setinterfaceconstant{nonterminalstart}{nonterminalstart}
\setinterfaceconstant{nonterminalstop}{nonterminalstop}
\setinterfaceconstant{is}{is}
% Missing variables
\setinterfacevariable{bnfgrammar}{bnfgrammar}
\setinterfacevariable{bnfgrammars}{bnfgrammars}

\usemodule[bnf]

\unprotect

\bgroup

\catcode`:\activecatcode
\catcode`|\activecatcode
\catcode`"\activecatcode
\catcode`'\activecatcode

\gdef:{\@@bnfis}
\gdef|{\@@bnfoption}
\gdef"{\thinspace\bgroup\@@bnfterminalstart\tt%
      \def"{\@@bnfterminalstop\egroup\thinspace}}
\gdef'{\thinspace\bgroup\@@bnfterminalstart\tt%
      \def'{\@@bnfterminalstop\egroup\thinspace}}

\egroup

\def\complexstartbnfgrammar[#1]%
  {\endgraf\nobreak\medskip
   \begingroup
   \setupbnfgrammar[#1]%
   \chardef\bnfsinglequote=`'
   \catcode`:\activecatcode
   \catcode`|\activecatcode
   \catcode`"\activecatcode
   \catcode`'\activecatcode
   \catcode`<=13
   \let\par=\bnfgrammarline
   \obeylines}

\protect

\starttext

\startplacebnfgrammar[title={An example of a placed grammar.}]
  \startbnfgrammar
    <exp>: <num> | <num> "+" <num>
    <num>: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
  \stopbnfgrammar
\stopplacebnfgrammar

\stoptext

在此处输入图片描述

这是我将模块移植到 MKIV 的卑微尝试。

\startmodule [bnf-mkiv]
\unprotect

\startinterface all
  \setinterfaceconstant {terminalstart}    {terminalstart}
  \setinterfaceconstant {terminalstop}     {terminalstop}
  \setinterfaceconstant {nonterminalstart} {nonterminalstart}
  \setinterfaceconstant {nonterminalstop}  {nonterminalstop}
  \setinterfaceconstant {is}               {is}
  \setinterfacevariable {bnfgrammar}       {bnfgrammar}
  \setinterfacevariable {bnfgrammars}      {bnfgrammars}
\stopinterface

\installnamespace{bnfgrammar}

\installcommandhandler \????bnfgrammar {bnfgrammar} \????bnfgrammar

\unexpanded\def\bnf_grammar_non_terminal#1>%
  {\bnfgrammarparameter{\c!nonterminalstart}#1\/\bnfgrammarparameter{\c!nonterminalstop}}

\bgroup

\catcode`:\activecatcode
\unexpanded\gdef:{\bnfgrammarparameter{\c!is}}

\catcode`|\activecatcode
\unexpanded\gdef|{\bnfgrammarparameter{\c!option}}

\catcode`"\activecatcode
\unexpanded\gdef"%
  {\thinspace\bgroup\bnfgrammarparameter{\c!terminalstart}%
   \unexpanded\def"{\bnfgrammarparameter{\c!terminalstop}\egroup\thinspace}}

\catcode`'\activecatcode
\unexpanded\gdef'%
  {\thinspace\bgroup\bnfgrammarparameter{\c!terminalstart}%
   \unexpanded\def'{\bnfgrammarparameter{\c!terminalstop}\egroup\thinspace}}

\catcode`<\activecatcode
\global\let<=\bnf_grammar_non_terminal

\unexpanded\gdef\bnf_grammar_rule<#1>{\endgraf<#1>}

\egroup

\unexpanded\def\bnf_grammar_line
  {\futurelet\next\bnf_grammar_switch}

\unexpanded\def\bnf_grammar_cont
  {\endgraf\qquad}

\unexpanded\def\bnf_grammar_switch
  {\ifx\next\bnf_grammar_non_terminal
    \let\next=\bnf_grammar_rule
  \else\expandafter\ifx\expandafter\next\csname stop\currentbnfgrammar\endcsname
    \let\next=\relax
  \else
    \let\next=\bnf_grammar_cont
    \fi\fi
  \next}

\unexpanded\def\bnf_grammar_start%
  {\dodoubleempty\bnf_grammar_start_indeed}

\unexpanded\def\bnf_grammar_start_indeed[#1][#2]%
  {\begingroup
   \edef\currentbnfgrammar{#1}
   \setupcurrentbnfgrammar[#2]
   \catcode`:\activecatcode
   \catcode`|\activecatcode
   \catcode`"\activecatcode
   \catcode`'\activecatcode
   \catcode`<\activecatcode
   \let\par=\bnf_grammar_line
   \obeylines}

\unexpanded\def\bnf_grammar_stop
  {\endgroup
   \blank
   \checknextindentation[\bnfgrammarparameter{\c!indentnext}]}

\appendtoks
   \setuevalue{start\currentbnfgrammar}{\bnf_grammar_start[\currentbnfgrammar]}%
   \setuevalue{stop\currentbnfgrammar}{\bnf_grammar_stop}%
\to \everydefinebnfgrammar

\setupbnfgrammar
  [\c!terminalstart=\tttf,
   \c!terminalstop=,
   \c!nonterminalstart=\mathematics{\langle},
   \c!nonterminalstop=\mathematics{\rangle},
   \c!is={ \mathematics{\longrightarrow}},
   \c!option=\mathematics{\vert},
   \c!indentnext=\v!no]

\definebnfgrammar
  [\v!bnfgrammar]

\logo[BNF]{BNF}
\setuplabeltext[\s!en][\v!bnfgrammar=\BNF\ Grammar ]

\definefloat
  [\v!bnfgrammar]
  [\v!bnfgrammars]

\protect
\stopmodule

例子:

\usemodule[bnf-mkiv]

\starttext

\startplacebnfgrammar[title={An example of a placed grammar.}]
  \startbnfgrammar[] % <-- empty brackets are important
    <exp>: <num> | <num> "+" <num>
    <num>: "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
  \stopbnfgrammar
\stopplacebnfgrammar

\stoptext

在此处输入图片描述

相关内容