From 2fe51f68b9b718c29473d59374e280deed8665e5 Mon Sep 17 00:00:00 2001 From: schwarze Date: Thu, 6 Jul 2017 00:08:52 +0000 Subject: [PATCH] Fix operator precedence according to Brian W. Kernighan and Lorinda L. Cherry, "Typesetting Mathematics - User's Guide (Second Edition)", August 15, 1978, paragraph 23; swarm of bugs pointed out by bentley@. --- regress/usr.bin/mandoc/eqn/fromto/Makefile | 6 ++-- .../usr.bin/mandoc/eqn/fromto/precedence.in | 15 +++++++++ .../mandoc/eqn/fromto/precedence.out_ascii | 9 ++++++ .../mandoc/eqn/fromto/precedence.out_html | 1 + regress/usr.bin/mandoc/eqn/over/precedence.in | 7 +++-- .../mandoc/eqn/over/precedence.out_ascii | 5 +-- .../mandoc/eqn/over/precedence.out_html | 2 +- regress/usr.bin/mandoc/eqn/subsup/Makefile | 6 ++-- .../usr.bin/mandoc/eqn/subsup/precedence.in | 14 +++++++++ .../mandoc/eqn/subsup/precedence.out_ascii | 9 ++++++ .../mandoc/eqn/subsup/precedence.out_html | 1 + regress/usr.bin/mandoc/eqn/unary/bold.in | 6 ++-- .../usr.bin/mandoc/eqn/unary/bold.out_ascii | 4 +-- .../usr.bin/mandoc/eqn/unary/bold.out_html | 2 +- regress/usr.bin/mandoc/eqn/unary/diacrit.in | 5 +-- .../mandoc/eqn/unary/diacrit.out_ascii | 4 +-- .../usr.bin/mandoc/eqn/unary/diacrit.out_html | 2 +- regress/usr.bin/mandoc/eqn/unary/sqrt.in | 6 ++-- .../usr.bin/mandoc/eqn/unary/sqrt.out_ascii | 5 +-- .../usr.bin/mandoc/eqn/unary/sqrt.out_html | 2 +- usr.bin/mandoc/eqn.c | 31 ++++++++++++------- usr.bin/mandoc/eqn_term.c | 19 ++++++------ 22 files changed, 111 insertions(+), 50 deletions(-) create mode 100644 regress/usr.bin/mandoc/eqn/fromto/precedence.in create mode 100644 regress/usr.bin/mandoc/eqn/fromto/precedence.out_ascii create mode 100644 regress/usr.bin/mandoc/eqn/fromto/precedence.out_html create mode 100644 regress/usr.bin/mandoc/eqn/subsup/precedence.in create mode 100644 regress/usr.bin/mandoc/eqn/subsup/precedence.out_ascii create mode 100644 regress/usr.bin/mandoc/eqn/subsup/precedence.out_html diff --git a/regress/usr.bin/mandoc/eqn/fromto/Makefile b/regress/usr.bin/mandoc/eqn/fromto/Makefile index a2012e8f932..1384c543153 100644 --- a/regress/usr.bin/mandoc/eqn/fromto/Makefile +++ b/regress/usr.bin/mandoc/eqn/fromto/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.2 2015/01/01 15:34:43 schwarze Exp $ +# $OpenBSD: Makefile,v 1.3 2017/07/06 00:08:52 schwarze Exp $ -REGRESS_TARGETS = basic noarg -HTML_TARGETS = basic noarg +REGRESS_TARGETS = basic noarg precedence +HTML_TARGETS = basic noarg precedence .include diff --git a/regress/usr.bin/mandoc/eqn/fromto/precedence.in b/regress/usr.bin/mandoc/eqn/fromto/precedence.in new file mode 100644 index 00000000000..939ab51a9ff --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/fromto/precedence.in @@ -0,0 +1,15 @@ +.\" $OpenBSD: precedence.in,v 1.1 2017/07/06 00:08:52 schwarze Exp $ +.Dd $Mdocdate: July 6 2017 $ +.Dt SUBSUP-PRECEDENCE 1 +.Os +.Sh NAME +.Nm subsup-precedence +.Nd precedence of subscripts and superscripts +.Sh DESCRIPTION +.ps 36 +initial text +.EQ +X from a under to c hat ; roman X from bold a to italic c ; +X sub 1 sup 2 from a sub c sup e to o sub r sup s +.EN +final text diff --git a/regress/usr.bin/mandoc/eqn/fromto/precedence.out_ascii b/regress/usr.bin/mandoc/eqn/fromto/precedence.out_ascii new file mode 100644 index 00000000000..23f3ca4a5d4 --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/fromto/precedence.out_ascii @@ -0,0 +1,9 @@ +SUBSUP-PRECEDENCE(1) General Commands Manual SUBSUP-PRECEDENCE(1) + +NNAAMMEE + ssuubbssuupp--pprreecceeddeennccee - precedence of subscripts and superscripts + +DDEESSCCRRIIPPTTIIOONN + initial text _X__a_^_c^ ; X_aa^_c ; _X_1^2__a__c^_e^_o__r^_s final text + +OpenBSD July 5, 2017 OpenBSD diff --git a/regress/usr.bin/mandoc/eqn/fromto/precedence.out_html b/regress/usr.bin/mandoc/eqn/fromto/precedence.out_html new file mode 100644 index 00000000000..bb9074e64b5 --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/fromto/precedence.out_html @@ -0,0 +1 @@ +Xa_c^;Xac;X12aceors diff --git a/regress/usr.bin/mandoc/eqn/over/precedence.in b/regress/usr.bin/mandoc/eqn/over/precedence.in index 3bc0e7fc86a..12b28cef4ea 100644 --- a/regress/usr.bin/mandoc/eqn/over/precedence.in +++ b/regress/usr.bin/mandoc/eqn/over/precedence.in @@ -1,5 +1,5 @@ -.\" $OpenBSD: precedence.in,v 1.2 2017/07/04 14:53:23 schwarze Exp $ -.Dd $Mdocdate: July 4 2017 $ +.\" $OpenBSD: precedence.in,v 1.3 2017/07/06 00:08:52 schwarze Exp $ +.Dd $Mdocdate: July 6 2017 $ .Dt OVER-PRECEDENCE 1 .Os .Sh NAME @@ -8,6 +8,7 @@ .Sh DESCRIPTION initial text .EQ -1 + x + x sup 2 over 2 + x sup 3 over { 2 * 3 } +1 + x + x sup 2 over 2 + x sup 3 over { 2 * 3 } ; +a hat over c tilde ; bold a over bold c ; sqrt a over sqrt c .EN final text diff --git a/regress/usr.bin/mandoc/eqn/over/precedence.out_ascii b/regress/usr.bin/mandoc/eqn/over/precedence.out_ascii index 92529bb4340..a9a9684a36b 100644 --- a/regress/usr.bin/mandoc/eqn/over/precedence.out_ascii +++ b/regress/usr.bin/mandoc/eqn/over/precedence.out_ascii @@ -4,6 +4,7 @@ NNAAMMEE oovveerr--pprreecceeddeennccee - precedence of the fraction operator DDEESSCCRRIIPPTTIIOONN - initial text 1 + _x + _x^2/2 + _x^3/(2 * 3) final text + initial text 1 + _x + _x^2/2 + _x^3/(2 * 3) ; _a^/_c~ ; aa/cc ; sqrt(_a)/sqrt(_c) + final text -OpenBSD July 4, 2017 OpenBSD +OpenBSD July 5, 2017 OpenBSD diff --git a/regress/usr.bin/mandoc/eqn/over/precedence.out_html b/regress/usr.bin/mandoc/eqn/over/precedence.out_html index b7c4f36d526..52e45eb557f 100644 --- a/regress/usr.bin/mandoc/eqn/over/precedence.out_html +++ b/regress/usr.bin/mandoc/eqn/over/precedence.out_html @@ -1 +1 @@ -1+x+x22+x32*3 +1+x+x22+x32*3;a^c~;ac;ac diff --git a/regress/usr.bin/mandoc/eqn/subsup/Makefile b/regress/usr.bin/mandoc/eqn/subsup/Makefile index 4e11b33d5c5..a780104630e 100644 --- a/regress/usr.bin/mandoc/eqn/subsup/Makefile +++ b/regress/usr.bin/mandoc/eqn/subsup/Makefile @@ -1,6 +1,6 @@ -# $OpenBSD: Makefile,v 1.2 2015/01/01 15:34:43 schwarze Exp $ +# $OpenBSD: Makefile,v 1.3 2017/07/06 00:08:52 schwarze Exp $ -REGRESS_TARGETS = combine noarg sub_group -HTML_TARGETS = combine noarg sub_group +REGRESS_TARGETS = combine noarg precedence sub_group +HTML_TARGETS = combine noarg precedence sub_group .include diff --git a/regress/usr.bin/mandoc/eqn/subsup/precedence.in b/regress/usr.bin/mandoc/eqn/subsup/precedence.in new file mode 100644 index 00000000000..d184fc07088 --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/subsup/precedence.in @@ -0,0 +1,14 @@ +.\" $OpenBSD: precedence.in,v 1.1 2017/07/06 00:08:52 schwarze Exp $ +.Dd $Mdocdate: July 6 2017 $ +.Dt SUBSUP-PRECEDENCE 1 +.Os +.Sh NAME +.Nm subsup-precedence +.Nd precedence of subscripts and superscripts +.Sh DESCRIPTION +initial text +.EQ +x hat sub 1 under sup 2 bar + e tilde sup x hat sub s dyad ; +roman I sub bold I sup italic I + roman I sup bold I sub italic I +.EN +final text diff --git a/regress/usr.bin/mandoc/eqn/subsup/precedence.out_ascii b/regress/usr.bin/mandoc/eqn/subsup/precedence.out_ascii new file mode 100644 index 00000000000..b5b7f6c2d5a --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/subsup/precedence.out_ascii @@ -0,0 +1,9 @@ +SUBSUP-PRECEDENCE(1) General Commands Manual SUBSUP-PRECEDENCE(1) + +NNAAMMEE + ssuubbssuupp--pprreecceeddeennccee - precedence of subscripts and superscripts + +DDEESSCCRRIIPPTTIIOONN + initial text _x^_1_^2 + _e~^_x^__s<-> ; I_II^_I + I^II__I final text + +OpenBSD July 5, 2017 OpenBSD diff --git a/regress/usr.bin/mandoc/eqn/subsup/precedence.out_html b/regress/usr.bin/mandoc/eqn/subsup/precedence.out_html new file mode 100644 index 00000000000..1cad9ce2d94 --- /dev/null +++ b/regress/usr.bin/mandoc/eqn/subsup/precedence.out_html @@ -0,0 +1 @@ +x^1_2+e~x^s;III+III diff --git a/regress/usr.bin/mandoc/eqn/unary/bold.in b/regress/usr.bin/mandoc/eqn/unary/bold.in index ad098a83065..e77398f46e9 100644 --- a/regress/usr.bin/mandoc/eqn/unary/bold.in +++ b/regress/usr.bin/mandoc/eqn/unary/bold.in @@ -1,5 +1,5 @@ -.\" $OpenBSD: bold.in,v 1.2 2017/07/04 14:53:23 schwarze Exp $ -.Dd $Mdocdate: July 4 2017 $ +.\" $OpenBSD: bold.in,v 1.3 2017/07/06 00:08:52 schwarze Exp $ +.Dd $Mdocdate: July 6 2017 $ .Dt UNARY-BOLD 1 .Os .Sh NAME @@ -8,6 +8,6 @@ .Sh DESCRIPTION initial text .EQ -bold { sin "sin" } +bold { sin "sin" } "text" bold x hat .EN final text diff --git a/regress/usr.bin/mandoc/eqn/unary/bold.out_ascii b/regress/usr.bin/mandoc/eqn/unary/bold.out_ascii index c20dc638a6b..a40528fc0ad 100644 --- a/regress/usr.bin/mandoc/eqn/unary/bold.out_ascii +++ b/regress/usr.bin/mandoc/eqn/unary/bold.out_ascii @@ -4,6 +4,6 @@ NNAAMMEE uunnaarryy--bboolldd - font handling in bold boxes DDEESSCCRRIIPPTTIIOONN - initial text ((sin ssiinn)) final text + initial text ((sin ssiinn)) _t_e_x_t xx^^ final text -OpenBSD July 4, 2017 OpenBSD +OpenBSD July 5, 2017 OpenBSD diff --git a/regress/usr.bin/mandoc/eqn/unary/bold.out_html b/regress/usr.bin/mandoc/eqn/unary/bold.out_html index 56d6762f913..e1263a4fd30 100644 --- a/regress/usr.bin/mandoc/eqn/unary/bold.out_html +++ b/regress/usr.bin/mandoc/eqn/unary/bold.out_html @@ -1 +1 @@ -sinsin +sinsintextx^ diff --git a/regress/usr.bin/mandoc/eqn/unary/diacrit.in b/regress/usr.bin/mandoc/eqn/unary/diacrit.in index 6e91f847e1f..ab83dbb1b8b 100644 --- a/regress/usr.bin/mandoc/eqn/unary/diacrit.in +++ b/regress/usr.bin/mandoc/eqn/unary/diacrit.in @@ -1,5 +1,5 @@ -.\" $OpenBSD: diacrit.in,v 1.2 2017/07/04 14:53:23 schwarze Exp $ -.Dd $Mdocdate: July 4 2017 $ +.\" $OpenBSD: diacrit.in,v 1.3 2017/07/06 00:08:52 schwarze Exp $ +.Dd $Mdocdate: July 6 2017 $ .Dt UNARY-DIACRIT 1 .Os .Sh NAME @@ -10,5 +10,6 @@ initial text .EQ x dot x dotdot x hat x tilde x vec x dyad { x + y } bar { x + y } under +x tilde hat .EN final text diff --git a/regress/usr.bin/mandoc/eqn/unary/diacrit.out_ascii b/regress/usr.bin/mandoc/eqn/unary/diacrit.out_ascii index f2c5b0bbf8d..5cc40fe3da8 100644 --- a/regress/usr.bin/mandoc/eqn/unary/diacrit.out_ascii +++ b/regress/usr.bin/mandoc/eqn/unary/diacrit.out_ascii @@ -4,6 +4,6 @@ NNAAMMEE uunnaarryy--ddiiaaccrriitt - diacritical marks in equations DDEESSCCRRIIPPTTIIOONN - initial text _x. _x" _x^ _x~ _x-> _x<-> (_x + _y) (_x + _y)_ final text + initial text _x. _x" _x^ _x~ _x-> _x<-> (_x + _y) (_x + _y)_ _x~^ final text -OpenBSD July 4, 2017 OpenBSD +OpenBSD July 5, 2017 OpenBSD diff --git a/regress/usr.bin/mandoc/eqn/unary/diacrit.out_html b/regress/usr.bin/mandoc/eqn/unary/diacrit.out_html index 02dcc2f4911..d3d4d3613af 100644 --- a/regress/usr.bin/mandoc/eqn/unary/diacrit.out_html +++ b/regress/usr.bin/mandoc/eqn/unary/diacrit.out_html @@ -1 +1 @@ -x˙x¨x^x~xxx+yx+y_ +x˙x¨x^x~xxx+yx+y_x~^ diff --git a/regress/usr.bin/mandoc/eqn/unary/sqrt.in b/regress/usr.bin/mandoc/eqn/unary/sqrt.in index a7059624257..e007ff01739 100644 --- a/regress/usr.bin/mandoc/eqn/unary/sqrt.in +++ b/regress/usr.bin/mandoc/eqn/unary/sqrt.in @@ -1,5 +1,5 @@ -.\" $OpenBSD: sqrt.in,v 1.4 2017/07/04 14:53:23 schwarze Exp $ -.Dd $Mdocdate: July 4 2017 $ +.\" $OpenBSD: sqrt.in,v 1.5 2017/07/06 00:08:52 schwarze Exp $ +.Dd $Mdocdate: July 6 2017 $ .Dt UNARY-SQRT 1 .Os .Sh NAME @@ -8,6 +8,6 @@ .Sh DESCRIPTION initial text .EQ -r = sqrt { x sup 2 + y sup 2 } + sqrt a+b + sqrt { } + sqrt +r = sqrt { x sup 2 + y sup 2 } + sqrt a+b + sqrt x hat + sqrt { } + sqrt .EN final text diff --git a/regress/usr.bin/mandoc/eqn/unary/sqrt.out_ascii b/regress/usr.bin/mandoc/eqn/unary/sqrt.out_ascii index 607a6013aa3..c8565529fc0 100644 --- a/regress/usr.bin/mandoc/eqn/unary/sqrt.out_ascii +++ b/regress/usr.bin/mandoc/eqn/unary/sqrt.out_ascii @@ -4,6 +4,7 @@ NNAAMMEE uunnaarryy--ssqqrrtt - square root DDEESSCCRRIIPPTTIIOONN - initial text _r = sqrt(_x^2 + _y^2) + sqrt(_a + _b) + sqrt() + sqrt final text + initial text _r = sqrt(_x^2 + _y^2) + sqrt(_a + _b) + sqrt(_x^) + sqrt() + sqrt + final text -OpenBSD July 4, 2017 OpenBSD +OpenBSD July 5, 2017 OpenBSD diff --git a/regress/usr.bin/mandoc/eqn/unary/sqrt.out_html b/regress/usr.bin/mandoc/eqn/unary/sqrt.out_html index ca2de199e98..0b5fe37e1d5 100644 --- a/regress/usr.bin/mandoc/eqn/unary/sqrt.out_html +++ b/regress/usr.bin/mandoc/eqn/unary/sqrt.out_html @@ -1 +1 @@ -r=x2+y2+a+b++ +r=x2+y2+a+b+x^++ diff --git a/usr.bin/mandoc/eqn.c b/usr.bin/mandoc/eqn.c index 251a87aa816..e0775f1ac6e 100644 --- a/usr.bin/mandoc/eqn.c +++ b/usr.bin/mandoc/eqn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eqn.c,v 1.36 2017/07/05 15:03:20 schwarze Exp $ */ +/* $OpenBSD: eqn.c,v 1.37 2017/07/06 00:08:52 schwarze Exp $ */ /* * Copyright (c) 2011, 2014 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2017 Ingo Schwarze @@ -817,6 +817,8 @@ next_tok: ep->gsize = size; break; } + while (parent->args == parent->expectargs) + parent = parent->parent; parent = eqn_box_alloc(ep, parent); parent->type = EQN_LIST; parent->expectargs = 1; @@ -838,13 +840,25 @@ next_tok: cur->type = EQN_TEXT; cur->text = mandoc_strdup(""); } - /* Handle the "subsup" and "fromto" positions. */ - if (EQN_TOK_SUP == tok && parent->pos == EQNPOS_SUB) { + while (parent->expectargs == 1 && parent->args == 1) + parent = parent->parent; + if (tok == EQN_TOK_FROM || tok == EQN_TOK_TO) { + for (cur = parent; cur != NULL; cur = cur->parent) + if (cur->pos == EQNPOS_SUB || + cur->pos == EQNPOS_SUP || + cur->pos == EQNPOS_SUBSUP || + cur->pos == EQNPOS_SQRT || + cur->pos == EQNPOS_OVER) + break; + if (cur != NULL) + parent = cur->parent; + } + if (tok == EQN_TOK_SUP && parent->pos == EQNPOS_SUB) { parent->expectargs = 3; parent->pos = EQNPOS_SUBSUP; break; } - if (EQN_TOK_TO == tok && parent->pos == EQNPOS_FROM) { + if (tok == EQN_TOK_TO && parent->pos == EQNPOS_FROM) { parent->expectargs = 3; parent->pos = EQNPOS_FROMTO; break; @@ -893,6 +907,8 @@ next_tok: cur->type = EQN_TEXT; cur->text = mandoc_strdup(""); } + while (parent->args == parent->expectargs) + parent = parent->parent; while (EQN_SUBEXPR == parent->type) parent = parent->parent; parent = eqn_box_makebinary(ep, EQNPOS_OVER, parent); @@ -1097,13 +1113,6 @@ next_tok: parent = split->parent; break; } - /* - * Post-process list status. - */ - while (parent->type == EQN_LIST && - parent->expectargs == 1 && - parent->args == 1) - parent = parent->parent; break; default: abort(); diff --git a/usr.bin/mandoc/eqn_term.c b/usr.bin/mandoc/eqn_term.c index f41bc1d4129..503919fdbf8 100644 --- a/usr.bin/mandoc/eqn_term.c +++ b/usr.bin/mandoc/eqn_term.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eqn_term.c,v 1.6 2017/07/05 15:03:20 schwarze Exp $ */ +/* $OpenBSD: eqn_term.c,v 1.7 2017/07/06 00:08:52 schwarze Exp $ */ /* * Copyright (c) 2011 Kristaps Dzonsons * Copyright (c) 2014, 2015, 2017 Ingo Schwarze @@ -111,15 +111,6 @@ eqn_box(struct termp *p, const struct eqn_box *bp) if (bp->font != EQNFONT_NONE) term_fontpop(p); - if ((bp->type == EQN_LIST && bp->expectargs > 1) || - (bp->type == EQN_PILE && (bp->prev || bp->next)) || - (bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) { - p->flags |= TERMP_NOSPACE; - term_word(p, bp->right != NULL ? bp->right : ")"); - if (bp->parent->type == EQN_SUBEXPR && bp->next != NULL) - p->flags |= TERMP_NOSPACE; - } - if (bp->top != NULL) { p->flags |= TERMP_NOSPACE; term_word(p, bp->top); @@ -128,4 +119,12 @@ eqn_box(struct termp *p, const struct eqn_box *bp) p->flags |= TERMP_NOSPACE; term_word(p, "_"); } + if ((bp->type == EQN_LIST && bp->expectargs > 1) || + (bp->type == EQN_PILE && (bp->prev || bp->next)) || + (bp->parent != NULL && bp->parent->pos == EQNPOS_SQRT)) { + p->flags |= TERMP_NOSPACE; + term_word(p, bp->right != NULL ? bp->right : ")"); + if (bp->parent->type == EQN_SUBEXPR && bp->next != NULL) + p->flags |= TERMP_NOSPACE; + } } -- 2.20.1