From 39048291be56962c72ce270f867b889d5a17f4eb Mon Sep 17 00:00:00 2001 From: Duncan Garmonsway Date: Thu, 26 Apr 2018 07:49:39 +0100 Subject: [PATCH] Recognise operators in grouped formulas (fixes 26) (#27) Before, it treated `-F10` as "not a reference" because it saw it as a single entity, rather than the combination of an operator `-` and a reference `F10`. This fixes it by treating operators as separators, so that it expects `-`, `*` et al to be followed by a separate entity. --- NEWS.md | 2 ++ src/ref_grammar.h | 40 +++++++++++++++++++++++++-- tests/testthat/formulas.xlsx | Bin 7898 -> 7923 bytes tests/testthat/test-shared-formula.R | 2 +- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/NEWS.md b/NEWS.md index bb53a9b..4ddb742 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # tidyxl 1.0.2 +* Correctly constructs formulas where references are preceded by operators, e.g. + `-F10` (#26 @cablegui). * No longer misinterprets date formats that use underscores `_` as dates when the underscore is followed by a date-ish character like `M` (#24). diff --git a/src/ref_grammar.h b/src/ref_grammar.h index 71231fe..dd5901e 100644 --- a/src/ref_grammar.h +++ b/src/ref_grammar.h @@ -23,6 +23,23 @@ namespace xlref struct openparen: one< '(' > {}; struct closeparen: one< ')' > {}; + // Operators + struct plusop : one< '+' > {}; + struct minusop : one< '-' > {}; + struct mulop : one< '*' > {}; + struct divop : one< '/' > {}; + struct expop : one< '^' > {}; + struct concatop : one< '&' > {}; + struct intersectop : one< ' ' > {}; + struct rangeop : one< ':' > {}; + struct percentop : one< '%' > {}; + struct gtop : one< '>' > {}; + struct eqop : one< '=' > {}; + struct ltop : one< '<' > {}; + struct neqop : string< '<', '>' > {}; + struct gteop : string< '>', '=' > {}; + struct lteop : string< '<', '=' > {}; + // Text matches two QuoteD (") and anything between, i.e. character and // the surrounding pair of double-quotes. struct QuoteD : one< '"' > {}; @@ -32,10 +49,27 @@ namespace xlref {}; struct Text : seq< QuoteD, DoubleQuotedString, QuoteD > {}; + struct Operator : sor< plusop, + minusop, + mulop, + divop, + expop, + concatop, + intersectop, + rangeop, + percentop, + eqop, + neqop, // Must precede lteop and ltop + gteop, // Must precede gtop + lteop, // Must precede ltop + gtop, + ltop > + {}; + // After attempting a Ref, attempt a Text, otherwise consume everything up to - // the next dollar, comma or parentheses, which are characters that separate - // other tokens. - struct sep: sor< dollar, comma, openparen, closeparen > {}; + // the next operator, dollar, comma or parentheses, which are characters that + // separate other tokens. + struct sep: sor< Operator, dollar, comma, openparen, closeparen > {}; struct notsep: if_then_else< at< sep >, failure, any > {}; struct notseps: plus< notsep > {}; struct Other: sor< sep, notseps > {}; diff --git a/tests/testthat/formulas.xlsx b/tests/testthat/formulas.xlsx index 7eeaf019c8660e88f0e9cfe87ba575f431536b15..62c64edfba76c990dc27118b8b17a4c87eb42369 100755 GIT binary patch delta 1283 zcmV+e1^oKjJ@Y-VIuQy;{rd1@0ssIE29rb)Ab-nl+b|Hk7wA7QL=J7xn6j)ijUX%V zqi%diQS^DHsg*@o5(SdBmaP(} z&{bS7md&M5Rf7~WSxUR{q?A-5p3ZBf`K(0W58a51Ew?}H(N|JvWmIlENXJ^C`<`#u z4MV0h$s{^(u@en>pANe5D55M)d_F%VtbfhUJ+XZD4N4FeG8_{nF8-NP3kRIyqrjE2 zz1oS7|BEIW9q=V6SO-mzJG=&rEV zd@mlkj%Yrl=_y1AKQQyqeXvJo9$&r0Q{+8;j4me8kt{N|OJ+0001RlRy?2f6(6w!XOj|@cW>5kaOQ$ zDD}34DPq< z?hM2SZhEe)K?Wc6P*>YcDYz1yi#QP?dr>2JI2Z5IX=-zmrbfB~H*Rp*^fGCY~3U&=%8TdeJSRSwb7@ zt(8oilA1rD^Iuh8lVA!JvlhVLf+hlYDg={lXH z?GiORxx~a7jW+_{w#GsUFuVSHX}i^$8ISP3JUo0MTOMTK_{Q-W2sf*iGA(XzO{%DASyHt=j}4aSvV15Z+xa-E~SbDCmo`5q**k#8s; zZfhf%fAdST!gZ?>rn>{>kR;Wl~avR2r zFqv=29Zd z@M8i101O6`q8(NN#gq9RAR8!3lK;K{003|S000mG000000000000000IFmFUJpm+> tavmca_1T78M*#o;VFCaE5dZ)H00000000000085YupT4^VH^Me003C+N=yI% delta 1296 zcmV+r1@HRvJ=#66IuQ=UQh=yb0ssJf1pojT0F%uf8h@NrTW^~%6n>wy|KM7E*rXK` zvaTy4RJo{X9y(3CK0D?BRsb{GO`3ndV^dPPv{SYhWW(`yJI5qf_jN@!pp8_`gpPuc z5@>|VWK&G&_ixu{A1N`GHyN)~0~5LfL$A`;uad3OYf}PPf(VV7(9+sAX3U5ZYHkA6 zLW5s&rGIN~ajOevS`9q&hw6$&Vfca7TsE{ri1jfTD$k{Wg%Wo)G`0iLP;ra;O(|Q` zqt)UVxSH$rU3(@}-6F(FR?_Y~C?&OsmqnvAUsdS)e)OJ;9@}pY;A<(gGAg$L!m&>1 zq326>$q*?`GKmgc>_kI8q0>=3A5)elKA#^Fwtr@@CYGc_8bFn zImFp+0Y+d0kT{6W_p%q<@-)$EOR$-!(zM)-#wbP&&!0>a;cBNN)SsuH-keUOw+YMB zWPg)}3EQAT@lZ1JB?Ku=$u(rO%Wa0aIVR~d_!|J0A;%D)JA|1J$r#Gtdx-wU0~R}V zR(mh>2IE)n2&F%jt};qb=!3ETL-+pV51UU=hH8BaXHh(NqR=kd`A-gq@Thdi(c$_; zUQ+oaA2(Y^_jv4cxm{wD7N=2+kMT>r_EM!oVV(K0yCdFwMAKt{u>6^xM{Zybd){4! zZiZW4z%AE>Yz(O&_k(_cBiG%8Fu=7{tsDOfycH{Dt*ZN7iGMl3p$-ESn=57e4YIQR ze>43JlVJ)JllL7Ev*QzE0tw=zSAn$v001|WPZk(|&)o{bAQT7i`=ED_bKhJGB4TcA zgPx!sK-_5xehihUx6fckjBbSUJIDXgx_uf=9_WK|mchO#fuI#`RCZ!;yIyuDAR%%) za_uZKcwvCH*=}mVwHPEc!=M9gk^b-xUM?MCL7>%Y? zSstk`NdeH*f_Mh~0f=Ef@2|u!e38ecJMGSLU45{Q&)bxp@PV zVG0zpG8exB1t&V@ghsRW86*LJjFL}J!yp)k?ot{y0h7C2DqZiHTh_-Uz(g z8Ve=B?Dp-Y?N)2%!6W>BJUqN1T^?l>e1WlLtujQS7zLnsElRb^(56_03lvz#lweh@ zAVVjxXqn&Mq+C;88+b9b2IESwfhQ?Txz5nuIZZLPd=HY@$TyS^x3!Uf%=x9+Va@m_ z+W}7Ec#b7FCYWQm1%`ScqBBzP0jUqB>Hvacs6c{p7L$nJpRNNV?Vks_WYm zv+kHJcpnb!qb-MG(=<^t=`_4Q!SCzm*Y2rdsoGg_KzS-Sz5XS6n>;=hE0iZOxeMb(n9K@tPp5>=rXTIq zzs|RU{f0aX{DU|lMM7vYr?dHpcmd=ozWNmTH?vwCR{;vdQh=yb0ssJf1(UlSRy?*7 z004MwFLQKxY-MvUcx`M@O928c02BZQ00;m803iV4q*sBp0000t0RR9H0000000000 z0000004bAA9z6jJlZzfB8z(yEghl}X0AT_E01*HH00000000000002XlgS<=21pzL G0002!9Y22n diff --git a/tests/testthat/test-shared-formula.R b/tests/testthat/test-shared-formula.R index 18507bb..d165eb6 100644 --- a/tests/testthat/test-shared-formula.R +++ b/tests/testthat/test-shared-formula.R @@ -11,5 +11,5 @@ test_that("Shared formulas are propogated correctly", { expect_equal(formulas[239], "E09904.2!A3") formulas <- tidyxl::xlsx_cells("./formulas.xlsx")$formula expect_equal(formulas[3], "N($A2)") + expect_equal(formulas[12], "G4*H4") }) -