From fe29944c3d5256062708e9b1ae62dc378f9d9993 Mon Sep 17 00:00:00 2001 From: Norbert Preining Date: Mon, 9 May 2022 03:01:47 +0000 Subject: CTAN sync 202205090301 --- macros/latex/contrib/simplebnf/simplebnf.sty | 126 +++++++++++++++++++++------ 1 file changed, 100 insertions(+), 26 deletions(-) (limited to 'macros/latex/contrib/simplebnf/simplebnf.sty') diff --git a/macros/latex/contrib/simplebnf/simplebnf.sty b/macros/latex/contrib/simplebnf/simplebnf.sty index a8ae523036..fd7b707ff7 100644 --- a/macros/latex/contrib/simplebnf/simplebnf.sty +++ b/macros/latex/contrib/simplebnf/simplebnf.sty @@ -13,11 +13,13 @@ \RequirePackage{mathtools} \ProvidesExplPackage {simplebnf} - {2020/09/01} - {0.2.0} + {2022/05/07} + {0.3.0} {A simple package to format Backus–Naur form} -\cs_generate_variant:Nn \seq_set_split:Nnn {NVn} +\cs_generate_variant:Nn \regex_split:nnNTF {nVNTF} +\cs_generate_variant:Nn \regex_split:NnN {NVN} + \tl_new:N \g__simplebnf_defeq_tl \tl_gset:Nn \g__simplebnf_defeq_tl { \ensuremath{\Coloneqq} } @@ -32,6 +34,9 @@ \seq_new:N \l__keypairs_seq \bool_new:N \l__first_rhs +\regex_new:N \g_simplebnf_rhs_newline_r +\regex_new:N \g_simplebnf_rhs_nb_r + %% Typeset a single rhs of a production. %% \l__first_rhs = true => `::=' already typeset %% \l__first_rhs = false => move to a newline and typeset `|' @@ -43,15 +48,18 @@ \bool_set_false:N \l__first_rhs } { - \tl_put_right:Nn \l__table_tl { \\ & \g__simplebnf_defor_tl & } + \tl_put_right:Nn \l__table_tl { \\ && \g__simplebnf_defor_tl & } } - \regex_split:nnNTF { : } { #1 } \l_tmpa_seq + \tl_set:Nn \l_tmpa_tl { #1 } + \regex_replace_once:nnN { ^\s+ } {} \l_tmpa_tl + \regex_replace_once:nnN { \s+$ } {} \l_tmpa_tl + \regex_split:nVNTF { : } \l_tmpa_tl \l_tmpa_seq { \seq_pop_left:NNT \l_tmpa_seq \l_tmpa_tl { - \tl_set:Nx \l_tmpa_tl { \bnfexpr { \l_tmpa_tl } } - \tl_put_right:NV \l__table_tl \l_tmpa_tl + \regex_replace_all:NnN \g_simplebnf_rhs_nb_r { \c{g__simplebnf_defor_tl} } \l_tmpa_tl + \tl_put_right:Nx \l__table_tl { \bnfexpr { \l_tmpa_tl } } } \tl_put_right:Nn \l__table_tl { & } @@ -63,34 +71,67 @@ } } { - \tl_put_right:Nn \l__table_tl { \bnfexpr { #1 } &} + \regex_replace_all:NnN \g_simplebnf_rhs_nb_r { \c{g__simplebnf_defor_tl} } \l_tmpa_tl + + \tl_put_right:Nx \l__table_tl { \bnfexpr { \l_tmpa_tl } } + \tl_put_right:Nn \l__table_tl { & } + } +} + +%% Typeset a single lhs of a production. +%% #1 - lhs : either term or (term : annotation) +\cs_new:Nn \simplebnf_typeset_lhs:n +{ + \tl_set:Nx \l_tmpa_tl { #1 } + \regex_replace_once:nnN { ^\s+ } {} \l_tmpa_tl + \regex_replace_once:nnN { \s+$ } {} \l_tmpa_tl + + \regex_split:nVNTF { : } \l_tmpa_tl \l_tmpa_seq + { + \seq_pop_right:NN \l_tmpa_seq \l_tmpa_tl + \tl_put_right:Nx \l__table_tl + { + \bnfannot{\l_tmpa_tl} + } + \seq_pop_left:NN \l_tmpa_seq \l_tmpa_tl + \tl_put_right:Nx \l__table_tl + { + & \bnfexpr { \l_tmpa_tl } + } + } + { + \tl_put_right:Nx \l__table_tl + { + & \bnfexpr { \l_tmpa_tl } + } } } \NewDocumentCommand \bnfexpr { m } { \texttt { #1 } } \NewDocumentCommand \bnfannot { m } { \textit{ #1 } } -\NewDocumentEnvironment { bnfgrammar } { +b } +%% Typeset a BNF grammar. +%% #1 - tabular specification (llcll) +%% #2 - regexp for newline separator for rhses +%% #2 - regexp for non-breaking separator for rhses +%% #3 - grammar +\NewDocumentEnvironment { bnfgrammar } { O{llcll} O{[^\|]\|[^\|]} O{\|\|} +b } { + \regex_gset:Nn \g_simplebnf_rhs_newline_r { #2 } + \regex_gset:Nn \g_simplebnf_rhs_nb_r { #3 } + %% \l__input_seq is a list of term definitions. - \regex_split:nnN { ;; } { #1 } \l__input_seq + \regex_split:nnN { ;; } { #4 } \l__input_seq \begin{center} \tl_set:Nn \l__table_tl { - \begin{tabular}{lcll} + \begin{tabular}{#1} } + \bool_set_true:N \l_tmp_first_term % Is this the first term in this grammar? \seq_map_inline:Nn \l__input_seq { - %% \l__term_seq - (term, rhses)... - %% \l__term_tl - term - %% \l__keypairs_tl - rhses - \regex_split:nnN { ::= } { ##1 } \l__term_seq - \seq_pop_left:NN \l__term_seq \l__term_tl - \seq_pop_left:NN \l__term_seq \l__keypairs_tl - - \regex_replace_once:nnN { ^\s+ } {} \l__term_tl - + %% If not-first, add newline \bool_if:NTF \l_tmp_first_term { \bool_set_false:N \l_tmp_first_term @@ -98,15 +139,48 @@ { \tl_put_right:Nn \l__table_tl { \\ } } - \tl_put_right:Nx \l__table_tl + + \regex_split:nnNTF { ::= } { ##1 } \l__term_seq + % Parse a ::= definition { - \bnfexpr { \l__term_tl } & \g__simplebnf_defeq_tl & + %% \l__term_seq - (lhs, rhses)... + %% \l__term_tl - lhs + %% \l__keypairs_tl - rhses + \seq_pop_left:NN \l__term_seq \l__term_tl + \seq_pop_left:NN \l__term_seq \l__keypairs_tl + + \simplebnf_typeset_lhs:n{\l__term_tl} + \tl_put_right:Nx \l__table_tl + { + & \g__simplebnf_defeq_tl & + } + %% \l__keypairs_seq - (rhs:annot | rhs)... + \regex_split:NVN \g_simplebnf_rhs_newline_r \l__keypairs_tl \l__keypairs_seq + + \bool_set_true:N \l__first_rhs + \seq_map_function:NN \l__keypairs_seq \simplebnf_typeset_rhs:n } - %% \l__keypairs_seq - (rhs:annot | rhs)... - \seq_set_split:NnV \l__keypairs_seq { | } \l__keypairs_tl + { + % Else, parse a \in declaration + \regex_split:nnNTF { \c{in} } { ##1 } \l__term_seq + { + %% \l__term_seq - (lhs, rhs) + \seq_pop_left:NN \l__term_seq \l_tmpa_tl - \bool_set_true:N \l__first_rhs - \seq_map_function:NN \l__keypairs_seq \simplebnf_typeset_rhs:n + \simplebnf_typeset_lhs:n{\l_tmpa_tl} + \tl_put_right:Nn \l__table_tl + { + & $\in$ & $ + } + \seq_pop_left:NN \l__term_seq \l_tmpa_tl + \tl_put_right:NV \l__table_tl \l_tmpa_tl + \tl_put_right:Nn \l__table_tl + { + $ & + } + } + { \msg_error:nn {simplebnf} { Could not parser ##1 } } + } } \tl_put_right:Nn \l__table_tl { \end{tabular} } -- cgit v1.2.3