diff options
author | Karl Berry <karl@freefriends.org> | 2022-05-08 20:24:44 +0000 |
---|---|---|
committer | Karl Berry <karl@freefriends.org> | 2022-05-08 20:24:44 +0000 |
commit | 867593c0625cb9ab8cc42f998dabc55a9724cdf2 (patch) | |
tree | 7ec26bebe2acf6b62885653c9d3e2820b9b2211d | |
parent | e980f86aff14b9d5d5f03c6974cad0070d5194e5 (diff) |
simplebnf (8may22)
git-svn-id: svn://tug.org/texlive/trunk@63263 c570f23f-e606-0410-a88d-b1316a301751
-rw-r--r-- | Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.pdf | bin | 133699 -> 152698 bytes | |||
-rw-r--r-- | Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.tex | 64 | ||||
-rw-r--r-- | Master/texmf-dist/tex/latex/simplebnf/simplebnf.sty | 126 |
3 files changed, 160 insertions, 30 deletions
diff --git a/Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.pdf b/Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.pdf Binary files differindex 1285776fe63..fb80c407fb9 100644 --- a/Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.pdf +++ b/Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.pdf diff --git a/Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.tex b/Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.tex index 62d6cba8682..30ea889f18b 100644 --- a/Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.tex +++ b/Master/texmf-dist/doc/latex/simplebnf/simplebnf-doc.tex @@ -8,7 +8,7 @@ \tcbset{listing engine=listings,colframe=black,colback=white,size=small} \NewDocumentEnvironment {exampleside} {} - { \tcblisting{listing side text,righthand width=.5\textwidth} } + { \tcblisting{listing side text,righthand width=.55\textwidth} } { \endtcblisting } \NewDocumentCommand \cmd { m } {\texttt{\textbackslash#1}} @@ -32,10 +32,10 @@ \title{% \textsf{simplebnf} --- A simple package to format Backus-Naur form% - \footnote{This file describes v0.2.0.}} + \footnote{This file describes v0.3.0.}} \author{Jay Lee\footnote{E-mail: % \href{mailto:jaeho.lee@snu.ac.kr}{\texttt{jaeho.lee@snu.ac.kr}}}} -\date{2020/09/01} +\date{2022/05/07} \begin{document} \maketitle @@ -64,6 +64,8 @@ where each of the \textit{rhs} represents alternative syntactic forms of the \te A sample code and the result is shown below: \begin{exampleside} \begin{bnfgrammar} + a \in \textit{Vars} + ;; expr ::= expr + term : sum | term : term @@ -73,4 +75,58 @@ A sample code and the result is shown below: | a : variable \end{bnfgrammar} \end{exampleside} -\end{document}
\ No newline at end of file + +Annotations can also be provided on left-hand sides, to label the nonterminal instead of a specific production. +\begin{exampleside} + \begin{bnfgrammar} + a : Variables \in \textit{Vars} + ;; + expr : Expressions ::= + expr + term + | term + ;; + term ::= + term * a + | a + \end{bnfgrammar} +\end{exampleside} + +You can also provide an optional specification to the grammar environment, to redefine alignment or spacing. +\begin{tcblisting}{text above listing} + \begin{bnfgrammar}[lr@{\hspace{4pt}}c@{\hspace{2pt}}ll] + a : Variables \in \textit{Vars} + ;; + expr ::= + expr + term : sum + | term : term + ;; + term ::= + term * a : product + | a : variable + \end{bnfgrammar} +\end{tcblisting} + +If you want to typeset multiple productions on a single line, you can use double vertical bars by default. +\begin{exampleside} + \begin{bnfgrammar} + a \in \textit{Vars} + ;; + expr ::= expr + term || term + ;; + term ::= term * a || a + \end{bnfgrammar} +\end{exampleside} + +The second and third optional arguments specify regular expressions for the line-breaking and non-breaking RHS seperators: +\begin{tcblisting}{text above listing} + \begin{bnfgrammar}[llcll][\|\|][\|] + a \in \textit{Vars} + ;; + expr ::= expr + term | term + ;; + term ::= term * a + || a + \end{bnfgrammar} +\end{tcblisting} + +\end{document} diff --git a/Master/texmf-dist/tex/latex/simplebnf/simplebnf.sty b/Master/texmf-dist/tex/latex/simplebnf/simplebnf.sty index a8ae5230366..fd7b707ff79 100644 --- a/Master/texmf-dist/tex/latex/simplebnf/simplebnf.sty +++ b/Master/texmf-dist/tex/latex/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} } |